From 73faaea227a53e365dd75f1dba7a5071c7b5e541 Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 28 Aug 2013 22:55:05 +0200 Subject: i386-gen: preserve fp control word in gen_cvt_ftoi - Use runtime function for conversion - Also initialize fp with tcc -run on windows This fixes a bug where double x = 1.0; double y = 1.0000000000000001; double z = x < y ? 0 : sqrt (x*x - y*y); caused a bad sqrt because rounding precision for the x < y comparison was different to the one used within the sqrt function. This also fixes a bug where printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2)); would print 100, 99 Unrelated: win32: document relative include & lib lookup win32: normalize_slashes: do not mirror silly gcc behavior This reverts part of commit 8a81f9e1036637e21a47e14fb56bf64133546890 winapi: add missing WINAPI decl. for some functions --- win32/include/winapi/winbase.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'win32/include') diff --git a/win32/include/winapi/winbase.h b/win32/include/winapi/winbase.h index a5d9b17..4a38006 100644 --- a/win32/include/winapi/winbase.h +++ b/win32/include/winapi/winbase.h @@ -968,15 +968,15 @@ extern "C" { LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand); #else - LONG InterlockedIncrement(LONG volatile *lpAddend); - LONG InterlockedDecrement(LONG volatile *lpAddend); - LONG InterlockedExchange(LONG volatile *Target,LONG Value); + LONG WINAPI InterlockedIncrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedDecrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedExchange(LONG volatile *Target,LONG Value); #define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value)) - LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); - LONG InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); - LONGLONG InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); + LONG WINAPI InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + LONG WINAPI InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); + LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) { LONGLONG Old; -- cgit v1.3.1 From fbc8810334e6a087bed6de4dd84635cb6037b4dc Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 16 Dec 2013 15:38:10 +0100 Subject: Fix "Add support for struct > 4B returned via registers" - avoid assumption "ret_align == register_size" which is false for non-arm targets - rename symbol "sret" to more descriptive "ret_nregs" This fixes commit dcec8673f21da86ae3dcf1ca3e9498127715b795 Also: - remove multiple definitions in win32/include/math.h --- i386-gen.c | 2 +- tccgen.c | 43 ++++++++++++++++++++++++++++--------------- win32/include/math.h | 2 ++ 3 files changed, 31 insertions(+), 16 deletions(-) (limited to 'win32/include') diff --git a/i386-gen.c b/i386-gen.c index eaab2b7..b26b844 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -392,7 +392,7 @@ ST_FUNC int gfunc_sret(CType *vt, CType *ret, int *ret_align) } else { ret->ref = NULL; ret->t = VT_INT; - return 0; + return 1; } #else *ret_align = 1; // Never have to re-align return values for x86 diff --git a/tccgen.c b/tccgen.c index 500e99e..bf208af 100644 --- a/tccgen.c +++ b/tccgen.c @@ -3927,7 +3927,7 @@ ST_FUNC void unary(void) } else if (tok == '(') { SValue ret; Sym *sa; - int nb_args, sret, ret_align; + int nb_args, ret_nregs, ret_align; /* function call */ if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { @@ -3951,8 +3951,8 @@ ST_FUNC void unary(void) ret.r2 = VT_CONST; /* compute first implicit argument if a structure is returned */ if ((s->type.t & VT_BTYPE) == VT_STRUCT) { - sret = gfunc_sret(&s->type, &ret.type, &ret_align); - if (!sret) { + ret_nregs = gfunc_sret(&s->type, &ret.type, &ret_align); + if (!ret_nregs) { /* get some space for the returned structure */ size = type_size(&s->type, &align); loc = (loc - size) & -align; @@ -3965,11 +3965,11 @@ ST_FUNC void unary(void) nb_args++; } } else { - sret = 1; + ret_nregs = 1; ret.type = s->type; } - if (sret) { + if (ret_nregs) { /* return in register */ if (is_float(ret.type.t)) { ret.r = reg_fret(ret.type.t); @@ -4008,23 +4008,30 @@ ST_FUNC void unary(void) } else { vtop -= (nb_args + 1); } + /* return value */ - for (r = ret.r + sret + !sret; r-- > ret.r;) { + for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) { vsetc(&ret.type, r, &ret.c); vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */ } + /* handle packed struct return */ - if (((s->type.t & VT_BTYPE) == VT_STRUCT) && sret) { + if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) { int addr, offset; size = type_size(&s->type, &align); loc = (loc - size) & -align; addr = loc; - for(offset = 0; offset < size; offset += ret_align) { + offset = 0; + for (;;) { vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset); vswap(); vstore(); vtop--; + if (--ret_nregs == 0) + break; + /* XXX: compatible with arm only: ret_align == register_size */ + offset += ret_align; } vset(&s->type, VT_LOCAL | VT_LVAL, addr); } @@ -4596,8 +4603,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, gen_assign_cast(&func_vt); if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { CType type, ret_type; - int ret_align; - if (!gfunc_sret(&func_vt, &ret_type, &ret_align)) { + int ret_align, ret_nregs; + ret_nregs = gfunc_sret(&func_vt, &ret_type, &ret_align); + if (0 == ret_nregs) { /* if returning structure, must copy it to implicit first pointer arg location */ type = func_vt; @@ -4609,7 +4617,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, vstore(); } else { /* returning structure packed into registers */ - int r, size, addr, offset, align; + int r, size, addr, align; size = type_size(&func_vt,&align); if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1))) && (align & (ret_align-1))) { @@ -4626,11 +4634,16 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, r = rc_fret(ret_type.t); else r = RC_IRET; - /* We assume that when a structure is returned in multiple - registers, their classes are consecutive values of the - suite s(n) = 2^n */ - for (offset = 0; offset < size; offset += ret_align, r<<=1) { + + for (;;) { gv(r); + if (--ret_nregs == 0) + break; + /* We assume that when a structure is returned in multiple + registers, their classes are consecutive values of the + suite s(n) = 2^n */ + r <<= 1; + /* XXX: compatible with arm only: ret_align == register_size */ vtop->c.i += ret_align; vtop->r = VT_LOCAL | VT_LVAL; } diff --git a/win32/include/math.h b/win32/include/math.h index 984a717..4fe64e7 100644 --- a/win32/include/math.h +++ b/win32/include/math.h @@ -666,6 +666,7 @@ extern "C" { extern long double __cdecl fmal (long double, long double, long double); +#if 0 // gr: duplicate, see below /* 7.12.14 */ /* * With these functions, comparisons involving quiet NaNs set the FP @@ -708,6 +709,7 @@ extern "C" { & 0x4500) == 0x4500) #endif +#endif //0 #endif /* __STDC_VERSION__ >= 199901L */ -- cgit v1.3.1 From 5f7cdd29b6b0f70ca9a4c4a17b3e48009ed4b603 Mon Sep 17 00:00:00 2001 From: minux Date: Sat, 12 Apr 2014 00:09:57 -0400 Subject: win32/include/process.h: update prototypes to match mingw. This eliminates an argument type mismatch warning during tcc self-compilation on windows. --- win32/include/process.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'win32/include') diff --git a/win32/include/process.h b/win32/include/process.h index f679442..dadaf2b 100644 --- a/win32/include/process.h +++ b/win32/include/process.h @@ -153,20 +153,20 @@ extern "C" { stupid warnings, define them in POSIX way. This is save, because those methods do not return in success case, so that the return value is not really dependent to its scalar width. */ - int __cdecl execv(const char *_Filename,char *const _ArgList[]); - int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); - int __cdecl execvp(const char *_Filename,char *const _ArgList[]); - int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); + int __cdecl execv(const char *_Filename,const char *const _ArgList[]); + int __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + int __cdecl execvp(const char *_Filename,const char *const _ArgList[]); + int __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); #else - intptr_t __cdecl execv(const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); - intptr_t __cdecl execvp(const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); + intptr_t __cdecl execv(const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + intptr_t __cdecl execvp(const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); #endif - intptr_t __cdecl spawnv(int,const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl spawnve(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); - intptr_t __cdecl spawnvp(int,const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl spawnvpe(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); + intptr_t __cdecl spawnv(int,const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl spawnve(int,const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + intptr_t __cdecl spawnvp(int,const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl spawnvpe(int,const char *_Filename,const char *const _ArgList[],char *const _Env[]); #endif #ifdef __cplusplus -- cgit v1.3.1