fixup! riscv: Implement large addend for global address
[tinycc.git] / lib / armeabi.c
blob6ade65ef183123922562fa968ebcbaa24546b562
1 /* TCC ARM runtime EABI
2 Copyright (C) 2013 Thomas Preud'homme
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.*/
22 #ifdef __TINYC__
23 #define INT_MIN (-2147483647 - 1)
24 #define INT_MAX 2147483647
25 #define UINT_MAX 0xffffffff
26 #define LONG_MIN (-2147483647L - 1)
27 #define LONG_MAX 2147483647L
28 #define ULONG_MAX 0xffffffffUL
29 #define LLONG_MAX 9223372036854775807LL
30 #define LLONG_MIN (-9223372036854775807LL - 1)
31 #define ULLONG_MAX 0xffffffffffffffffULL
32 #else
33 #include <limits.h>
34 #endif
36 /* We rely on the little endianness and EABI calling convention for this to
37 work */
39 typedef struct double_unsigned_struct {
40 unsigned low;
41 unsigned high;
42 } double_unsigned_struct;
44 typedef struct unsigned_int_struct {
45 unsigned low;
46 int high;
47 } unsigned_int_struct;
49 #define REGS_RETURN(name, type) \
50 void name ## _return(type ret) {}
53 /* Float helper functions */
55 #define FLOAT_EXP_BITS 8
56 #define FLOAT_FRAC_BITS 23
58 #define DOUBLE_EXP_BITS 11
59 #define DOUBLE_FRAC_BITS 52
61 #define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
63 REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
64 REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
66 /* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
69 /* float to [unsigned] long long conversion */
70 #define DEFINE__AEABI_F2XLZ(name, with_sign) \
71 void __aeabi_ ## name(unsigned val) \
72 { \
73 int exp, high_shift, sign; \
74 double_unsigned_struct ret; \
76 /* compute sign */ \
77 sign = val >> 31; \
79 /* compute real exponent */ \
80 exp = val >> FLOAT_FRAC_BITS; \
81 exp &= (1 << FLOAT_EXP_BITS) - 1; \
82 exp -= ONE_EXP(FLOAT); \
84 /* undefined behavior if truncated value cannot be represented */ \
85 if (with_sign) { \
86 if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
87 return; \
88 } else { \
89 if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
90 return; \
91 } \
93 val &= (1 << FLOAT_FRAC_BITS) - 1; \
94 if (exp >= 32) { \
95 ret.high = 1 << (exp - 32); \
96 if (exp - 32 >= FLOAT_FRAC_BITS) { \
97 ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \
98 ret.low = 0; \
99 } else { \
100 high_shift = FLOAT_FRAC_BITS - (exp - 32); \
101 ret.high |= val >> high_shift; \
102 ret.low = val << (32 - high_shift); \
104 } else { \
105 ret.high = 0; \
106 ret.low = 1 << exp; \
107 if (exp > FLOAT_FRAC_BITS) \
108 ret.low |= val << (exp - FLOAT_FRAC_BITS); \
109 else \
110 ret.low |= val >> (FLOAT_FRAC_BITS - exp); \
113 /* encode negative integer using 2's complement */ \
114 if (with_sign && sign) { \
115 ret.low = ~ret.low; \
116 ret.high = ~ret.high; \
117 if (ret.low == UINT_MAX) { \
118 ret.low = 0; \
119 ret.high++; \
120 } else \
121 ret.low++; \
124 double_unsigned_struct_return(ret); \
127 /* float to unsigned long long conversion */
128 DEFINE__AEABI_F2XLZ(f2ulz, 0)
130 /* float to long long conversion */
131 DEFINE__AEABI_F2XLZ(f2lz, 1)
133 /* double to [unsigned] long long conversion */
134 #define DEFINE__AEABI_D2XLZ(name, with_sign) \
135 void __aeabi_ ## name(double_unsigned_struct val) \
137 int exp, high_shift, sign; \
138 double_unsigned_struct ret; \
140 if ((val.high & ~0x80000000) == 0 && val.low == 0) { \
141 ret.low = ret.high = 0; \
142 goto _ret_; \
145 /* compute sign */ \
146 sign = val.high >> 31; \
148 /* compute real exponent */ \
149 exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \
150 exp &= (1 << DOUBLE_EXP_BITS) - 1; \
151 exp -= ONE_EXP(DOUBLE); \
153 /* undefined behavior if truncated value cannot be represented */ \
154 if (with_sign) { \
155 if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
156 return; \
157 } else { \
158 if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
159 return; \
162 val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \
163 if (exp >= 32) { \
164 ret.high = 1 << (exp - 32); \
165 if (exp >= DOUBLE_FRAC_BITS) { \
166 high_shift = exp - DOUBLE_FRAC_BITS; \
167 ret.high |= val.high << high_shift; \
168 ret.high |= val.low >> (32 - high_shift); \
169 ret.low = val.low << high_shift; \
170 } else { \
171 high_shift = DOUBLE_FRAC_BITS - exp; \
172 ret.high |= val.high >> high_shift; \
173 ret.low = val.high << (32 - high_shift); \
174 ret.low |= val.low >> high_shift; \
176 } else { \
177 ret.high = 0; \
178 ret.low = 1 << exp; \
179 if (exp > DOUBLE_FRAC_BITS - 32) { \
180 high_shift = exp - DOUBLE_FRAC_BITS - 32; \
181 ret.low |= val.high << high_shift; \
182 ret.low |= val.low >> (32 - high_shift); \
183 } else \
184 ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \
187 /* encode negative integer using 2's complement */ \
188 if (with_sign && sign) { \
189 ret.low = ~ret.low; \
190 ret.high = ~ret.high; \
191 if (ret.low == UINT_MAX) { \
192 ret.low = 0; \
193 ret.high++; \
194 } else \
195 ret.low++; \
198 _ret_: \
199 double_unsigned_struct_return(ret); \
202 /* double to unsigned long long conversion */
203 DEFINE__AEABI_D2XLZ(d2ulz, 0)
205 /* double to long long conversion */
206 DEFINE__AEABI_D2XLZ(d2lz, 1)
208 /* long long to float conversion */
209 #define DEFINE__AEABI_XL2F(name, with_sign) \
210 unsigned __aeabi_ ## name(unsigned long long v) \
212 int s /* shift */, flb /* first lost bit */, sign = 0; \
213 unsigned p = 0 /* power */, ret; \
214 double_unsigned_struct val; \
216 /* fraction in negative float is encoded in 1's complement */ \
217 if (with_sign && (v & (1ULL << 63))) { \
218 sign = 1; \
219 v = ~v + 1; \
221 val.low = v; \
222 val.high = v >> 32; \
223 /* fill fraction bits */ \
224 for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
225 if (p) { \
226 ret = val.high & (p - 1); \
227 if (s < FLOAT_FRAC_BITS) { \
228 ret <<= FLOAT_FRAC_BITS - s; \
229 ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \
230 flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \
231 } else { \
232 flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
233 ret >>= s - FLOAT_FRAC_BITS; \
235 s += 32; \
236 } else { \
237 for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
238 if (p) { \
239 ret = val.low & (p - 1); \
240 if (s <= FLOAT_FRAC_BITS) { \
241 ret <<= FLOAT_FRAC_BITS - s; \
242 flb = 0; \
243 } else { \
244 flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
245 ret >>= s - FLOAT_FRAC_BITS; \
247 } else \
248 return 0; \
250 if (flb) \
251 ret++; \
253 /* fill exponent bits */ \
254 ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \
256 /* fill sign bit */ \
257 ret |= sign << 31; \
259 return ret; \
262 /* unsigned long long to float conversion */
263 DEFINE__AEABI_XL2F(ul2f, 0)
265 /* long long to float conversion */
266 DEFINE__AEABI_XL2F(l2f, 1)
268 /* long long to double conversion */
269 #define __AEABI_XL2D(name, with_sign) \
270 void __aeabi_ ## name(unsigned long long v) \
272 int s /* shift */, high_shift, sign = 0; \
273 unsigned tmp, p = 0; \
274 double_unsigned_struct val, ret; \
276 /* fraction in negative float is encoded in 1's complement */ \
277 if (with_sign && (v & (1ULL << 63))) { \
278 sign = 1; \
279 v = ~v + 1; \
281 val.low = v; \
282 val.high = v >> 32; \
284 /* fill fraction bits */ \
285 for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
286 if (p) { \
287 tmp = val.high & (p - 1); \
288 if (s < DOUBLE_FRAC_BITS - 32) { \
289 high_shift = DOUBLE_FRAC_BITS - 32 - s; \
290 ret.high = tmp << high_shift; \
291 ret.high |= val.low >> (32 - high_shift); \
292 ret.low = val.low << high_shift; \
293 } else { \
294 high_shift = s - (DOUBLE_FRAC_BITS - 32); \
295 ret.high = tmp >> high_shift; \
296 ret.low = tmp << (32 - high_shift); \
297 ret.low |= val.low >> high_shift; \
298 if ((val.low >> (high_shift - 1)) & 1) { \
299 if (ret.low == UINT_MAX) { \
300 ret.high++; \
301 ret.low = 0; \
302 } else \
303 ret.low++; \
306 s += 32; \
307 } else { \
308 for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
309 if (p) { \
310 tmp = val.low & (p - 1); \
311 if (s <= DOUBLE_FRAC_BITS - 32) { \
312 high_shift = DOUBLE_FRAC_BITS - 32 - s; \
313 ret.high = tmp << high_shift; \
314 ret.low = 0; \
315 } else { \
316 high_shift = s - (DOUBLE_FRAC_BITS - 32); \
317 ret.high = tmp >> high_shift; \
318 ret.low = tmp << (32 - high_shift); \
320 } else { \
321 ret.high = ret.low = 0; \
322 goto _ret_; \
326 /* fill exponent bits */ \
327 ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \
329 /* fill sign bit */ \
330 ret.high |= sign << 31; \
332 _ret_: \
333 double_unsigned_struct_return(ret); \
336 /* unsigned long long to double conversion */
337 __AEABI_XL2D(ul2d, 0)
339 /* long long to double conversion */
340 __AEABI_XL2D(l2d, 1)
343 /* Long long helper functions */
345 /* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
347 #define define_aeabi_xdivmod_signed_type(basetype, type) \
348 typedef struct type { \
349 basetype quot; \
350 unsigned basetype rem; \
351 } type
353 #define define_aeabi_xdivmod_unsigned_type(basetype, type) \
354 typedef struct type { \
355 basetype quot; \
356 basetype rem; \
357 } type
359 #define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
360 static inline rettype aeabi_ ## name (type num, type den) \
362 rettype ret; \
363 type quot = 0; \
365 /* Increase quotient while it is less than numerator */ \
366 while (num >= den) { \
367 type q = 1; \
369 /* Find closest power of two */ \
370 while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
371 q <<= 1; \
373 /* Compute difference between current quotient and numerator */ \
374 num -= q * den; \
375 quot += q; \
377 ret.quot = quot; \
378 ret.rem = num; \
379 return ret; \
382 #define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
383 void __aeabi_ ## name(type numerator, type denominator) \
385 unsigned type num, den; \
386 urettype uxdiv_ret; \
387 rettype ret; \
389 if (numerator >= 0) \
390 num = numerator; \
391 else \
392 num = 0 - numerator; \
393 if (denominator >= 0) \
394 den = denominator; \
395 else \
396 den = 0 - denominator; \
397 uxdiv_ret = aeabi_ ## uiname(num, den); \
398 /* signs differ */ \
399 if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
400 ret.quot = 0 - uxdiv_ret.quot; \
401 else \
402 ret.quot = uxdiv_ret.quot; \
403 if (numerator < 0) \
404 ret.rem = 0 - uxdiv_ret.rem; \
405 else \
406 ret.rem = uxdiv_ret.rem; \
408 rettype ## _return(ret); \
411 define_aeabi_xdivmod_signed_type(long long, lldiv_t);
412 define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
413 define_aeabi_xdivmod_signed_type(int, idiv_t);
414 define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
416 REGS_RETURN(lldiv_t, lldiv_t)
417 REGS_RETURN(ulldiv_t, ulldiv_t)
418 REGS_RETURN(idiv_t, idiv_t)
419 REGS_RETURN(uidiv_t, uidiv_t)
421 AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
423 __AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
425 void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
427 ulldiv_t_return(aeabi_uldivmod(num, den));
430 void __aeabi_llsl(double_unsigned_struct val, int shift)
432 double_unsigned_struct ret;
434 if (shift >= 32) {
435 val.high = val.low;
436 val.low = 0;
437 shift -= 32;
439 if (shift > 0) {
440 ret.low = val.low << shift;
441 ret.high = (val.high << shift) | (val.low >> (32 - shift));
442 double_unsigned_struct_return(ret);
443 return;
445 double_unsigned_struct_return(val);
448 #define aeabi_lsr(val, shift, fill, type) \
449 type ## _struct ret; \
451 if (shift >= 32) { \
452 val.low = val.high; \
453 val.high = fill; \
454 shift -= 32; \
456 if (shift > 0) { \
457 ret.high = val.high >> shift; \
458 ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
459 type ## _struct_return(ret); \
460 return; \
462 type ## _struct_return(val);
464 void __aeabi_llsr(double_unsigned_struct val, int shift)
466 aeabi_lsr(val, shift, 0, double_unsigned);
469 void __aeabi_lasr(unsigned_int_struct val, int shift)
471 aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
475 /* Integer division functions */
477 AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
479 int __aeabi_idiv(int numerator, int denominator)
481 unsigned num, den;
482 uidiv_t ret;
484 if (numerator >= 0)
485 num = numerator;
486 else
487 num = 0 - numerator;
488 if (denominator >= 0)
489 den = denominator;
490 else
491 den = 0 - denominator;
492 ret = aeabi_uidivmod(num, den);
493 if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
494 ret.quot *= -1;
495 return ret.quot;
498 unsigned __aeabi_uidiv(unsigned num, unsigned den)
500 return aeabi_uidivmod(num, den).quot;
503 __AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
505 void __aeabi_uidivmod(unsigned num, unsigned den)
507 uidiv_t_return(aeabi_uidivmod(num, den));
510 /* Some targets do not have all eabi calls (OpenBSD) */
511 typedef __SIZE_TYPE__ size_t;
512 extern void *memcpy(void *dest, const void *src, size_t n);
513 extern void *memmove(void *dest, const void *src, size_t n);
514 extern void *memset(void *s, int c, size_t n);
516 void *
517 __aeabi_memcpy (void *dest, const void *src, size_t n)
519 return memcpy (dest, src, n);
522 void *
523 __aeabi_memmove (void *dest, const void *src, size_t n)
525 return memmove (dest, src, n);
528 void *
529 __aeabi_memmove4 (void *dest, const void *src, size_t n)
531 return memmove (dest, src, n);
534 void *
535 __aeabi_memmove8 (void *dest, const void *src, size_t n)
537 return memmove (dest, src, n);
540 void *
541 __aeabi_memset (void *s, size_t n, int c)
543 return memset (s, c, n);