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 | 19 | #if __SIZEOF_POINTER__ == 4 |
| 20 | 20 | /* 32bit systems. */ |
| 21 | −#if defined TARGETOS_OpenBSD | |
| 21 | +#if defined __OpenBSD__ | |
| 22 | 22 | #define __SIZE_TYPE__ unsigned long |
| 23 | 23 | #define __PTRDIFF_TYPE__ long |
| 24 | 24 | #else |
| @@ -68,12 +68,6 @@ · 43 unmodified lines | ||
| 68 | 68 | #define __WINT_TYPE__ int |
| 69 | 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 | 71 | #if __STDC_VERSION__ >= 201112L |
| 78 | 72 | # define __STDC_NO_ATOMICS__ 1 |
| 79 | 73 | # define __STDC_NO_COMPLEX__ 1 |
| @@ -135,6 +129,7 @@ · 55 unmodified lines | ||
| 135 | 129 | #define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD |
| 136 | 130 | #define __PRETTY_FUNCTION__ __FUNCTION__ |
| 137 | 131 | #define __has_builtin(x) 0 |
| 132 | + #define __has_feature(x) 0 | |
| 138 | 133 | #define _Nonnull |
| 139 | 134 | #define _Nullable |
| 140 | 135 | |
| @@ -137,6 +137,11 @@ void __aeabi_ ## name(double_unsigned_struct val) \ · 136 unmodified lines | ||
| 137 | 137 | int exp, high_shift, sign; \ |
| 138 | 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 | 145 | /* compute sign */ \ |
| 141 | 146 | sign = val.high >> 31; \ |
| 142 | 147 | \ |
| @@ -190,6 +195,7 @@ void __aeabi_ ## name(double_unsigned_struct val) \ · 47 unmodified lines | ||
| 190 | 195 | ret.low++; \ |
| 191 | 196 | } \ |
| 192 | 197 | \ |
| 198 | +_ret_: \ | |
| 193 | 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 | 320 | } else { \ |
| 315 | 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 | 329 | /* fill sign bit */ \ |
| 324 | 330 | ret.high |= sign << 31; \ |
| 325 | 331 | \ |
| 332 | +_ret_: \ | |
| 326 | 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 | 2277 | ph->p_flags |= PF_X; |
| 2278 | 2278 | if (f & SHF_TLS) { |
| 2279 | 2279 | ph->p_type = PT_TLS; |
| 2280 | − ph->p_align = 4; | |
| 2280 | + ph->p_align = align + 1; | |
| 2281 | 2281 | } |
| 2282 | + | |
| 2282 | 2283 | ph->p_offset = file_offset; |
| 2283 | 2284 | ph->p_vaddr = addr; |
| 2284 | 2285 | if (n == 0) { |
| @@ -3147,7 +3147,10 @@ error: · 3146 unmodified lines | ||
| 3147 | 3147 | |
| 3148 | 3148 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 3149 | 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 | 3154 | #endif |
| 3152 | 3155 | if (c) { |
| 3153 | 3156 | /* constant case: we can do it now */ |
| @@ -5449,7 +5452,11 @@ ST_FUNC void unary(void) · 2295 unmodified lines | ||
| 5449 | 5452 | t = VT_DOUBLE; |
| 5450 | 5453 | goto push_tokc; |
| 5451 | 5454 | case TOK_CLDOUBLE: |
| 5455 | +#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | |
| 5456 | + t = VT_DOUBLE | VT_LONG; | |
| 5457 | +#else | |
| 5452 | 5458 | t = VT_LDOUBLE; |
| 5459 | +#endif | |
| 5453 | 5460 | goto push_tokc; |
| 5454 | 5461 | case TOK_CLONG: |
| 5455 | 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 | 7669 | else if (sizeof (long double) == sizeof (double)) |
| 7663 | 7670 | __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld)); |
| 7664 | 7671 | #endif |
| 7665 | − else if (vtop->c.ld == 0.0) | |
| 7666 | − ; | |
| 7667 | 7672 | else |
| 7668 | 7673 | #endif |
| 7669 | 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 | 7676 | if (sizeof(long double) == LDOUBLE_SIZE) |
| 7672 | 7677 | memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); |
| 7673 | 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 | 7682 | #ifndef TCC_CROSS_TEST |
| 7676 | 7683 | else |
| 7677 | 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 | 1002 | case TOK_CULLONG: |
| 1003 | 1003 | return 1 + 2; |
| 1004 | 1004 | case TOK_CLDOUBLE: |
| 1005 | +#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | |
| 1006 | + return 1 + 8 / 4; | |
| 1007 | +#else | |
| 1005 | 1008 | return 1 + LDOUBLE_SIZE / 4; |
| 1009 | +#endif | |
| 1006 | 1010 | default: |
| 1007 | 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 | 1147 | #if LONG_SIZE == 8 |
| 1144 | 1148 | case TOK_CLONG: |
| 1145 | 1149 | case TOK_CULONG: |
| 1146 | −#endif | |
| 1147 | −#if LDOUBLE_SIZE == 8 | |
| 1148 | − case TOK_CLDOUBLE: | |
| 1149 | 1150 | #endif |
| 1150 | 1151 | str[len++] = cv->tab[0]; |
| 1151 | 1152 | str[len++] = cv->tab[1]; |
| 1152 | 1153 | break; |
| 1153 | −#if LDOUBLE_SIZE == 12 | |
| 1154 | 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 | 1159 | str[len++] = cv->tab[0]; |
| 1156 | 1160 | str[len++] = cv->tab[1]; |
| 1157 | 1161 | str[len++] = cv->tab[2]; |
| 1158 | 1162 | #elif LDOUBLE_SIZE == 16 |
| 1159 | − case TOK_CLDOUBLE: | |
| 1160 | 1163 | str[len++] = cv->tab[0]; |
| 1161 | 1164 | str[len++] = cv->tab[1]; |
| 1162 | 1165 | str[len++] = cv->tab[2]; |
| 1163 | 1166 | str[len++] = cv->tab[3]; |
| 1164 | −#elif LDOUBLE_SIZE != 8 | |
| 1167 | +#else | |
| 1165 | 1168 | #error add long double size support |
| 1166 | 1169 | #endif |
| 1167 | 1170 | break; |
| @@ -1229,12 +1232,12 @@ static inline void tok_get(int *t, const int **pp, CValue *cv) · 61 unmodified lines | ||
| 1229 | 1232 | n = 2; |
| 1230 | 1233 | goto copy; |
| 1231 | 1234 | case TOK_CLDOUBLE: |
| 1232 | −#if LDOUBLE_SIZE == 16 | |
| 1233 | − n = 4; | |
| 1235 | +#if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE | |
| 1236 | + n = 2; | |
| 1234 | 1237 | #elif LDOUBLE_SIZE == 12 |
| 1235 | 1238 | n = 3; |
| 1236 | −#elif LDOUBLE_SIZE == 8 | |
| 1237 | − n = 2; | |
| 1239 | +#elif LDOUBLE_SIZE == 16 | |
| 1240 | + n = 4; | |
| 1238 | 1241 | #else |
| 1239 | 1242 | # error add long double size support |
| 1240 | 1243 | #endif |
| @@ -2334,11 +2337,10 @@ static void parse_number(const char *p) · 1093 unmodified lines | ||
| 2334 | 2337 | tokc.f = (float)d; |
| 2335 | 2338 | } else if (t == 'L') { |
| 2336 | 2339 | ch = *p++; |
| 2340 | + tok = TOK_CLDOUBLE; | |
| 2337 | 2341 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE |
| 2338 | − tok = TOK_CDOUBLE; | |
| 2339 | 2342 | tokc.d = d; |
| 2340 | 2343 | #else |
| 2341 | − tok = TOK_CLDOUBLE; | |
| 2342 | 2344 | /* XXX: not large enough */ |
| 2343 | 2345 | tokc.ld = (long double)d; |
| 2344 | 2346 | #endif |
| @@ -2390,11 +2392,10 @@ static void parse_number(const char *p) · 45 unmodified lines | ||
| 2390 | 2392 | tokc.f = strtof(token_buf, NULL); |
| 2391 | 2393 | } else if (t == 'L') { |
| 2392 | 2394 | ch = *p++; |
| 2395 | + tok = TOK_CLDOUBLE; | |
| 2393 | 2396 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE |
| 2394 | − tok = TOK_CDOUBLE; | |
| 2395 | 2397 | tokc.d = strtod(token_buf, NULL); |
| 2396 | 2398 | #else |
| 2397 | − tok = TOK_CLDOUBLE; | |
| 2398 | 2399 | tokc.ld = strtold(token_buf, NULL); |
| 2399 | 2400 | #endif |
| 2400 | 2401 | } else { |