diff options
| author | Shinichiro Hamaji <shinichiro.hamaji _at_ gmail.com> | 2009-04-14 01:12:29 +0900 |
|---|---|---|
| committer | grischka <grischka> | 2009-04-18 15:08:01 +0200 |
| commit | 9fe28b610ebe6f60a0840c3b6620a3418d703830 (patch) | |
| tree | 22d848d52e29bc32d203da20b42b3e54f0589dab | |
| parent | 0e239e2ba5b38f99fd0b849f03fc82db7c2d56b7 (diff) | |
| download | tinycc-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.c | 28 | ||||
| -rw-r--r-- | tcctest.c | 6 |
2 files changed, 31 insertions, 3 deletions
@@ -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); } @@ -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)\ |
