lib/armeabi.c: fix zero from/to double conversion

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)
This commit is contained in:
grischka 2023-04-25 08:59:42 +02:00
parent 86f3d8e331
commit 19ef024aa9
5 changed files with 38 additions and 27 deletions

View file

@ -18,7 +18,7 @@
#if __SIZEOF_POINTER__ == 4 #if __SIZEOF_POINTER__ == 4
/* 32bit systems. */ /* 32bit systems. */
#if defined TARGETOS_OpenBSD #if defined __OpenBSD__
#define __SIZE_TYPE__ unsigned long #define __SIZE_TYPE__ unsigned long
#define __PTRDIFF_TYPE__ long #define __PTRDIFF_TYPE__ long
#else #else
@ -68,12 +68,6 @@
#define __WINT_TYPE__ int #define __WINT_TYPE__ int
#endif #endif
#if !defined _WIN32
/* extension to generate different code on old cpu's (>20y ago) */
#define _unaligned
#define __unaligned
#endif
#if __STDC_VERSION__ >= 201112L #if __STDC_VERSION__ >= 201112L
# define __STDC_NO_ATOMICS__ 1 # define __STDC_NO_ATOMICS__ 1
# define __STDC_NO_COMPLEX__ 1 # define __STDC_NO_COMPLEX__ 1
@ -135,6 +129,7 @@
#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD #define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD
#define __PRETTY_FUNCTION__ __FUNCTION__ #define __PRETTY_FUNCTION__ __FUNCTION__
#define __has_builtin(x) 0 #define __has_builtin(x) 0
#define __has_feature(x) 0
#define _Nonnull #define _Nonnull
#define _Nullable #define _Nullable

View file

@ -137,6 +137,11 @@ void __aeabi_ ## name(double_unsigned_struct val) \
int exp, high_shift, sign; \ int exp, high_shift, sign; \
double_unsigned_struct ret; \ double_unsigned_struct ret; \
\ \
if ((val.high & ~0x80000000) == 0 && val.low == 0) { \
ret.low = ret.high = 0; \
goto _ret_; \
} \
\
/* compute sign */ \ /* compute sign */ \
sign = val.high >> 31; \ sign = val.high >> 31; \
\ \
@ -190,6 +195,7 @@ void __aeabi_ ## name(double_unsigned_struct val) \
ret.low++; \ ret.low++; \
} \ } \
\ \
_ret_: \
double_unsigned_struct_return(ret); \ double_unsigned_struct_return(ret); \
} }
@ -313,7 +319,7 @@ void __aeabi_ ## name(unsigned long long v) \
} \ } \
} else { \ } else { \
ret.high = ret.low = 0; \ ret.high = ret.low = 0; \
double_unsigned_struct_return(ret); \ goto _ret_; \
} \ } \
} \ } \
\ \
@ -323,6 +329,7 @@ void __aeabi_ ## name(unsigned long long v) \
/* fill sign bit */ \ /* fill sign bit */ \
ret.high |= sign << 31; \ ret.high |= sign << 31; \
\ \
_ret_: \
double_unsigned_struct_return(ret); \ double_unsigned_struct_return(ret); \
} }

View file

@ -2277,8 +2277,9 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
ph->p_flags |= PF_X; ph->p_flags |= PF_X;
if (f & SHF_TLS) { if (f & SHF_TLS) {
ph->p_type = PT_TLS; ph->p_type = PT_TLS;
ph->p_align = 4; ph->p_align = align + 1;
} }
ph->p_offset = file_offset; ph->p_offset = file_offset;
ph->p_vaddr = addr; ph->p_vaddr = addr;
if (n == 0) { if (n == 0) {

View file

@ -3147,7 +3147,10 @@ error:
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
c &= (dbt != VT_LDOUBLE) | !!nocode_wanted; /* don't try to convert to ldouble when cross-compiling
(except when it's '0' which is needed for arm:gen_negf()) */
if (dbt_bt == VT_LDOUBLE && !nocode_wanted && (sf || vtop->c.i != 0))
c = 0;
#endif #endif
if (c) { if (c) {
/* constant case: we can do it now */ /* constant case: we can do it now */
@ -5449,7 +5452,11 @@ ST_FUNC void unary(void)
t = VT_DOUBLE; t = VT_DOUBLE;
goto push_tokc; goto push_tokc;
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
t = VT_DOUBLE | VT_LONG;
#else
t = VT_LDOUBLE; t = VT_LDOUBLE;
#endif
goto push_tokc; goto push_tokc;
case TOK_CLONG: case TOK_CLONG:
t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG; 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)
else if (sizeof (long double) == sizeof (double)) else if (sizeof (long double) == sizeof (double))
__asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld)); __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
#endif #endif
else if (vtop->c.ld == 0.0)
;
else else
#endif #endif
/* For other platforms it should work natively, but may not work /* 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)
if (sizeof(long double) == LDOUBLE_SIZE) if (sizeof(long double) == LDOUBLE_SIZE)
memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE);
else if (sizeof(double) == LDOUBLE_SIZE) else if (sizeof(double) == LDOUBLE_SIZE)
memcpy(ptr, &vtop->c.ld, LDOUBLE_SIZE); *(double*)ptr = (double)vtop->c.ld;
else if (0 == memcmp(ptr, &vtop->c.ld, LDOUBLE_SIZE))
; /* nothing to do for 0.0 */
#ifndef TCC_CROSS_TEST #ifndef TCC_CROSS_TEST
else else
tcc_error("can't cross compile long double constants"); tcc_error("can't cross compile long double constants");

29
tccpp.c
View file

@ -1002,7 +1002,11 @@ static inline int tok_size(const int *p)
case TOK_CULLONG: case TOK_CULLONG:
return 1 + 2; return 1 + 2;
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
return 1 + 8 / 4;
#else
return 1 + LDOUBLE_SIZE / 4; return 1 + LDOUBLE_SIZE / 4;
#endif
default: default:
return 1 + 0; return 1 + 0;
} }
@ -1143,25 +1147,24 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
#if LONG_SIZE == 8 #if LONG_SIZE == 8
case TOK_CLONG: case TOK_CLONG:
case TOK_CULONG: case TOK_CULONG:
#endif
#if LDOUBLE_SIZE == 8
case TOK_CLDOUBLE:
#endif #endif
str[len++] = cv->tab[0]; str[len++] = cv->tab[0];
str[len++] = cv->tab[1]; str[len++] = cv->tab[1];
break; break;
#if LDOUBLE_SIZE == 12
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
#if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE
str[len++] = cv->tab[0];
str[len++] = cv->tab[1];
#elif LDOUBLE_SIZE == 12
str[len++] = cv->tab[0]; str[len++] = cv->tab[0];
str[len++] = cv->tab[1]; str[len++] = cv->tab[1];
str[len++] = cv->tab[2]; str[len++] = cv->tab[2];
#elif LDOUBLE_SIZE == 16 #elif LDOUBLE_SIZE == 16
case TOK_CLDOUBLE:
str[len++] = cv->tab[0]; str[len++] = cv->tab[0];
str[len++] = cv->tab[1]; str[len++] = cv->tab[1];
str[len++] = cv->tab[2]; str[len++] = cv->tab[2];
str[len++] = cv->tab[3]; str[len++] = cv->tab[3];
#elif LDOUBLE_SIZE != 8 #else
#error add long double size support #error add long double size support
#endif #endif
break; break;
@ -1229,12 +1232,12 @@ static inline void tok_get(int *t, const int **pp, CValue *cv)
n = 2; n = 2;
goto copy; goto copy;
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
#if LDOUBLE_SIZE == 16 #if LDOUBLE_SIZE == 8 || defined TCC_USING_DOUBLE_FOR_LDOUBLE
n = 4; n = 2;
#elif LDOUBLE_SIZE == 12 #elif LDOUBLE_SIZE == 12
n = 3; n = 3;
#elif LDOUBLE_SIZE == 8 #elif LDOUBLE_SIZE == 16
n = 2; n = 4;
#else #else
# error add long double size support # error add long double size support
#endif #endif
@ -2334,11 +2337,10 @@ static void parse_number(const char *p)
tokc.f = (float)d; tokc.f = (float)d;
} else if (t == 'L') { } else if (t == 'L') {
ch = *p++; ch = *p++;
tok = TOK_CLDOUBLE;
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
tok = TOK_CDOUBLE;
tokc.d = d; tokc.d = d;
#else #else
tok = TOK_CLDOUBLE;
/* XXX: not large enough */ /* XXX: not large enough */
tokc.ld = (long double)d; tokc.ld = (long double)d;
#endif #endif
@ -2390,11 +2392,10 @@ static void parse_number(const char *p)
tokc.f = strtof(token_buf, NULL); tokc.f = strtof(token_buf, NULL);
} else if (t == 'L') { } else if (t == 'L') {
ch = *p++; ch = *p++;
tok = TOK_CLDOUBLE;
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
tok = TOK_CDOUBLE;
tokc.d = strtod(token_buf, NULL); tokc.d = strtod(token_buf, NULL);
#else #else
tok = TOK_CLDOUBLE;
tokc.ld = strtold(token_buf, NULL); tokc.ld = strtold(token_buf, NULL);
#endif #endif
} else { } else {