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:
parent
9a2a05ba1e
commit
2633c30fb4
3 changed files with 49 additions and 19 deletions
|
|
@ -211,6 +211,20 @@ static int load_symofs(int r, SValue *sv, int forstore)
|
||||||
return rr;
|
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)
|
ST_FUNC void load(int r, SValue *sv)
|
||||||
{
|
{
|
||||||
int fr = sv->r;
|
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)
|
EI(0x03, 3, rr, br, fc); // ld RR, fc(BR)
|
||||||
br = rr;
|
br = rr;
|
||||||
fc = 0;
|
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)");
|
tcc_error("unimp: load(non-local lval)");
|
||||||
}
|
}
|
||||||
EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)
|
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)");
|
tcc_error("unimp: load(float)");
|
||||||
if (fc != sv->c.i) {
|
if (fc != sv->c.i) {
|
||||||
int64_t si = sv->c.i;
|
int64_t si = sv->c.i;
|
||||||
uint32_t pi;
|
|
||||||
si >>= 32;
|
si >>= 32;
|
||||||
if (si != 0) {
|
if (si != 0) {
|
||||||
pi = si;
|
load_large_constant(rr, fc, 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
|
|
||||||
fc &= 0xff;
|
fc &= 0xff;
|
||||||
rb = rr;
|
rb = rr;
|
||||||
do32bit = 0;
|
do32bit = 0;
|
||||||
|
|
@ -381,6 +395,17 @@ ST_FUNC void store(int r, SValue *sv)
|
||||||
/*if (((unsigned)fc + (1 << 11)) >> 12)
|
/*if (((unsigned)fc + (1 << 11)) >> 12)
|
||||||
tcc_error("unimp: store(large addend) (0x%x)", fc);*/
|
tcc_error("unimp: store(large addend) (0x%x)", fc);*/
|
||||||
fc = 0; // XXX support offsets regs
|
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
|
} else
|
||||||
tcc_error("implement me: %s(!local)", __FUNCTION__);
|
tcc_error("implement me: %s(!local)", __FUNCTION__);
|
||||||
ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
|
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;
|
rc[0] = -1;
|
||||||
else if (!rc[0] || rc[1] == RC_FLOAT || is_float(type->t)) {
|
else if (!rc[0] || rc[1] == RC_FLOAT || is_float(type->t)) {
|
||||||
rc[++rc[0]] = is_float(type->t) ? RC_FLOAT : RC_INT;
|
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
|
} else
|
||||||
rc[0] = -1;
|
rc[0] = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -537,6 +562,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
Sym *sa;
|
Sym *sa;
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
int bc_save = tcc_state->do_bounds_check;
|
||||||
if (tcc_state->do_bounds_check)
|
if (tcc_state->do_bounds_check)
|
||||||
gbound_args(nb_args);
|
gbound_args(nb_args);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -692,7 +718,14 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
gaddrof();
|
gaddrof();
|
||||||
vtop->type = char_pointer_type;
|
vtop->type = char_pointer_type;
|
||||||
vpushi(ii >> 20);
|
vpushi(ii >> 20);
|
||||||
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
if ((origtype.t & VT_BTYPE) == VT_STRUCT)
|
||||||
|
tcc_state->do_bounds_check = 0;
|
||||||
|
#endif
|
||||||
gen_op('+');
|
gen_op('+');
|
||||||
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
tcc_state->do_bounds_check = bc_save;
|
||||||
|
#endif
|
||||||
indir();
|
indir();
|
||||||
vtop->type = origtype;
|
vtop->type = origtype;
|
||||||
loadt = vtop->type.t & VT_BTYPE;
|
loadt = vtop->type.t & VT_BTYPE;
|
||||||
|
|
@ -835,6 +868,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
|
||||||
*regsize = size / nregs;
|
*regsize = size / nregs;
|
||||||
}
|
}
|
||||||
ret->t = fieldofs[1] & VT_BTYPE;
|
ret->t = fieldofs[1] & VT_BTYPE;
|
||||||
|
ret->ref = NULL;
|
||||||
return nregs;
|
return nregs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2799,14 +2799,12 @@ void stdarg_test(void)
|
||||||
stdarg_for_struct(bob, bob2, bob3, bob4, bob, bob, bob.profile);
|
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_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
|
||||||
stdarg_syntax(1, 17);
|
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(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,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,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,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,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]);
|
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 };
|
int reltab[3] = { 1, 2, 3 };
|
||||||
|
|
@ -4038,7 +4036,7 @@ void builtin_frame_address_test(void)
|
||||||
char *fp0 = __builtin_frame_address(0);
|
char *fp0 = __builtin_frame_address(0);
|
||||||
|
|
||||||
printf("str: %s\n", str);
|
printf("str: %s\n", str);
|
||||||
#ifndef __riscv
|
#ifndef __riscv // gcc dumps core. tcc, clang work
|
||||||
bfa1(str-fp0);
|
bfa1(str-fp0);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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);
|
void *addr = mmap ((void *)0x20000000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
||||||
if (addr != (void *) -1) {
|
if (addr != (void *) -1) {
|
||||||
#if !defined(__riscv)
|
|
||||||
*(int *)0x20000000 += 42;
|
*(int *)0x20000000 += 42;
|
||||||
#endif
|
|
||||||
munmap (addr, 4096);
|
munmap (addr, 4096);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue