aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji _at_ gmail.com>2009-04-14 01:12:29 +0900
committergrischka <grischka>2009-04-18 15:08:01 +0200
commit9fe28b610ebe6f60a0840c3b6620a3418d703830 (patch)
tree22d848d52e29bc32d203da20b42b3e54f0589dab
parent0e239e2ba5b38f99fd0b849f03fc82db7c2d56b7 (diff)
downloadtinycc-9fe28b610ebe6f60a0840c3b6620a3418d703830.tar.gz
tinycc-9fe28b610ebe6f60a0840c3b6620a3418d703830.tar.bz2
x86-64: Make ABI for long double compatible with GCC.
- Now we use x87's stack top the long double return values. - Add rc_fret and reg_fret, wrapper functions for RC_FRET and REG_FRET. - Add a test case to check if strto* works OK.
-rw-r--r--tcc.c28
-rw-r--r--tcctest.c6
2 files changed, 31 insertions, 3 deletions
diff --git a/tcc.c b/tcc.c
index 1b0b72b..4f525ae 100644
--- a/tcc.c
+++ b/tcc.c
@@ -5180,6 +5180,28 @@ void gv2(int rc1, int rc2)
}
}
+/* wrapper around RC_FRET to return a register by type */
+int rc_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+ if (t == VT_LDOUBLE) {
+ return TREG_ST0;
+ }
+#endif
+ return RC_FRET;
+}
+
+/* wrapper around REG_FRET to return a register by type */
+int reg_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+ if (t == VT_LDOUBLE) {
+ return TREG_ST0;
+ }
+#endif
+ return REG_FRET;
+ }
+
/* expand long long on stack in two int registers */
void lexpand(void)
{
@@ -6014,7 +6036,7 @@ void gen_cvt_itof1(int t)
vrott(2);
gfunc_call(1);
vpushi(0);
- vtop->r = REG_FRET;
+ vtop->r = reg_fret(t);
} else {
gen_cvt_itof(t);
}
@@ -7942,7 +7964,7 @@ static void unary(void)
ret.type = s->type;
/* return in register */
if (is_float(ret.type.t)) {
- ret.r = REG_FRET;
+ ret.r = reg_fret(ret.type.t);
} else {
if ((ret.type.t & VT_BTYPE) == VT_LLONG)
ret.r2 = REG_LRET;
@@ -8524,7 +8546,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
}
#endif
} else if (is_float(func_vt.t)) {
- gv(RC_FRET);
+ gv(rc_fret(func_vt.t));
} else {
gv(RC_IRET);
}
diff --git a/tcctest.c b/tcctest.c
index bc6818b..be47c90 100644
--- a/tcctest.c
+++ b/tcctest.c
@@ -1399,6 +1399,11 @@ void bitfield_test(void)
#define FLOAT_FMT "%.5f\n"
#endif
+/* declare strto* functions as they are C99 */
+double strtod(const char *nptr, char **endptr);
+float strtof(const char *nptr, char **endptr);
+long double strtold(const char *nptr, char **endptr);
+
#define FTEST(prefix, type, fmt)\
void prefix ## cmp(type a, type b)\
{\
@@ -1455,6 +1460,7 @@ void prefix ## call(void)\
printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
printf("double: %f\n", prefix ## retd(42.123456789));\
printf("long double: %Lf\n", prefix ## retld(42.123456789));\
+ printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
}\
\
void prefix ## test(void)\