riscv: Fix 73_arm.c

some constants were loaded wrong (e.g. 0xffffabcdU), and
risc-v needs to do explicit zero-extensions for widening from
32bit (not sign-extensions like the other 64bit targets).

This makes the whole tests2.all testsuite work.

Parameter passing is still not psABI-compliant, but internally
consistent.  (e.g. structs of two floats/doubles are passed
in integer registers, but should sit in float regs).
This commit is contained in:
Michael Matz 2019-07-21 05:39:35 +02:00
parent 982de78e8d
commit 2616c6b230
2 changed files with 20 additions and 12 deletions

View file

@ -203,8 +203,8 @@ ST_FUNC void load(int r, SValue *sv)
tcc_error("unimp: load(non-local lval)"); tcc_error("unimp: load(non-local lval)");
} }
} else if (v == VT_CONST) { } else if (v == VT_CONST) {
int rb = 0, do32bit = 8, doload = 0; int rb = 0, do32bit = 8, doload = 0, zext = 0;
assert(!is_float(sv->type.t) && is_ireg(r) || bt == VT_LDOUBLE); assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);
if (fr & VT_SYM) { if (fr & VT_SYM) {
static Sym label; static Sym label;
if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
@ -252,16 +252,10 @@ ST_FUNC void load(int r, SValue *sv)
fc &= 0xff; fc &= 0xff;
rb = rr; rb = rr;
do32bit = 0; do32bit = 0;
} else { } else if (bt == VT_LLONG) {
/* A 32bit unsigned constant. lui always sign extends, so we need /* A 32bit unsigned constant for a 64bit type.
tricks. */ lui always sign extends, so we need to do an explicit zext.*/
pi = (uint32_t)sv->c.i; zext = 1;
o(0x37 | (rr << 7) | (((pi + 0x80000) & 0xfff00000) >> 8)); // lui RR, up(fc)>>8
EI(0x13, 0, rr, rr, (((pi + 0x200) & 0x000ffc00) >> 8) | (-((int)(pi + 0x200) & 0x80000) >> 8)); // addi RR, RR, mid(fc)
EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8
fc = (pi & 0x3ff) | (-((int)(pi & 0x200)));
rb = rr;
do32bit = 0;
} }
} }
if (((unsigned)fc + (1 << 11)) >> 12) if (((unsigned)fc + (1 << 11)) >> 12)
@ -272,6 +266,10 @@ ST_FUNC void load(int r, SValue *sv)
EI(0x13 | do32bit, 0, rr, rr, fc << 20 >> 20); // addi[w] R, x0|R, FC EI(0x13 | do32bit, 0, rr, rr, fc << 20 >> 20); // addi[w] R, x0|R, FC
} else } else
EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC
if (zext) {
EI(0x13, 1, rr, rr, 32); // slli RR, RR, 32
EI(0x13, 5, rr, rr, 32); // srli RR, RR, 32
}
} else if (v == VT_LOCAL) { } else if (v == VT_LOCAL) {
int br = 8; // s0 int br = 8; // s0
assert(is_ireg(r)); assert(is_ireg(r));

View file

@ -2834,6 +2834,16 @@ static void gen_cast(CType *type)
o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r)); o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
#else #else
#error #error
#endif
} else if (sbt & VT_UNSIGNED) {
#if defined(TCC_TARGET_RISCV64)
/* RISC-V keeps 32bit vals in registers sign-extended.
So here we need a zero-extension. */
vtop->type.t = dbt;
vpushi(32);
gen_op(TOK_SHL);
vpushi(32);
gen_op(TOK_SHR);
#endif #endif
} }
} }