aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm-gen.c116
-rw-r--r--libtcc1.c12
-rw-r--r--tcc.c43
-rw-r--r--tcctok.h63
4 files changed, 140 insertions, 94 deletions
diff --git a/arm-gen.c b/arm-gen.c
index e3a5629..67a6f85 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -110,6 +110,13 @@ static int regmask(int r) {
#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 @@ static int regmask(int r) {
#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 @@ void gen_opi(int op)
{
int c, func = 0;
unsigned long opc = 0,r,fr;
+ unsigned short retreg = REG_IRET;
c=0;
switch(op) {
@@ -1151,11 +1164,21 @@ void gen_opi(int op)
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 @@ done:
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 @@ void gen_opf(int op)
/* 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 @@ void gen_cvt_itof(int t)
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 @@ void gen_cvt_itof(int t)
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 @@ void gen_cvt_ftoi(int t)
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 --git a/libtcc1.c b/libtcc1.c
index 11393e3..892baba 100644
--- a/libtcc1.c
+++ b/libtcc1.c
@@ -419,7 +419,7 @@ unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
}
/* 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 @@ long long __sardi3(long long a, int b)
}
/* 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 @@ unsigned long long __shrdi3(unsigned long long a, int b)
}
/* 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 @@ unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
#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 @@ float __ulltof(unsigned long long a)
}
}
-double __ulltod(unsigned long long a)
+double __floatundidf(unsigned long long a)
{
DWunion uu;
XFtype r;
@@ -513,7 +513,7 @@ double __ulltod(unsigned long long a)
}
}
-long double __ulltold(unsigned long long a)
+long double __floatundixf(unsigned long long a)
{
DWunion uu;
XFtype r;
diff --git a/tcc.c b/tcc.c
index 9855a13..aa34658 100644
--- a/tcc.c
+++ b/tcc.c
@@ -5261,6 +5261,8 @@ void gen_opl(int op)
{
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) {
@@ -5273,17 +5275,22 @@ void gen_opl(int op)
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 '&':
@@ -5407,13 +5414,13 @@ void gen_opl(int op)
/* 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;
}
}
@@ -5878,6 +5885,7 @@ void gen_op(int op)
}
}
+#ifndef TCC_TARGET_ARM
/* generic itof for unsigned long long case */
void gen_cvt_itof1(int t)
{
@@ -5885,11 +5893,13 @@ void gen_cvt_itof1(int t)
(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);
@@ -5898,6 +5908,7 @@ void gen_cvt_itof1(int t)
gen_cvt_itof(t);
}
}
+#endif
/* generic ftoi for unsigned long long case */
void gen_cvt_ftoi1(int t)
@@ -5909,10 +5920,12 @@ void gen_cvt_ftoi1(int t)
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);
@@ -6020,11 +6033,7 @@ static void gen_cast(CType *type)
}
} 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 --git a/tcctok.h b/tcctok.h
index e019476..d717024 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -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