riscv: Replace RR insn emitter with specific one

instead of using o() directly.  Makes the code a little easier
to read.
This commit is contained in:
Michael Matz 2019-08-13 04:06:07 +02:00
parent d5bb407cc4
commit 48ba22c744

View File

@ -101,6 +101,12 @@ static void EIu(uint32_t opcode, uint32_t func3,
o(opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));
}
static void ER(uint32_t opcode, uint32_t func3,
uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)
{
o(opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);
}
static void EI(uint32_t opcode, uint32_t func3,
uint32_t rd, uint32_t rs1, uint32_t imm)
{
@ -175,7 +181,7 @@ static int load_symofs(int r, SValue *sv, int forstore)
if (((unsigned)fc + (1 << 11)) >> 12) {
rr = is_ireg(r) ? ireg(r) : 5; // t0
o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
o(0x33 | (rr << 7) | (rr << 15) | (8 << 20)); // add RR, RR, s0
ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0
sv->c.i = fc << 20 >> 20;
}
} else
@ -268,7 +274,7 @@ ST_FUNC void load(int r, SValue *sv)
} else if (v < VT_CONST) { /* reg-reg */
//assert(!fc); XXX support offseted regs
if (is_freg(r) && is_freg(v))
o(0x53 | (rr << 7) | (freg(v) << 15) | (freg(v) << 20) | ((bt == VT_DOUBLE ? 0x11 : 0x10) << 25)); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V
ER(0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V
else if (is_ireg(r) && is_ireg(v))
EI(0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V
else {
@ -696,7 +702,7 @@ ST_FUNC void gfunc_epilog(void)
d = 16;
o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
o(0x33 | (2 << 7) | (2 << 15) | (5 << 20)); //add sp, sp, t0
ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
}
EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)
EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
@ -707,7 +713,7 @@ ST_FUNC void gfunc_epilog(void)
EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
o(0x33 | (2 << 7) | (2 << 15) | (5 << 20) | (0x20 << 25)); //sub sp, sp, t0
ER(0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
gjmp_addr(func_sub_sp_offset + 5*4);
}
saved_ind = ind;
@ -849,7 +855,7 @@ static void gen_opil(int op, int ll)
if (fc)
gen_opil('-', ll), a = ireg(vtop++->r);
if (op == TOK_NE)
o(0x33 | (3 << 12) | (ireg(d) << 7) | (0 << 15) | (a << 20)); // sltu d, x0, a == snez d,a
ER(0x33, 3, ireg(d), 0, a, 0); //sltu d, x0, a == snez d,a
else
EI(0x13, 3, ireg(d), a, 1); // sltiu d, a, 1 == seqz d,a
--vtop;
@ -871,44 +877,44 @@ static void gen_opil(int op, int ll)
tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
case '+':
o(0x33 | (d << 7) | (a << 15) | (b << 20)); // add d, a, b
ER(0x33, 0, d, a, b, 0); // add d, a, b
break;
case '-':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); //sub d, a, b
ER(0x33, 0, d, a, b, 0x20); // sub d, a, b
break;
case TOK_SAR:
o(0x33 | ll | (d << 7) | (a << 15) | (b << 20) | (5 << 12) | (1 << 30)); //sra d, a, b
ER(0x33 | ll, 5, d, a, b, 0x20); // sra d, a, b
break;
case TOK_SHR:
o(0x33 | ll | (d << 7) | (a << 15) | (b << 20) | (5 << 12)); //srl d, a, b
ER(0x33 | ll, 5, d, a, b, 0); // srl d, a, b
break;
case TOK_SHL:
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (1 << 12)); //sll d, a, b
ER(0x33, 1, d, a, b, 0); // sll d, a, b
break;
case '*':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25)); //mul d, a, b
ER(0x33, 0, d, a, b, 1); // mul d, a, b
break;
case '/':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (4 << 12)); //div d, a, b
ER(0x33, 4, d, a, b, 1); // div d, a, b
break;
case '&':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (7 << 12)); // and d, a, b
ER(0x33, 7, d, a, b, 0); // and d, a, b
break;
case '^':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (4 << 12)); // xor d, a, b
ER(0x33, 4, d, a, b, 0); // xor d, a, b
break;
case '|':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (6 << 12)); // or d, a, b
ER(0x33, 6, d, a, b, 0); // or d, a, b
break;
case '%':
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (6 << 12)); //rem d, a, b
ER(0x33, 6, d, a, b, 1); // rem d, a, b
break;
case TOK_UMOD:
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (7 << 12)); //remu d, a, b
ER(0x33, 7, d, a, b, 1); // remu d, a, b
break;
case TOK_PDIV:
case TOK_UDIV:
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25) | (5 << 12)); //divu d, a, b
ER(0x33, 5, d, a, b, 1); // divu d, a, b
break;
case TOK_ULT:
@ -927,7 +933,7 @@ static void gen_opil(int op, int ll)
int t = a; a = b; b = t;
inv ^= 1;
}
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (((op > TOK_UGT) ? 2 : 3) << 12)); // slt[u] d, a, b
ER(0x33, (op > TOK_UGT) ? 2 : 3, d, a, b, 0); // slt[u] d, a, b
if (inv)
EI(0x13, 4, d, d, 1); // xori d, d, 1
vset_VT_CMP(TOK_NE);
@ -935,9 +941,9 @@ static void gen_opil(int op, int ll)
break;
case TOK_NE:
case TOK_EQ:
o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); // sub d, a, b
ER(0x33, 0, d, a, b, 0x20); // sub d, a, b
if (op == TOK_NE)
o(0x33 | (3 << 12) | (d << 7) | (0 << 15) | (d << 20)); // sltu d, x0, d == snez d,d
ER(0x33, 3, d, 0, d, 0); // sltu d, x0, d == snez d,d
else
EI(0x13, 3, d, d, 1); // sltiu d, d, 1 == seqz d,d
vset_VT_CMP(TOK_NE);
@ -1007,7 +1013,7 @@ ST_FUNC void gen_opf(int op)
rd = get_reg(RC_FLOAT);
vtop->r = rd;
rd = freg(rd);
o(0x53 | (rd << 7) | (rs1 << 15) | (rs2 << 20) | (7 << 12) | (dbl << 25) | (op << 27)); // fop.[sd] RD, RS1, RS2 (dyn rm)
ER(0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
break;
case '-':
op = 1; // fsub
@ -1024,7 +1030,7 @@ ST_FUNC void gen_opf(int op)
rd = get_reg(RC_INT);
vtop->r = rd;
rd = ireg(rd);
o(0x53 | (rd << 7) | (rs1 << 15) | (rs2 << 20) | (op << 12) | (dbl << 25) | (0x14 << 27)); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
ER(0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
if (invert)
EI(0x13, 4, rd, rd, 1); // xori RD, 1
break;
@ -1175,7 +1181,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align)
int rr = ireg(gv(RC_INT));
EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15
EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16
o(0x33 | (2 << 7) | (2 << 15) | (rr << 20) | (0x20 << 25)); //sub sp, sp, rr
ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
vpop();
}
#endif