riscv: Make 32_leds work
* more ops: umod and udiv * large immediates: suboptimal code, e.g. when loading 0xffffffffU (which is what a cast from long to int does). tests2 work up to 67_macro_concat.
This commit is contained in:
parent
02c8e69a07
commit
9c1b17407f
2 changed files with 26 additions and 5 deletions
|
@ -191,12 +191,10 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
} else if (v == VT_CONST) {
|
} else if (v == VT_CONST) {
|
||||||
int rb = 0;
|
int rb = 0;
|
||||||
assert(!is_float(sv->type.t) && is_ireg(r));
|
assert(!is_float(sv->type.t) && is_ireg(r));
|
||||||
if (fc != sv->c.i)
|
|
||||||
tcc_error("unimp: load(very large const)");
|
|
||||||
if (fr & VT_SYM) {
|
if (fr & VT_SYM) {
|
||||||
static Sym label;
|
static Sym label;
|
||||||
greloca(cur_text_section, sv->sym, ind,
|
greloca(cur_text_section, sv->sym, ind,
|
||||||
R_RISCV_PCREL_HI20, fc);
|
R_RISCV_PCREL_HI20, sv->c.i);
|
||||||
if (!label.v) {
|
if (!label.v) {
|
||||||
label.v = tok_alloc(".L0 ", 4)->tok;
|
label.v = tok_alloc(".L0 ", 4)->tok;
|
||||||
label.type.t = VT_VOID | VT_STATIC;
|
label.type.t = VT_VOID | VT_STATIC;
|
||||||
|
@ -208,9 +206,25 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
R_RISCV_PCREL_LO12_I, 0);
|
R_RISCV_PCREL_LO12_I, 0);
|
||||||
rb = rr;
|
rb = rr;
|
||||||
fc = 0;
|
fc = 0;
|
||||||
|
sv->c.i = 0;
|
||||||
}
|
}
|
||||||
if (is_float(sv->type.t))
|
if (is_float(sv->type.t))
|
||||||
tcc_error("unimp: load(float)");
|
tcc_error("unimp: load(float)");
|
||||||
|
if (fc != sv->c.i) {
|
||||||
|
int64_t si = sv->c.i;
|
||||||
|
uint32_t pi;
|
||||||
|
si >>= 32;
|
||||||
|
if (si != 0)
|
||||||
|
tcc_error("unimp: load(very large const)");
|
||||||
|
/* A 32bit unsigned constant. lui always sign extends, so we need
|
||||||
|
tricks. */
|
||||||
|
pi = (uint32_t)sv->c.i;
|
||||||
|
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;
|
||||||
|
}
|
||||||
if (((unsigned)fc + (1 << 11)) >> 12)
|
if (((unsigned)fc + (1 << 11)) >> 12)
|
||||||
o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)
|
o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)
|
||||||
EI(0x13, 0, rr, rb, fc << 20 >> 20); // addi R, x0|R, FC
|
EI(0x13, 0, rr, rb, fc << 20 >> 20); // addi R, x0|R, FC
|
||||||
|
@ -575,9 +589,7 @@ static void gen_opil(int op, int ll)
|
||||||
case '%':
|
case '%':
|
||||||
case TOK_SAR:
|
case TOK_SAR:
|
||||||
case TOK_SHR:
|
case TOK_SHR:
|
||||||
case TOK_UDIV:
|
|
||||||
case TOK_PDIV:
|
case TOK_PDIV:
|
||||||
case TOK_UMOD:
|
|
||||||
default:
|
default:
|
||||||
tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
|
tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
|
||||||
|
|
||||||
|
@ -605,6 +617,12 @@ static void gen_opil(int op, int ll)
|
||||||
case '|':
|
case '|':
|
||||||
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (6 << 12)); // or d, a, b
|
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (6 << 12)); // or d, a, b
|
||||||
break;
|
break;
|
||||||
|
case TOK_UMOD:
|
||||||
|
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (7 << 12)); //remu d, a, b
|
||||||
|
break;
|
||||||
|
case TOK_UDIV:
|
||||||
|
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (5 << 12)); //divu d, a, b
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_ULT:
|
case TOK_ULT:
|
||||||
case TOK_UGE:
|
case TOK_UGE:
|
||||||
|
|
3
tccgen.c
3
tccgen.c
|
@ -2840,6 +2840,9 @@ static void gen_cast(CType *type)
|
||||||
lexpand();
|
lexpand();
|
||||||
vpop();
|
vpop();
|
||||||
#else
|
#else
|
||||||
|
/* XXX some architectures (e.g. risc-v) would like it
|
||||||
|
better for this merely being a 32-to-64 sign or zero-
|
||||||
|
extension. */
|
||||||
vpushi(0xffffffff);
|
vpushi(0xffffffff);
|
||||||
vtop->type.t |= VT_UNSIGNED;
|
vtop->type.t |= VT_UNSIGNED;
|
||||||
gen_op('&');
|
gen_op('&');
|
||||||
|
|
Loading…
Reference in a new issue