From e9c2a1996ab7fd00a36fbb11102e660869166cc2 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 22 Jul 2019 06:46:37 +0200 Subject: [PATCH] riscv: Fix tcctest.c this is it! With this tcctest.c works, as well as compiling TCC with itself. abitest.c doesn't yet work due to known problems, all the rest does. There are still warnings during linking. --- riscv64-gen.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/riscv64-gen.c b/riscv64-gen.c index ac40f00b..09c011e3 100644 --- a/riscv64-gen.c +++ b/riscv64-gen.c @@ -184,7 +184,7 @@ ST_FUNC void load(int r, SValue *sv) sv->c.i = 0; } else { if (((unsigned)fc + (1 << 11)) >> 12) - tcc_error("unimp: large addend for global address"); + tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); greloca(cur_text_section, sv->sym, ind, R_RISCV_GOT_HI20, 0); doload = 1; @@ -233,7 +233,7 @@ ST_FUNC void load(int r, SValue *sv) sv->c.i = 0; } else { if (((unsigned)fc + (1 << 11)) >> 12) - tcc_error("unimp: large addend for global address"); + tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); greloca(cur_text_section, sv->sym, ind, R_RISCV_GOT_HI20, 0); doload = 1; @@ -383,7 +383,7 @@ ST_FUNC void store(int r, SValue *sv) sv->c.i = 0; } else { if (((unsigned)fc + (1 << 11)) >> 12) - tcc_error("unimp: large addend for global address"); + tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); greloca(cur_text_section, sv->sym, ind, R_RISCV_GOT_HI20, 0); doload = 1; @@ -569,6 +569,7 @@ ST_FUNC void gfunc_call(int nb_args) } } vrotb(nb_args + 1); + save_regs(nb_args + 1); gcall_or_jmp(1); vtop -= nb_args + 1; if (stack_adj + tempspace) @@ -1081,9 +1082,24 @@ ST_FUNC void gen_cvt_ftof(int dt) int func = (dt == VT_LDOUBLE) ? (st == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : (dt == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); + /* We can't use gfunc_call, as func_old_type works like vararg + functions, and on riscv unnamed float args are passed like + integers. But we really need them in the float argument registers + for extendsftf2/extenddftf2. So, do it explicitely. */ + save_regs(1); + if (dt == VT_LDOUBLE) + gv(RC_F(0)); + else { + gv(RC_R(0)); + assert(vtop->r2 < 7); + if (vtop->r2 != 1 + vtop->r) { + EI(0x13, 0, ireg(vtop->r) + 1, ireg(vtop->r2), 0); // mv Ra+1, RR2 + vtop->r2 = 1 + vtop->r; + } + } vpush_global_sym(&func_old_type, func); - vrott(2); - gfunc_call(1); + gcall_or_jmp(1); + vtop -= 2; vpushi(0); vtop->type.t = dt; if (dt == VT_LDOUBLE)