diff -rud tcc-0.9.24/arm-gen.c tcc-0.9.24-immed/arm-gen.c --- tcc-0.9.24/arm-gen.c Mon Mar 31 09:24:00 2008 +++ tcc-0.9.24-immed/arm-gen.c Fri Sep 5 20:21:01 2008 @@ -110,6 +110,13 @@ #define REG_LRET TREG_R1 /* second word return register (for long long) */ #define REG_FRET TREG_F0 /* float return register */ +#ifdef TCC_ARM_EABI +#define TOK___divdi3 TOK___aeabi_ldivmod +#define TOK___moddi3 TOK___aeabi_ldivmod +#define TOK___udivdi3 TOK___aeabi_uldivmod +#define TOK___umoddi3 TOK___aeabi_uldivmod +#endif + /* defined if function parameters must be evaluated in reverse order */ #define INVERT_FUNC_PARAMS @@ -119,6 +126,11 @@ #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) static CType float_type, double_type, func_float_type, func_double_type; +#define func_ldouble_type func_double_type +#else +#define func_float_type func_old_type +#define func_double_type func_old_type +#define func_ldouble_type func_old_type #endif /* pointer size, in bytes */ @@ -1083,6 +1095,7 @@ { int c, func = 0; unsigned long opc = 0,r,fr; + unsigned short retreg = REG_IRET; c=0; switch(op) { @@ -1151,11 +1164,21 @@ c=3; break; case '%': +#ifdef TCC_ARM_EABI + func=TOK___aeabi_idivmod; + retreg=REG_LRET; +#else func=TOK___modsi3; +#endif c=3; break; case TOK_UMOD: +#ifdef TCC_ARM_EABI + func=TOK___aeabi_uidivmod; + retreg=REG_LRET; +#else func=TOK___umodsi3; +#endif c=3; break; case TOK_UMULL: @@ -1230,7 +1253,7 @@ vrott(3); gfunc_call(2); vpushi(0); - vtop->r = REG_IRET; + vtop->r = retreg; break; default: error("gen_opi %i unimplemented!",op); @@ -1547,11 +1570,14 @@ /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' and 'long long' cases. */ -void gen_cvt_itof(int t) +void gen_cvt_itof1(int t) { int r,r2,bt; bt=vtop->type.t & VT_BTYPE; if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) { +#ifndef TCC_ARM_VFP + unsigned int dsize=0; +#endif r=intr(gv(RC_INT)); #ifdef TCC_ARM_VFP r2=vfpr(vtop->r=get_reg(RC_FLOAT)); @@ -1562,10 +1588,12 @@ o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ #else r2=fpr(vtop->r=get_reg(RC_FLOAT)); - o(0xEE000190|(r2<<16)|(r<<12)); + if((t & VT_BTYPE) != VT_FLOAT) + dsize=0x80; /* flts -> fltd */ + o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */ if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { unsigned int off=0; - o(0xE3500000|(r<<12)); + o(0xE3500000|(r<<12)); /* cmp */ r=fpr(get_reg(RC_FLOAT)); if(last_itod_magic) { off=ind+8-last_itod_magic; @@ -1573,44 +1601,50 @@ if(off>255) off=0; } - o(0xBD1F8100|(r<<12)|off); + o(0xBD1F0100|(r<<12)|off); /* ldflts */ if(!off) { - o(0xEA000001); + o(0xEA000000); /* b */ last_itod_magic=ind; - o(0x41F00000); - o(0); + o(0x4F800000); /* 4294967296.0f */ } - o(0xBE000180|(r2<<16)|(r2<<12)|r); + o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */ } #endif return; } else if(bt == VT_LLONG) { int func; - CType *func_type = &func_old_type; -#ifdef TCC_ARM_VFP -#ifdef TCC_ARM_EABI - func_type = &func_double_type; -#endif + CType *func_type = 0; if((t & VT_BTYPE) == VT_FLOAT) { -#ifdef TCC_ARM_EABI func_type = &func_float_type; -#endif if(vtop->type.t & VT_UNSIGNED) - func=TOK___ulltof; + func=TOK___floatundisf; else - func=TOK___slltof; - } else + func=TOK___floatdisf; +#if LDOUBLE_SIZE != 8 + } else if((t & VT_BTYPE) == VT_LDOUBLE) { + func_type = &func_ldouble_type; + if(vtop->type.t & VT_UNSIGNED) + func=TOK___floatundixf; + else + func=TOK___floatdixf; + } else if((t & VT_BTYPE) == VT_DOUBLE) { +#else + } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) { #endif - if(vtop->type.t & VT_UNSIGNED) - func=TOK___ulltold; - else - func=TOK___slltold; - vpush_global_sym(func_type, func); - vswap(); - gfunc_call(1); - vpushi(0); - vtop->r=TREG_F0; - return; + func_type = &func_double_type; + if(vtop->type.t & VT_UNSIGNED) + func=TOK___floatundidf; + else + func=TOK___floatdidf; + } + if(func_type) { + vpush_global_sym(func_type, func); + vswap(); + gfunc_call(1); + vpushi(0); + vtop->r=TREG_F0; + return; + } } error("unimplemented gen_cvt_itof %x!",vtop->type.t); } @@ -1634,33 +1668,33 @@ if(u) { if(r2 == VT_FLOAT) func=TOK___fixunssfsi; - else if(r2 == VT_DOUBLE) - func=TOK___fixunsdfsi; +#if LDOUBLE_SIZE != 8 else if(r2 == VT_LDOUBLE) -#if LDOUBLE_SIZE == 8 - func=TOK___fixunsdfsi; -#else func=TOK___fixunsxfsi; + else if(r2 == VT_DOUBLE) +#else + else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE) #endif + func=TOK___fixunsdfsi; } else { r=fpr(gv(RC_FLOAT)); r2=intr(vtop->r=get_reg(RC_INT)); o(0xEE100170|(r2<<12)|r); - return; + return; } #endif } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1 if(r2 == VT_FLOAT) func=TOK___fixsfdi; - else if(r2 == VT_DOUBLE) - func=TOK___fixdfdi; +#if LDOUBLE_SIZE != 8 else if(r2 == VT_LDOUBLE) -#if LDOUBLE_SIZE == 8 - func=TOK___fixdfdi; -#else func=TOK___fixxfdi; + else if(r2 == VT_DOUBLE) +#else + else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE) #endif - } + func=TOK___fixdfdi; + } if(func) { vpush_global_sym(&func_old_type, func); vswap(); diff -rud tcc-0.9.24/libtcc1.c tcc-0.9.24-immed/libtcc1.c --- tcc-0.9.24/libtcc1.c Mon Mar 31 09:24:00 2008 +++ tcc-0.9.24-immed/libtcc1.c Fri Sep 5 20:22:29 2008 @@ -419,7 +419,7 @@ } /* XXX: fix tcc's code generator to do this instead */ -long long __sardi3(long long a, int b) +long long __ashrdi3(long long a, int b) { #ifdef __TINYC__ DWunion u; @@ -438,7 +438,7 @@ } /* XXX: fix tcc's code generator to do this instead */ -unsigned long long __shrdi3(unsigned long long a, int b) +unsigned long long __lshrdi3(unsigned long long a, int b) { #ifdef __TINYC__ DWunion u; @@ -457,7 +457,7 @@ } /* XXX: fix tcc's code generator to do this instead */ -long long __shldi3(long long a, int b) +long long __ashldi3(long long a, int b) { #ifdef __TINYC__ DWunion u; @@ -483,7 +483,7 @@ #endif /* XXX: fix tcc's code generator to do this instead */ -float __ulltof(unsigned long long a) +float __floatundisf(unsigned long long a) { DWunion uu; XFtype r; @@ -498,7 +498,7 @@ } } -double __ulltod(unsigned long long a) +double __floatundidf(unsigned long long a) { DWunion uu; XFtype r; @@ -513,7 +513,7 @@ } } -long double __ulltold(unsigned long long a) +long double __floatundixf(unsigned long long a) { DWunion uu; XFtype r; diff -rud tcc-0.9.24/tcc.c tcc-0.9.24-immed/tcc.c --- tcc-0.9.24/tcc.c Mon Mar 31 09:24:00 2008 +++ tcc-0.9.24-immed/tcc.c Fri Sep 5 20:21:01 2008 @@ -5252,6 +5252,8 @@ { int t, a, b, op1, c, i; int func; + unsigned short reg_iret = REG_IRET; + unsigned short reg_lret = REG_LRET; SValue tmp; switch(op) { @@ -5264,17 +5266,22 @@ goto gen_func; case '%': func = TOK___moddi3; - goto gen_func; + goto gen_mod_func; case TOK_UMOD: func = TOK___umoddi3; + gen_mod_func: +#ifdef TCC_ARM_EABI + reg_iret = TREG_R2; + reg_lret = TREG_R3; +#endif gen_func: /* call generic long long function */ vpush_global_sym(&func_old_type, func); vrott(3); gfunc_call(2); vpushi(0); - vtop->r = REG_IRET; - vtop->r2 = REG_LRET; + vtop->r = reg_iret; + vtop->r2 = reg_lret; break; case '^': case '&': @@ -5398,13 +5405,13 @@ /* XXX: should provide a faster fallback on x86 ? */ switch(op) { case TOK_SAR: - func = TOK___sardi3; + func = TOK___ashrdi3; goto gen_func; case TOK_SHR: - func = TOK___shrdi3; + func = TOK___lshrdi3; goto gen_func; case TOK_SHL: - func = TOK___shldi3; + func = TOK___ashldi3; goto gen_func; } } @@ -5869,6 +5876,7 @@ } } +#ifndef TCC_TARGET_ARM /* generic itof for unsigned long long case */ void gen_cvt_itof1(int t) { @@ -5876,11 +5884,13 @@ (VT_LLONG | VT_UNSIGNED)) { if (t == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___ulltof); - else if (t == VT_DOUBLE) - vpush_global_sym(&func_old_type, TOK___ulltod); + vpush_global_sym(&func_old_type, TOK___floatundisf); +#if LDOUBLE_SIZE != 8 + else if (t == VT_LDOUBLE) + vpush_global_sym(&func_old_type, TOK___floatundixf); +#endif else - vpush_global_sym(&func_old_type, TOK___ulltold); + vpush_global_sym(&func_old_type, TOK___floatundidf); vrott(2); gfunc_call(1); vpushi(0); @@ -5889,6 +5899,7 @@ gen_cvt_itof(t); } } +#endif /* generic ftoi for unsigned long long case */ void gen_cvt_ftoi1(int t) @@ -5900,10 +5911,12 @@ st = vtop->type.t & VT_BTYPE; if (st == VT_FLOAT) vpush_global_sym(&func_old_type, TOK___fixunssfdi); - else if (st == VT_DOUBLE) - vpush_global_sym(&func_old_type, TOK___fixunsdfdi); - else +#if LDOUBLE_SIZE != 8 + else if (st == VT_LDOUBLE) vpush_global_sym(&func_old_type, TOK___fixunsxfdi); +#endif + else + vpush_global_sym(&func_old_type, TOK___fixunsdfdi); vrott(2); gfunc_call(1); vpushi(0); @@ -6011,11 +6024,7 @@ } } else { do_itof: -#if !defined(TCC_TARGET_ARM) gen_cvt_itof1(dbt); -#else - gen_cvt_itof(dbt); -#endif } } else if (sf) { /* convert fp to int */ diff -rud tcc-0.9.24/tcctok.h tcc-0.9.24-immed/tcctok.h --- tcc-0.9.24/tcctok.h Mon Mar 31 09:24:00 2008 +++ tcc-0.9.24-immed/tcctok.h Fri Sep 5 20:21:01 2008 @@ -126,41 +126,42 @@ DEF(TOK_memcpy4, "__aeabi_memcpy4") DEF(TOK_memcpy8, "__aeabi_memcpy8") DEF(TOK_memset, "__aeabi_memset") + DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") + DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") #else DEF(TOK_memcpy, "memcpy") DEF(TOK_memset, "memset") -#endif DEF(TOK___divdi3, "__divdi3") DEF(TOK___moddi3, "__moddi3") DEF(TOK___udivdi3, "__udivdi3") DEF(TOK___umoddi3, "__umoddi3") +#endif #if defined(TCC_TARGET_ARM) - DEF(TOK___modsi3, "__modsi3") - DEF(TOK___umodsi3, "__umodsi3") #ifdef TCC_ARM_EABI + DEF(TOK___aeabi_idivmod, "__aeabi_idivmod") + DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod") DEF(TOK___divsi3, "__aeabi_idiv") DEF(TOK___udivsi3, "__aeabi_uidiv") - DEF(TOK___sardi3, "__aeabi_lasr") - DEF(TOK___shrdi3, "__aeabi_llsr") - DEF(TOK___shldi3, "__aeabi_llsl") - DEF(TOK___slltof, "__aeabi_l2f") - DEF(TOK___slltold, "__aeabi_l2d") + DEF(TOK___floatdisf, "__aeabi_l2f") + DEF(TOK___floatdidf, "__aeabi_l2d") DEF(TOK___fixsfdi, "__aeabi_f2lz") DEF(TOK___fixdfdi, "__aeabi_d2lz") - DEF(TOK___fixxfdi, "__aeabi_d2lz") #else + DEF(TOK___modsi3, "__modsi3") + DEF(TOK___umodsi3, "__umodsi3") DEF(TOK___divsi3, "__divsi3") DEF(TOK___udivsi3, "__udivsi3") - DEF(TOK___sardi3, "__ashrdi3") - DEF(TOK___shrdi3, "__lshrdi3") - DEF(TOK___shldi3, "__ashldi3") - DEF(TOK___slltold, "__slltold") + DEF(TOK___floatdisf, "__floatdisf") + DEF(TOK___floatdidf, "__floatdidf") +#ifndef TCC_ARM_VFP + DEF(TOK___floatdixf, "__floatdixf") DEF(TOK___fixunssfsi, "__fixunssfsi") DEF(TOK___fixunsdfsi, "__fixunsdfsi") DEF(TOK___fixunsxfsi, "__fixunsxfsi") + DEF(TOK___fixxfdi, "__fixxfdi") +#endif DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixdfdi, "__fixdfdi") - DEF(TOK___fixxfdi, "__fixxfdi") #endif #elif defined(TCC_TARGET_C67) DEF(TOK__divi, "_divi") @@ -169,33 +170,35 @@ DEF(TOK__divd, "_divd") DEF(TOK__remi, "_remi") DEF(TOK__remu, "_remu") - DEF(TOK___sardi3, "__sardi3") - DEF(TOK___shrdi3, "__shrdi3") - DEF(TOK___shldi3, "__shldi3") -#else - /* XXX: same names on i386 ? */ - DEF(TOK___sardi3, "__sardi3") - DEF(TOK___shrdi3, "__shrdi3") - DEF(TOK___shldi3, "__shldi3") #endif +#ifdef TCC_TARGET_I386 DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") +#endif #ifdef TCC_ARM_EABI - DEF(TOK___ulltof, "__aeabi_ul2f") - DEF(TOK___ulltod, "__aeabi_ul2d") - DEF(TOK___ulltold, "__aeabi_ul2d") + DEF(TOK___ashrdi3, "__aeabi_lasr") + DEF(TOK___lshrdi3, "__aeabi_llsr") + DEF(TOK___ashldi3, "__aeabi_llsl") + DEF(TOK___floatundisf, "__aeabi_ul2f") + DEF(TOK___floatundidf, "__aeabi_ul2d") DEF(TOK___fixunssfdi, "__aeabi_f2ulz") DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") - DEF(TOK___fixunsxfdi, "__aeabi_d2ulz") #else - DEF(TOK___ulltof, "__ulltof") - DEF(TOK___ulltod, "__ulltod") - DEF(TOK___ulltold, "__ulltold") + DEF(TOK___ashrdi3, "__ashrdi3") + DEF(TOK___lshrdi3, "__lshrdi3") + DEF(TOK___ashldi3, "__ashldi3") + DEF(TOK___floatundisf, "__floatundisf") + DEF(TOK___floatundidf, "__floatundidf") +#ifndef TCC_ARM_VFP + DEF(TOK___floatundixf, "__floatundixf") + DEF(TOK___fixunsxfdi, "__fixunsxfdi") +#endif DEF(TOK___fixunssfdi, "__fixunssfdi") DEF(TOK___fixunsdfdi, "__fixunsdfdi") - DEF(TOK___fixunsxfdi, "__fixunsxfdi") #endif +#ifdef TCC_TARGET_PE DEF(TOK___chkstk, "__chkstk") +#endif /* bound checking symbols */ #ifdef CONFIG_TCC_BCHECK