tccgen.c: - allow cross-compiling 0.0L (cross-compile tcc with tcc) tccelf.c: - use alignment of TLS section for PT_TLS tccpp.c: - support long double constants on systems that do not support long doubles (i.e. mark them (VT_DOUBLE | VT_LONG)) tccdefs.h: #define __has_feature() for android remove _unaligned (why define a msvc extension under !_WIN32)
Unified · Split
| @@ -18,7 +18,7 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #if __SIZEOF_POINTER__ == 4 | 19 | #if __SIZEOF_POINTER__ == 4 |
| 20 | /* 32bit systems. */ | 20 | /* 32bit systems. */ |
| 21 | #if defined TARGETOS_OpenBSD | 21 | #if defined __OpenBSD__ |
| 22 | #define __SIZE_TYPE__ unsigned long | 22 | #define __SIZE_TYPE__ unsigned long |
| 23 | #define __PTRDIFF_TYPE__ long | 23 | #define __PTRDIFF_TYPE__ long |
| 24 | #else | 24 | #else |
| @@ -68,12 +68,6 @@ · 43 unmodified lines | |||
| 68 | #define __WINT_TYPE__ int | 68 | #define __WINT_TYPE__ int |
| 69 | #endif | 69 | #endif |
| 70 | 70 | ||
| 71 | #if !defined _WIN32 | ||
| 72 | /* extension to generate different code on old cpu's (>20y ago) */ | ||
| 73 | #define _unaligned | ||
| 74 | #define __unaligned | ||
| 75 | #endif | ||
| 76 | |||
| 77 | #if __STDC_VERSION__ >= 201112L | 71 | #if __STDC_VERSION__ >= 201112L |
| 78 | # define __STDC_NO_ATOMICS__ 1 | 72 | # define __STDC_NO_ATOMICS__ 1 |
| 79 | # define __STDC_NO_COMPLEX__ 1 | 73 | # define __STDC_NO_COMPLEX__ 1 |
| @@ -135,6 +129,7 @@ · 55 unmodified lines | |||
| 135 | #define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD | 129 | #define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD |
| 136 | #define __PRETTY_FUNCTION__ __FUNCTION__ | 130 | #define __PRETTY_FUNCTION__ __FUNCTION__ |
| 137 | #define __has_builtin(x) 0 | 131 | #define __has_builtin(x) 0 |
| 132 | #define __has_feature(x) 0 | ||
| 138 | #define _Nonnull | 133 | #define _Nonnull |
| 139 | #define _Nullable | 134 | #define _Nullable |
| 140 | 135 | ||
| @@ -137,6 +137,11 @@ void __aeabi_ ## name(double_unsigned_struct val) \ · 136 unmodified lines | |||
| 137 | int exp, high_shift, sign; \ | 137 | int exp, high_shift, sign; \ |
| 138 | double_unsigned_struct ret; \ | 138 | double_unsigned_struct ret; \ |
| 139 | \ | 139 | \ |
| 140 | if ((val.high & ~0x80000000) == 0 && val.low == 0) { \ | ||
| 141 | ret.low = ret.high = 0; \ | ||
| 142 | goto _ret_; \ | ||
| 143 | } \ | ||
| 144 | \ | ||
| 140 | /* compute sign */ \ | 145 | /* compute sign */ \ |
| 141 | sign = val.high >> 31; \ | 146 | sign = val.high >> 31; \ |
| 142 | \ | 147 | \ |
| @@ -190,6 +195,7 @@ void __aeabi_ ## name(double_unsigned_struct val) \ · 47 unmodified lines | |||
| 190 | ret.low++; \ | 195 | ret.low++; \ |
| 191 | } \ | 196 | } \ |
| 192 | \ | 197 | \ |
| 198 | _ret_: \ | ||
| 193 | double_unsigned_struct_return(ret); \ | 199 | double_unsigned_struct_return(ret); \ |
| 194 | } | 200 | } |
| 195 | 201 | ||
| @@ -313,7 +319,7 @@ void __aeabi_ ## name(unsigned long long v) \ · 117 unmodified lines | |||
| 313 | } \ | 319 | } \ |
| 314 | } else { \ | 320 | } else { \ |
| 315 | ret.high = ret.low = 0; \ | 321 | ret.high = ret.low = 0; \ |
| 316 | double_unsigned_struct_return(ret); \ | 322 | goto _ret_; \ |
| 317 | } \ | 323 | } \ |
| 318 | } \ | 324 | } \ |
| 319 | \ | 325 | \ |
| @@ -323,6 +329,7 @@ void __aeabi_ ## name(unsigned long long v) \ · 3 unmodified lines | |||
| 323 | /* fill sign bit */ \ | 329 | /* fill sign bit */ \ |
| 324 | ret.high |= sign << 31; \ | 330 | ret.high |= sign << 31; \ |
| 325 | \ | 331 | \ |
| 332 | _ret_: \ | ||
| 326 | double_unsigned_struct_return(ret); \ | 333 | double_unsigned_struct_return(ret); \ |
| 327 | } | 334 | } |
| 328 | 335 | ||
| @@ -2277,8 +2277,9 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 2276 unmodified lines | |||
| 2277 | ph->p_flags |= PF_X; | 2277 | ph->p_flags |= PF_X; |
| 2278 | if (f & SHF_TLS) { | 2278 | if (f & SHF_TLS) { |
| 2279 | ph->p_type = PT_TLS; | 2279 | ph->p_type = PT_TLS; |
| 2280 | ph->p_align = 4; | 2280 | ph->p_align = align + 1; |
| 2281 | } | 2281 | } |
| 2282 | |||
| 2282 | ph->p_offset = file_offset; | 2283 | ph->p_offset = file_offset; |
| 2283 | ph->p_vaddr = addr; | 2284 | ph->p_vaddr = addr; |
| 2284 | if (n == 0) { | 2285 | if (n == 0) { |
| @@ -3147,7 +3147,10 @@ error: · 3146 unmodified lines | |||
| 3147 | 3147 | ||
| 3148 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | 3148 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 3149 | #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 | 3149 | #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 |
| 3150 | c &= (dbt != VT_LDOUBLE) | !!nocode_wanted; | 3150 | /* don't try to convert to ldouble when cross-compiling |
| 3151 | (except when it's '0' which is needed for arm:gen_negf()) */ | ||
| 3152 | if (dbt_bt == VT_LDOUBLE && !nocode_wanted && (sf || vtop->c.i != 0)) | ||
| 3153 | c = 0; | ||
| 3151 | #endif | 3154 | #endif |
| 3152 | if (c) { | 3155 | if (c) { |
| 3153 | /* constant case: we can do it now */ | 3156 | /* constant case: we can do it now */ |
| @@ -5449,7 +5452,11 @@ ST_FUNC void unary(void) · 2295 unmodified lines | |||
| 5449 | t = VT_DOUBLE; | 5452 | t = VT_DOUBLE; |
| 5450 | goto push_tokc; | 5453 | goto push_tokc; |
| 5451 | case TOK_CLDOUBLE: | 5454 | case TOK_CLDOUBLE: |
| 5455 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | ||
| 5456 | t = VT_DOUBLE | VT_LONG; | ||
| 5457 | #else | ||
| 5452 | t = VT_LDOUBLE; | 5458 | t = VT_LDOUBLE; |
| 5459 | #endif | ||
| 5453 | goto push_tokc; | 5460 | goto push_tokc; |
| 5454 | case TOK_CLONG: | 5461 | case TOK_CLONG: |
| 5455 | t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG; | 5462 | t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG; |
| @@ -7662,8 +7669,6 @@ static void init_putv(init_params *p, CType *type, unsigned long c) · 2206 unmodified lines | |||
| 7662 | else if (sizeof (long double) == sizeof (double)) | 7669 | else if (sizeof (long double) == sizeof (double)) |
| 7663 | __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld)); | 7670 | __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld)); |
| 7664 | #endif | 7671 | #endif |
| 7665 | else if (vtop->c.ld == 0.0) | ||
| 7666 | ; | ||
| 7667 | else | 7672 | else |
| 7668 | #endif | 7673 | #endif |
| 7669 | /* For other platforms it should work natively, but may not work | 7674 | /* For other platforms it should work natively, but may not work |
| @@ -7671,7 +7676,9 @@ static void init_putv(init_params *p, CType *type, unsigned long c) · 1 unmodified line | |||
| 7671 | if (sizeof(long double) == LDOUBLE_SIZE) | 7676 | if (sizeof(long double) == LDOUBLE_SIZE) |
| 7672 | memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); | 7677 | memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); |
| 7673 | else if (sizeof(double) == LDOUBLE_SIZE) | 7678 | else if (sizeof(double) == LDOUBLE_SIZE) |
| 7674 | memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); | 7679 | *(double*)ptr = (double)vtop->c.ld; |
| 7680 | else if (0 == memcmp(ptr, &vtop->c.ld, LDOUBLE_SIZE)) | ||
| 7681 | ; /* nothing to do for 0.0 */ | ||
| 7675 | #ifndef TCC_CROSS_TEST | 7682 | #ifndef TCC_CROSS_TEST |
| 7676 | else | 7683 | else |
| 7677 | tcc_error("can't cross compile long double constants"); | 7684 | tcc_error("can't cross compile long double constants"); |
| @@ -1002,7 +1002,11 @@ static inline int tok_size(const int *p) · 1001 unmodified lines | |||
| 1002 | case TOK_CULLONG: | 1002 | case TOK_CULLONG: |
| 1003 | return 1 + 2; | 1003 | return 1 + 2; |
| 1004 | case TOK_CLDOUBLE: | 1004 | case TOK_CLDOUBLE: |
| 1005 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | ||
| 1006 | return 1 + 8 / 4; | ||
| 1007 | #else | ||
| 1005 | return 1 + LDOUBLE_SIZE / 4; | 1008 | return 1 + LDOUBLE_SIZE / 4; |
| 1009 | #endif | ||
| 1006 | default: | 1010 | default: |
| 1007 | return 1 + 0; | 1011 | return 1 + 0; |
| 1008 | } | 1012 | } |
| @@ -1143,25 +1147,24 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 134 unmodified lines | |||
| 1143 | #if LONG_SIZE == 8 | 1147 | #if LONG_SIZE == 8 |
| 1144 | case TOK_CLONG: | 1148 | case TOK_CLONG: |
| 1145 | case TOK_CULONG: | 1149 | case TOK_CULONG: |
| 1146 | #endif | ||
| 1147 | #if LDOUBLE_SIZE == 8 | ||
| 1148 | case TOK_CLDOUBLE: | ||
| 1149 | #endif | 1150 | #endif |
| 1150 | str[len++] = cv->tab[0]; | 1151 | str[len++] = cv->tab[0]; |
| 1151 | str[len++] = cv->tab[1]; | 1152 | str[len++] = cv->tab[1]; |
| 1152 | break; | 1153 | break; |
| 1153 | #if LDOUBLE_SIZE == 12 | ||
| 1154 | case TOK_CLDOUBLE: | 1154 | case TOK_CLDOUBLE: |
| 1155 | #if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE | ||
| 1156 | str[len++] = cv->tab[0]; | ||
| 1157 | str[len++] = cv->tab[1]; | ||
| 1158 | #elif LDOUBLE_SIZE == 12 | ||
| 1155 | str[len++] = cv->tab[0]; | 1159 | str[len++] = cv->tab[0]; |
| 1156 | str[len++] = cv->tab[1]; | 1160 | str[len++] = cv->tab[1]; |
| 1157 | str[len++] = cv->tab[2]; | 1161 | str[len++] = cv->tab[2]; |
| 1158 | #elif LDOUBLE_SIZE == 16 | 1162 | #elif LDOUBLE_SIZE == 16 |
| 1159 | case TOK_CLDOUBLE: | ||
| 1160 | str[len++] = cv->tab[0]; | 1163 | str[len++] = cv->tab[0]; |
| 1161 | str[len++] = cv->tab[1]; | 1164 | str[len++] = cv->tab[1]; |
| 1162 | str[len++] = cv->tab[2]; | 1165 | str[len++] = cv->tab[2]; |
| 1163 | str[len++] = cv->tab[3]; | 1166 | str[len++] = cv->tab[3]; |
| 1164 | #elif LDOUBLE_SIZE != 8 | 1167 | #else |
| 1165 | #error add long double size support | 1168 | #error add long double size support |
| 1166 | #endif | 1169 | #endif |
| 1167 | break; | 1170 | break; |
| @@ -1229,12 +1232,12 @@ static inline void tok_get(int *t, const int **pp, CValue *cv) · 61 unmodified lines | |||
| 1229 | n = 2; | 1232 | n = 2; |
| 1230 | goto copy; | 1233 | goto copy; |
| 1231 | case TOK_CLDOUBLE: | 1234 | case TOK_CLDOUBLE: |
| 1232 | #if LDOUBLE_SIZE == 16 | 1235 | #if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE |
| 1233 | n = 4; | 1236 | n = 2; |
| 1234 | #elif LDOUBLE_SIZE == 12 | 1237 | #elif LDOUBLE_SIZE == 12 |
| 1235 | n = 3; | 1238 | n = 3; |
| 1236 | #elif LDOUBLE_SIZE == 8 | 1239 | #elif LDOUBLE_SIZE == 16 |
| 1237 | n = 2; | 1240 | n = 4; |
| 1238 | #else | 1241 | #else |
| 1239 | # error add long double size support | 1242 | # error add long double size support |
| 1240 | #endif | 1243 | #endif |
| @@ -2334,11 +2337,10 @@ static void parse_number(const char *p) · 1093 unmodified lines | |||
| 2334 | tokc.f = (float)d; | 2337 | tokc.f = (float)d; |
| 2335 | } else if (t == 'L') { | 2338 | } else if (t == 'L') { |
| 2336 | ch = *p++; | 2339 | ch = *p++; |
| 2340 | tok = TOK_CLDOUBLE; | ||
| 2337 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | 2341 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE |
| 2338 | tok = TOK_CDOUBLE; | ||
| 2339 | tokc.d = d; | 2342 | tokc.d = d; |
| 2340 | #else | 2343 | #else |
| 2341 | tok = TOK_CLDOUBLE; | ||
| 2342 | /* XXX: not large enough */ | 2344 | /* XXX: not large enough */ |
| 2343 | tokc.ld = (long double)d; | 2345 | tokc.ld = (long double)d; |
| 2344 | #endif | 2346 | #endif |
| @@ -2390,11 +2392,10 @@ static void parse_number(const char *p) · 45 unmodified lines | |||
| 2390 | tokc.f = strtof(token_buf, NULL); | 2392 | tokc.f = strtof(token_buf, NULL); |
| 2391 | } else if (t == 'L') { | 2393 | } else if (t == 'L') { |
| 2392 | ch = *p++; | 2394 | ch = *p++; |
| 2395 | tok = TOK_CLDOUBLE; | ||
| 2393 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | 2396 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE |
| 2394 | tok = TOK_CDOUBLE; | ||
| 2395 | tokc.d = strtod(token_buf, NULL); | 2397 | tokc.d = strtod(token_buf, NULL); |
| 2396 | #else | 2398 | #else |
| 2397 | tok = TOK_CLDOUBLE; | ||
| 2398 | tokc.ld = strtold(token_buf, NULL); | 2399 | tokc.ld = strtold(token_buf, NULL); |
| 2399 | #endif | 2400 | #endif |
| 2400 | } else { | 2401 | } else { |