armeabi.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /* TCC ARM runtime EABI
  2. Copyright (C) 2013 Thomas Preud'homme
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  14. THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.*/
  18. #ifdef __TINYC__
  19. #define INT_MIN (-2147483647 - 1)
  20. #define INT_MAX 2147483647
  21. #define UINT_MAX 0xffffffff
  22. #define LONG_MIN (-2147483647L - 1)
  23. #define LONG_MAX 2147483647L
  24. #define ULONG_MAX 0xffffffffUL
  25. #define LLONG_MAX 9223372036854775807LL
  26. #define LLONG_MIN (-9223372036854775807LL - 1)
  27. #define ULLONG_MAX 0xffffffffffffffffULL
  28. #else
  29. #include <limits.h>
  30. #endif
  31. /* We rely on the little endianness and EABI calling convention for this to
  32. work */
  33. typedef struct double_unsigned_struct {
  34. unsigned low;
  35. unsigned high;
  36. } double_unsigned_struct;
  37. typedef struct unsigned_int_struct {
  38. unsigned low;
  39. int high;
  40. } unsigned_int_struct;
  41. #define REGS_RETURN(name, type) \
  42. void name ## _return(type ret) {}
  43. /* Float helper functions */
  44. #define FLOAT_EXP_BITS 8
  45. #define FLOAT_FRAC_BITS 23
  46. #define DOUBLE_EXP_BITS 11
  47. #define DOUBLE_FRAC_BITS 52
  48. #define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
  49. REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
  50. REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
  51. /* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
  52. /* float to [unsigned] long long conversion */
  53. #define DEFINE__AEABI_F2XLZ(name, with_sign) \
  54. void __aeabi_ ## name(unsigned val) \
  55. { \
  56. int exp, high_shift, sign; \
  57. double_unsigned_struct ret; \
  58. \
  59. /* compute sign */ \
  60. sign = val >> 31; \
  61. \
  62. /* compute real exponent */ \
  63. exp = val >> FLOAT_FRAC_BITS; \
  64. exp &= (1 << FLOAT_EXP_BITS) - 1; \
  65. exp -= ONE_EXP(FLOAT); \
  66. \
  67. /* undefined behavior if truncated value cannot be represented */ \
  68. if (with_sign) { \
  69. if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
  70. return; \
  71. } else { \
  72. if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
  73. return; \
  74. } \
  75. \
  76. val &= (1 << FLOAT_FRAC_BITS) - 1; \
  77. if (exp >= 32) { \
  78. ret.high = 1 << (exp - 32); \
  79. if (exp - 32 >= FLOAT_FRAC_BITS) { \
  80. ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \
  81. ret.low = 0; \
  82. } else { \
  83. high_shift = FLOAT_FRAC_BITS - (exp - 32); \
  84. ret.high |= val >> high_shift; \
  85. ret.low = val << (32 - high_shift); \
  86. } \
  87. } else { \
  88. ret.high = 0; \
  89. ret.low = 1 << exp; \
  90. if (exp > FLOAT_FRAC_BITS) \
  91. ret.low |= val << (exp - FLOAT_FRAC_BITS); \
  92. else \
  93. ret.low |= val >> (FLOAT_FRAC_BITS - exp); \
  94. } \
  95. \
  96. /* encode negative integer using 2's complement */ \
  97. if (with_sign && sign) { \
  98. ret.low = ~ret.low; \
  99. ret.high = ~ret.high; \
  100. if (ret.low == UINT_MAX) { \
  101. ret.low = 0; \
  102. ret.high++; \
  103. } else \
  104. ret.low++; \
  105. } \
  106. \
  107. double_unsigned_struct_return(ret); \
  108. }
  109. /* float to unsigned long long conversion */
  110. DEFINE__AEABI_F2XLZ(f2ulz, 0)
  111. /* float to long long conversion */
  112. DEFINE__AEABI_F2XLZ(f2lz, 1)
  113. /* double to [unsigned] long long conversion */
  114. #define DEFINE__AEABI_D2XLZ(name, with_sign) \
  115. void __aeabi_ ## name(double_unsigned_struct val) \
  116. { \
  117. int exp, high_shift, sign; \
  118. double_unsigned_struct ret; \
  119. \
  120. /* compute sign */ \
  121. sign = val.high >> 31; \
  122. \
  123. /* compute real exponent */ \
  124. exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \
  125. exp &= (1 << DOUBLE_EXP_BITS) - 1; \
  126. exp -= ONE_EXP(DOUBLE); \
  127. \
  128. /* undefined behavior if truncated value cannot be represented */ \
  129. if (with_sign) { \
  130. if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
  131. return; \
  132. } else { \
  133. if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
  134. return; \
  135. } \
  136. \
  137. val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \
  138. if (exp >= 32) { \
  139. ret.high = 1 << (exp - 32); \
  140. if (exp >= DOUBLE_FRAC_BITS) { \
  141. high_shift = exp - DOUBLE_FRAC_BITS; \
  142. ret.high |= val.high << high_shift; \
  143. ret.high |= val.low >> (32 - high_shift); \
  144. ret.low = val.low << high_shift; \
  145. } else { \
  146. high_shift = DOUBLE_FRAC_BITS - exp; \
  147. ret.high |= val.high >> high_shift; \
  148. ret.low = val.high << (32 - high_shift); \
  149. ret.low |= val.low >> high_shift; \
  150. } \
  151. } else { \
  152. ret.high = 0; \
  153. ret.low = 1 << exp; \
  154. if (exp > DOUBLE_FRAC_BITS - 32) { \
  155. high_shift = exp - DOUBLE_FRAC_BITS - 32; \
  156. ret.low |= val.high << high_shift; \
  157. ret.low |= val.low >> (32 - high_shift); \
  158. } else \
  159. ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \
  160. } \
  161. \
  162. /* encode negative integer using 2's complement */ \
  163. if (with_sign && sign) { \
  164. ret.low = ~ret.low; \
  165. ret.high = ~ret.high; \
  166. if (ret.low == UINT_MAX) { \
  167. ret.low = 0; \
  168. ret.high++; \
  169. } else \
  170. ret.low++; \
  171. } \
  172. \
  173. double_unsigned_struct_return(ret); \
  174. }
  175. /* double to unsigned long long conversion */
  176. DEFINE__AEABI_D2XLZ(d2ulz, 0)
  177. /* double to long long conversion */
  178. DEFINE__AEABI_D2XLZ(d2lz, 1)
  179. /* long long to float conversion */
  180. #define DEFINE__AEABI_XL2F(name, with_sign) \
  181. unsigned __aeabi_ ## name(unsigned long long v) \
  182. { \
  183. int s /* shift */, flb /* first lost bit */, sign = 0; \
  184. unsigned p = 0 /* power */, ret; \
  185. double_unsigned_struct val; \
  186. \
  187. /* fraction in negative float is encoded in 1's complement */ \
  188. if (with_sign && (v & (1ULL << 63))) { \
  189. sign = 1; \
  190. v = ~v + 1; \
  191. } \
  192. val.low = v; \
  193. val.high = v >> 32; \
  194. /* fill fraction bits */ \
  195. for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
  196. if (p) { \
  197. ret = val.high & (p - 1); \
  198. if (s < FLOAT_FRAC_BITS) { \
  199. ret <<= FLOAT_FRAC_BITS - s; \
  200. ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \
  201. flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \
  202. } else { \
  203. flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
  204. ret >>= s - FLOAT_FRAC_BITS; \
  205. } \
  206. s += 32; \
  207. } else { \
  208. for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
  209. if (p) { \
  210. ret = val.low & (p - 1); \
  211. if (s <= FLOAT_FRAC_BITS) { \
  212. ret <<= FLOAT_FRAC_BITS - s; \
  213. flb = 0; \
  214. } else { \
  215. flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
  216. ret >>= s - FLOAT_FRAC_BITS; \
  217. } \
  218. } else \
  219. return 0; \
  220. } \
  221. if (flb) \
  222. ret++; \
  223. \
  224. /* fill exponent bits */ \
  225. ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \
  226. \
  227. /* fill sign bit */ \
  228. ret |= sign << 31; \
  229. \
  230. return ret; \
  231. }
  232. /* unsigned long long to float conversion */
  233. DEFINE__AEABI_XL2F(ul2f, 0)
  234. /* long long to float conversion */
  235. DEFINE__AEABI_XL2F(l2f, 1)
  236. /* long long to double conversion */
  237. #define __AEABI_XL2D(name, with_sign) \
  238. void __aeabi_ ## name(unsigned long long v) \
  239. { \
  240. int s /* shift */, high_shift, sign = 0; \
  241. unsigned tmp, p = 0; \
  242. double_unsigned_struct val, ret; \
  243. \
  244. /* fraction in negative float is encoded in 1's complement */ \
  245. if (with_sign && (v & (1ULL << 63))) { \
  246. sign = 1; \
  247. v = ~v + 1; \
  248. } \
  249. val.low = v; \
  250. val.high = v >> 32; \
  251. \
  252. /* fill fraction bits */ \
  253. for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
  254. if (p) { \
  255. tmp = val.high & (p - 1); \
  256. if (s < DOUBLE_FRAC_BITS - 32) { \
  257. high_shift = DOUBLE_FRAC_BITS - 32 - s; \
  258. ret.high = tmp << high_shift; \
  259. ret.high |= val.low >> (32 - high_shift); \
  260. ret.low = val.low << high_shift; \
  261. } else { \
  262. high_shift = s - (DOUBLE_FRAC_BITS - 32); \
  263. ret.high = tmp >> high_shift; \
  264. ret.low = tmp << (32 - high_shift); \
  265. ret.low |= val.low >> high_shift; \
  266. if ((val.low >> (high_shift - 1)) & 1) { \
  267. if (ret.low == UINT_MAX) { \
  268. ret.high++; \
  269. ret.low = 0; \
  270. } else \
  271. ret.low++; \
  272. } \
  273. } \
  274. s += 32; \
  275. } else { \
  276. for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
  277. if (p) { \
  278. tmp = val.low & (p - 1); \
  279. if (s <= DOUBLE_FRAC_BITS - 32) { \
  280. high_shift = DOUBLE_FRAC_BITS - 32 - s; \
  281. ret.high = tmp << high_shift; \
  282. ret.low = 0; \
  283. } else { \
  284. high_shift = s - (DOUBLE_FRAC_BITS - 32); \
  285. ret.high = tmp >> high_shift; \
  286. ret.low = tmp << (32 - high_shift); \
  287. } \
  288. } else { \
  289. ret.high = ret.low = 0; \
  290. double_unsigned_struct_return(ret); \
  291. } \
  292. } \
  293. \
  294. /* fill exponent bits */ \
  295. ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \
  296. \
  297. /* fill sign bit */ \
  298. ret.high |= sign << 31; \
  299. \
  300. double_unsigned_struct_return(ret); \
  301. }
  302. /* unsigned long long to double conversion */
  303. __AEABI_XL2D(ul2d, 0)
  304. /* long long to double conversion */
  305. __AEABI_XL2D(l2d, 1)
  306. /* Long long helper functions */
  307. /* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
  308. #define define_aeabi_xdivmod_signed_type(basetype, type) \
  309. typedef struct type { \
  310. basetype quot; \
  311. unsigned basetype rem; \
  312. } type
  313. #define define_aeabi_xdivmod_unsigned_type(basetype, type) \
  314. typedef struct type { \
  315. basetype quot; \
  316. basetype rem; \
  317. } type
  318. #define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
  319. static inline rettype aeabi_ ## name (type num, type den) \
  320. { \
  321. rettype ret; \
  322. type quot = 0; \
  323. \
  324. /* Increase quotient while it is less than numerator */ \
  325. while (num >= den) { \
  326. type q = 1; \
  327. \
  328. /* Find closest power of two */ \
  329. while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
  330. q <<= 1; \
  331. \
  332. /* Compute difference between current quotient and numerator */ \
  333. num -= q * den; \
  334. quot += q; \
  335. } \
  336. ret.quot = quot; \
  337. ret.rem = num; \
  338. return ret; \
  339. }
  340. #define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
  341. void __aeabi_ ## name(type numerator, type denominator) \
  342. { \
  343. unsigned type num, den; \
  344. urettype uxdiv_ret; \
  345. rettype ret; \
  346. \
  347. if (numerator >= 0) \
  348. num = numerator; \
  349. else \
  350. num = 0 - numerator; \
  351. if (denominator >= 0) \
  352. den = denominator; \
  353. else \
  354. den = 0 - denominator; \
  355. uxdiv_ret = aeabi_ ## uiname(num, den); \
  356. /* signs differ */ \
  357. if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
  358. ret.quot = 0 - uxdiv_ret.quot; \
  359. else \
  360. ret.quot = uxdiv_ret.quot; \
  361. if (numerator < 0) \
  362. ret.rem = 0 - uxdiv_ret.rem; \
  363. else \
  364. ret.rem = uxdiv_ret.rem; \
  365. \
  366. rettype ## _return(ret); \
  367. }
  368. define_aeabi_xdivmod_signed_type(long long, lldiv_t);
  369. define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
  370. define_aeabi_xdivmod_signed_type(int, idiv_t);
  371. define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
  372. REGS_RETURN(lldiv_t, lldiv_t)
  373. REGS_RETURN(ulldiv_t, ulldiv_t)
  374. REGS_RETURN(idiv_t, idiv_t)
  375. REGS_RETURN(uidiv_t, uidiv_t)
  376. AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
  377. __AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
  378. void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
  379. {
  380. ulldiv_t_return(aeabi_uldivmod(num, den));
  381. }
  382. void __aeabi_llsl(double_unsigned_struct val, int shift)
  383. {
  384. double_unsigned_struct ret;
  385. if (shift >= 32) {
  386. val.high = val.low;
  387. val.low = 0;
  388. shift -= 32;
  389. }
  390. if (shift > 0) {
  391. ret.low = val.low << shift;
  392. ret.high = (val.high << shift) | (val.low >> (32 - shift));
  393. double_unsigned_struct_return(ret);
  394. return;
  395. }
  396. double_unsigned_struct_return(val);
  397. }
  398. #define aeabi_lsr(val, shift, fill, type) \
  399. type ## _struct ret; \
  400. \
  401. if (shift >= 32) { \
  402. val.low = val.high; \
  403. val.high = fill; \
  404. shift -= 32; \
  405. } \
  406. if (shift > 0) { \
  407. ret.high = val.high >> shift; \
  408. ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
  409. type ## _struct_return(ret); \
  410. return; \
  411. } \
  412. type ## _struct_return(val);
  413. void __aeabi_llsr(double_unsigned_struct val, int shift)
  414. {
  415. aeabi_lsr(val, shift, 0, double_unsigned);
  416. }
  417. void __aeabi_lasr(unsigned_int_struct val, int shift)
  418. {
  419. aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
  420. }
  421. /* Integer division functions */
  422. AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
  423. int __aeabi_idiv(int numerator, int denominator)
  424. {
  425. unsigned num, den;
  426. uidiv_t ret;
  427. if (numerator >= 0)
  428. num = numerator;
  429. else
  430. num = 0 - numerator;
  431. if (denominator >= 0)
  432. den = denominator;
  433. else
  434. den = 0 - denominator;
  435. ret = aeabi_uidivmod(num, den);
  436. if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
  437. ret.quot *= -1;
  438. return ret.quot;
  439. }
  440. unsigned __aeabi_uidiv(unsigned num, unsigned den)
  441. {
  442. return aeabi_uidivmod(num, den).quot;
  443. }
  444. __AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
  445. void __aeabi_uidivmod(unsigned num, unsigned den)
  446. {
  447. uidiv_t_return(aeabi_uidivmod(num, den));
  448. }