RISC-V: Add misa to DisasContext

gen methods should access state from DisasContext. Add misa
field to the DisasContext struct and remove CPURISCVState
argument from all gen methods.

Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
Michael Clark 2019-01-14 23:58:42 +00:00 committed by Palmer Dabbelt
parent d75377bf7b
commit db9f3fd69d
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41
1 changed files with 40 additions and 35 deletions

View File

@ -46,6 +46,7 @@ typedef struct DisasContext {
target_ulong priv_ver; target_ulong priv_ver;
uint32_t opcode; uint32_t opcode;
uint32_t mstatus_fs; uint32_t mstatus_fs;
uint32_t misa;
uint32_t mem_idx; uint32_t mem_idx;
/* Remember the rounding mode encoded in the previous fp instruction, /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status. Or -1 for which we have already installed into env->fp_status. Or -1 for
@ -75,6 +76,11 @@ static const int tcg_memop_lookup[8] = {
#define CASE_OP_32_64(X) case X #define CASE_OP_32_64(X) case X
#endif #endif
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
{
return ctx->misa & ext;
}
static void generate_exception(DisasContext *ctx, int excp) static void generate_exception(DisasContext *ctx, int excp)
{ {
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
@ -506,14 +512,13 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t opc, int rd,
tcg_temp_free(source1); tcg_temp_free(source1);
} }
static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd, static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
target_ulong imm)
{ {
target_ulong next_pc; target_ulong next_pc;
/* check misaligned: */ /* check misaligned: */
next_pc = ctx->base.pc_next + imm; next_pc = ctx->base.pc_next + imm;
if (!riscv_has_ext(env, RVC)) { if (!has_ext(ctx, RVC)) {
if ((next_pc & 0x3) != 0) { if ((next_pc & 0x3) != 0) {
gen_exception_inst_addr_mis(ctx); gen_exception_inst_addr_mis(ctx);
return; return;
@ -527,8 +532,8 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
ctx->base.is_jmp = DISAS_NORETURN; ctx->base.is_jmp = DISAS_NORETURN;
} }
static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc, static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
int rd, int rs1, target_long imm) target_long imm)
{ {
/* no chaining with JALR */ /* no chaining with JALR */
TCGLabel *misaligned = NULL; TCGLabel *misaligned = NULL;
@ -540,7 +545,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
tcg_gen_addi_tl(cpu_pc, cpu_pc, imm); tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2); tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
if (!riscv_has_ext(env, RVC)) { if (!has_ext(ctx, RVC)) {
misaligned = gen_new_label(); misaligned = gen_new_label();
tcg_gen_andi_tl(t0, cpu_pc, 0x2); tcg_gen_andi_tl(t0, cpu_pc, 0x2);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned); tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
@ -565,8 +570,8 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
tcg_temp_free(t0); tcg_temp_free(t0);
} }
static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc, static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
int rs1, int rs2, target_long bimm) target_long bimm)
{ {
TCGLabel *l = gen_new_label(); TCGLabel *l = gen_new_label();
TCGv source1, source2; TCGv source1, source2;
@ -603,7 +608,7 @@ static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
gen_goto_tb(ctx, 1, ctx->pc_succ_insn); gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
gen_set_label(l); /* branch taken */ gen_set_label(l); /* branch taken */
if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) { if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
/* misaligned */ /* misaligned */
gen_exception_inst_addr_mis(ctx); gen_exception_inst_addr_mis(ctx);
} else { } else {
@ -1314,8 +1319,8 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
} }
} }
static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc, static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
int rd, int rs1, int csr) int csr)
{ {
TCGv source1, csr_store, dest, rs1_pass, imm_rs1; TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
source1 = tcg_temp_new(); source1 = tcg_temp_new();
@ -1361,7 +1366,7 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
gen_exception_illegal(ctx); gen_exception_illegal(ctx);
break; break;
case 0x102: /* SRET */ case 0x102: /* SRET */
if (riscv_has_ext(env, RVS)) { if (has_ext(ctx, RVS)) {
gen_helper_sret(cpu_pc, cpu_env, cpu_pc); gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
tcg_gen_exit_tb(NULL, 0); /* no chaining */ tcg_gen_exit_tb(NULL, 0); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN; ctx->base.is_jmp = DISAS_NORETURN;
@ -1506,7 +1511,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
} }
} }
static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx) static void decode_RV32_64C1(DisasContext *ctx)
{ {
uint8_t funct3 = extract32(ctx->opcode, 13, 3); uint8_t funct3 = extract32(ctx->opcode, 13, 3);
uint8_t rd_rs1 = GET_C_RS1(ctx->opcode); uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
@ -1526,7 +1531,7 @@ static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
GET_C_IMM(ctx->opcode)); GET_C_IMM(ctx->opcode));
#else #else
/* C.JAL(RV32) -> jal x1, offset[11:1] */ /* C.JAL(RV32) -> jal x1, offset[11:1] */
gen_jal(env, ctx, 1, GET_C_J_IMM(ctx->opcode)); gen_jal(ctx, 1, GET_C_J_IMM(ctx->opcode));
#endif #endif
break; break;
case 2: case 2:
@ -1605,22 +1610,22 @@ static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
break; break;
case 5: case 5:
/* C.J -> jal x0, offset[11:1]*/ /* C.J -> jal x0, offset[11:1]*/
gen_jal(env, ctx, 0, GET_C_J_IMM(ctx->opcode)); gen_jal(ctx, 0, GET_C_J_IMM(ctx->opcode));
break; break;
case 6: case 6:
/* C.BEQZ -> beq rs1', x0, offset[8:1]*/ /* C.BEQZ -> beq rs1', x0, offset[8:1]*/
rs1s = GET_C_RS1S(ctx->opcode); rs1s = GET_C_RS1S(ctx->opcode);
gen_branch(env, ctx, OPC_RISC_BEQ, rs1s, 0, GET_C_B_IMM(ctx->opcode)); gen_branch(ctx, OPC_RISC_BEQ, rs1s, 0, GET_C_B_IMM(ctx->opcode));
break; break;
case 7: case 7:
/* C.BNEZ -> bne rs1', x0, offset[8:1]*/ /* C.BNEZ -> bne rs1', x0, offset[8:1]*/
rs1s = GET_C_RS1S(ctx->opcode); rs1s = GET_C_RS1S(ctx->opcode);
gen_branch(env, ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode)); gen_branch(ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode));
break; break;
} }
} }
static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx) static void decode_RV32_64C2(DisasContext *ctx)
{ {
uint8_t rd, rs2; uint8_t rd, rs2;
uint8_t funct3 = extract32(ctx->opcode, 13, 3); uint8_t funct3 = extract32(ctx->opcode, 13, 3);
@ -1654,7 +1659,7 @@ static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
if (extract32(ctx->opcode, 12, 1) == 0) { if (extract32(ctx->opcode, 12, 1) == 0) {
if (rs2 == 0) { if (rs2 == 0) {
/* C.JR -> jalr x0, rs1, 0*/ /* C.JR -> jalr x0, rs1, 0*/
gen_jalr(env, ctx, OPC_RISC_JALR, 0, rd, 0); gen_jalr(ctx, OPC_RISC_JALR, 0, rd, 0);
} else { } else {
/* C.MV -> add rd, x0, rs2 */ /* C.MV -> add rd, x0, rs2 */
gen_arith(ctx, OPC_RISC_ADD, rd, 0, rs2); gen_arith(ctx, OPC_RISC_ADD, rd, 0, rs2);
@ -1662,11 +1667,11 @@ static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
} else { } else {
if (rd == 0) { if (rd == 0) {
/* C.EBREAK -> ebreak*/ /* C.EBREAK -> ebreak*/
gen_system(env, ctx, OPC_RISC_ECALL, 0, 0, 0x1); gen_system(ctx, OPC_RISC_ECALL, 0, 0, 0x1);
} else { } else {
if (rs2 == 0) { if (rs2 == 0) {
/* C.JALR -> jalr x1, rs1, 0*/ /* C.JALR -> jalr x1, rs1, 0*/
gen_jalr(env, ctx, OPC_RISC_JALR, 1, rd, 0); gen_jalr(ctx, OPC_RISC_JALR, 1, rd, 0);
} else { } else {
/* C.ADD -> add rd, rd, rs2 */ /* C.ADD -> add rd, rd, rs2 */
gen_arith(ctx, OPC_RISC_ADD, rd, rd, rs2); gen_arith(ctx, OPC_RISC_ADD, rd, rd, rs2);
@ -1698,7 +1703,7 @@ static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
} }
} }
static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx) static void decode_RV32_64C(DisasContext *ctx)
{ {
uint8_t op = extract32(ctx->opcode, 0, 2); uint8_t op = extract32(ctx->opcode, 0, 2);
@ -1707,15 +1712,15 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
decode_RV32_64C0(ctx); decode_RV32_64C0(ctx);
break; break;
case 1: case 1:
decode_RV32_64C1(env, ctx); decode_RV32_64C1(ctx);
break; break;
case 2: case 2:
decode_RV32_64C2(env, ctx); decode_RV32_64C2(ctx);
break; break;
} }
} }
static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx) static void decode_RV32_64G(DisasContext *ctx)
{ {
int rs1; int rs1;
int rs2; int rs2;
@ -1750,13 +1755,13 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
break; break;
case OPC_RISC_JAL: case OPC_RISC_JAL:
imm = GET_JAL_IMM(ctx->opcode); imm = GET_JAL_IMM(ctx->opcode);
gen_jal(env, ctx, rd, imm); gen_jal(ctx, rd, imm);
break; break;
case OPC_RISC_JALR: case OPC_RISC_JALR:
gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm); gen_jalr(ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
break; break;
case OPC_RISC_BRANCH: case OPC_RISC_BRANCH:
gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2, gen_branch(ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
GET_B_IMM(ctx->opcode)); GET_B_IMM(ctx->opcode));
break; break;
case OPC_RISC_LOAD: case OPC_RISC_LOAD:
@ -1827,7 +1832,7 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
} }
break; break;
case OPC_RISC_SYSTEM: case OPC_RISC_SYSTEM:
gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1, gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF00000) >> 20); (ctx->opcode & 0xFFF00000) >> 20);
break; break;
default: default:
@ -1836,19 +1841,19 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
} }
} }
static void decode_opc(CPURISCVState *env, DisasContext *ctx) static void decode_opc(DisasContext *ctx)
{ {
/* check for compressed insn */ /* check for compressed insn */
if (extract32(ctx->opcode, 0, 2) != 3) { if (extract32(ctx->opcode, 0, 2) != 3) {
if (!riscv_has_ext(env, RVC)) { if (!has_ext(ctx, RVC)) {
gen_exception_illegal(ctx); gen_exception_illegal(ctx);
} else { } else {
ctx->pc_succ_insn = ctx->base.pc_next + 2; ctx->pc_succ_insn = ctx->base.pc_next + 2;
decode_RV32_64C(env, ctx); decode_RV32_64C(ctx);
} }
} else { } else {
ctx->pc_succ_insn = ctx->base.pc_next + 4; ctx->pc_succ_insn = ctx->base.pc_next + 4;
decode_RV32_64G(env, ctx); decode_RV32_64G(ctx);
} }
} }
@ -1861,6 +1866,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK; ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS; ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS;
ctx->priv_ver = env->priv_ver; ctx->priv_ver = env->priv_ver;
ctx->misa = env->misa;
ctx->frm = -1; /* unknown rounding mode */ ctx->frm = -1; /* unknown rounding mode */
} }
@ -1891,14 +1897,13 @@ static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
return true; return true;
} }
static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{ {
DisasContext *ctx = container_of(dcbase, DisasContext, base); DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPURISCVState *env = cpu->env_ptr; CPURISCVState *env = cpu->env_ptr;
ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
decode_opc(env, ctx); decode_opc(ctx);
ctx->base.pc_next = ctx->pc_succ_insn; ctx->base.pc_next = ctx->pc_succ_insn;
if (ctx->base.is_jmp == DISAS_NEXT) { if (ctx->base.is_jmp == DISAS_NEXT) {