1
0
mirror of https://github.com/mirror/tinycc.git synced 2025-04-25 14:00:22 +08:00

riscv64 update

implement load/store to constant address
use VT_LLONG instead of VT_PTR in register passing
fix bound checking problem with small structs
enable riscv tests in tests/tcctest.c and tests/tests2/119_random_stuff.c
This commit is contained in:
herman ten brugge 2021-01-01 20:36:57 +01:00
parent 9a2a05ba1e
commit 2633c30fb4
3 changed files with 49 additions and 19 deletions

View File

@ -211,6 +211,20 @@ static int load_symofs(int r, SValue *sv, int forstore)
return rr;
}
static void load_large_constant(int rr, int fc, uint32_t pi)
{
if (fc < 0)
pi++;
o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))
EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))
EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))
EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
fc = fc << 12 >> 12;
EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))
EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8
}
ST_FUNC void load(int r, SValue *sv)
{
int fr = sv->r;
@ -242,7 +256,18 @@ ST_FUNC void load(int r, SValue *sv)
EI(0x03, 3, rr, br, fc); // ld RR, fc(BR)
br = rr;
fc = 0;
} else {
} else if (v == VT_CONST) {
int64_t si = sv->c.i;
si >>= 32;
if (si != 0) {
load_large_constant(rr, fc, si);
fc &= 0xff;
} else {
o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
fc = fc << 20 >> 20;
}
br = rr;
} else {
tcc_error("unimp: load(non-local lval)");
}
EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)
@ -258,20 +283,9 @@ ST_FUNC void load(int r, SValue *sv)
tcc_error("unimp: load(float)");
if (fc != sv->c.i) {
int64_t si = sv->c.i;
uint32_t pi;
si >>= 32;
if (si != 0) {
pi = si;
if (fc < 0)
pi++;
o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))
EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))
EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))
EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
fc = fc << 12 >> 12;
EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))
EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8
load_large_constant(rr, fc, si);
fc &= 0xff;
rb = rr;
do32bit = 0;
@ -381,6 +395,17 @@ ST_FUNC void store(int r, SValue *sv)
/*if (((unsigned)fc + (1 << 11)) >> 12)
tcc_error("unimp: store(large addend) (0x%x)", fc);*/
fc = 0; // XXX support offsets regs
} else if (fr == VT_CONST) {
int64_t si = sv->c.i;
ptrreg = 8; // s0
si >>= 32;
if (si != 0) {
load_large_constant(ptrreg, fc, si);
fc &= 0xff;
} else {
o(0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
fc = fc << 20 >> 20;
}
} else
tcc_error("implement me: %s(!local)", __FUNCTION__);
ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
@ -510,7 +535,7 @@ static void reg_pass_rec(CType *type, int *rc, int *fieldofs, int ofs)
rc[0] = -1;
else if (!rc[0] || rc[1] == RC_FLOAT || is_float(type->t)) {
rc[++rc[0]] = is_float(type->t) ? RC_FLOAT : RC_INT;
fieldofs[rc[0]] = (ofs << 4) | (type->t & VT_BTYPE);
fieldofs[rc[0]] = (ofs << 4) | ((type->t & VT_BTYPE) == VT_PTR ? VT_LLONG : type->t & VT_BTYPE);
} else
rc[0] = -1;
}
@ -537,6 +562,7 @@ ST_FUNC void gfunc_call(int nb_args)
Sym *sa;
#ifdef CONFIG_TCC_BCHECK
int bc_save = tcc_state->do_bounds_check;
if (tcc_state->do_bounds_check)
gbound_args(nb_args);
#endif
@ -692,7 +718,14 @@ ST_FUNC void gfunc_call(int nb_args)
gaddrof();
vtop->type = char_pointer_type;
vpushi(ii >> 20);
#ifdef CONFIG_TCC_BCHECK
if ((origtype.t & VT_BTYPE) == VT_STRUCT)
tcc_state->do_bounds_check = 0;
#endif
gen_op('+');
#ifdef CONFIG_TCC_BCHECK
tcc_state->do_bounds_check = bc_save;
#endif
indir();
vtop->type = origtype;
loadt = vtop->type.t & VT_BTYPE;
@ -835,6 +868,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
*regsize = size / nregs;
}
ret->t = fieldofs[1] & VT_BTYPE;
ret->ref = NULL;
return nregs;
}

View File

@ -2799,14 +2799,12 @@ void stdarg_test(void)
stdarg_for_struct(bob, bob2, bob3, bob4, bob, bob, bob.profile);
stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
stdarg_syntax(1, 17);
#ifndef __riscv
stdarg_double_struct(6,-1,pts[0],pts[1],pts[2],pts[3],pts[4],pts[5]);
stdarg_double_struct(7,1,pts[0],-1.0,pts[1],pts[2],pts[3],pts[4],pts[5]);
stdarg_double_struct(7,2,pts[0],pts[1],-1.0,pts[2],pts[3],pts[4],pts[5]);
stdarg_double_struct(7,3,pts[0],pts[1],pts[2],-1.0,pts[3],pts[4],pts[5]);
stdarg_double_struct(7,4,pts[0],pts[1],pts[2],pts[3],-1.0,pts[4],pts[5]);
stdarg_double_struct(7,5,pts[0],pts[1],pts[2],pts[3],pts[4],-1.0,pts[5]);
#endif
}
int reltab[3] = { 1, 2, 3 };
@ -4038,7 +4036,7 @@ void builtin_frame_address_test(void)
char *fp0 = __builtin_frame_address(0);
printf("str: %s\n", str);
#ifndef __riscv
#ifndef __riscv // gcc dumps core. tcc, clang work
bfa1(str-fp0);
#endif
#endif

View File

@ -33,9 +33,7 @@ void tst_const_addr(void)
{
void *addr = mmap ((void *)0x20000000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (addr != (void *) -1) {
#if !defined(__riscv)
*(int *)0x20000000 += 42;
#endif
munmap (addr, 4096);
}
}