target/riscv: Convert RVXI csr insns to decodetree

Backports commit 771fbe156a2a2be964a4fbe6251339a5570a26c4 from qemu
This commit is contained in:
Bastian Koppelmann 2019-03-18 16:16:32 -04:00 committed by Lioncash
parent de580ee378
commit 4ea449a809
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 92 additions and 44 deletions

View file

@ -22,6 +22,7 @@
%rd 7:5
%sh10 20:10
%csr 20:12
# immediates:
%imm_i 20:s12
@ -43,6 +44,7 @@
@j .................... ..... ....... imm=%imm_j %rd
@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
@csr ............ ..... ... ..... ....... %csr %rs1 %rd
# *** RV32I Base Instruction Set ***
lui .................... ..... 0110111 @u
@ -84,3 +86,9 @@ or 0000000 ..... ..... 110 ..... 0110011 @r
and 0000000 ..... ..... 111 ..... 0110011 @r
fence ---- pred:4 succ:4 ----- 000 ----- 0001111
fence_i ---- ---- ---- ----- 001 ----- 0001111
csrrw ............ ..... 001 ..... 1110011 @csr
csrrs ............ ..... 010 ..... 1110011 @csr
csrrc ............ ..... 011 ..... 1110011 @csr
csrrwi ............ ..... 101 ..... 1110011 @csr
csrrsi ............ ..... 110 ..... 1110011 @csr
csrrci ............ ..... 111 ..... 1110011 @csr

View file

@ -343,3 +343,86 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
ctx->base.is_jmp = DISAS_NORETURN;
return true;
}
#define RISCV_OP_CSR_PRE do {\
source1 = tcg_temp_new(tcg_ctx); \
csr_store = tcg_temp_new(tcg_ctx); \
dest = tcg_temp_new(tcg_ctx); \
rs1_pass = tcg_temp_new(tcg_ctx); \
gen_get_gpr(ctx, source1, a->rs1); \
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->base.pc_next); \
tcg_gen_movi_tl(tcg_ctx, rs1_pass, a->rs1); \
tcg_gen_movi_tl(tcg_ctx, csr_store, a->csr); \
} while (0)
#define RISCV_OP_CSR_POST do {\
gen_set_gpr(ctx, a->rd, dest); \
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->pc_succ_insn); \
tcg_gen_exit_tb(tcg_ctx, NULL, 0); \
ctx->base.is_jmp = DISAS_NORETURN; \
tcg_temp_free(tcg_ctx, source1); \
tcg_temp_free(tcg_ctx, csr_store); \
tcg_temp_free(tcg_ctx, dest); \
tcg_temp_free(tcg_ctx, rs1_pass); \
} while (0)
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrw(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store);
RISCV_OP_CSR_POST;
return true;
}
static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrs(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store, rs1_pass);
RISCV_OP_CSR_POST;
return true;
}
static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrc(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store, rs1_pass);
RISCV_OP_CSR_POST;
return true;
}
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrw(tcg_ctx, dest, tcg_ctx->cpu_env, rs1_pass, csr_store);
RISCV_OP_CSR_POST;
return true;
}
static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrs(tcg_ctx, dest, tcg_ctx->cpu_env, rs1_pass, csr_store, rs1_pass);
RISCV_OP_CSR_POST;
return true;
}
static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass;
RISCV_OP_CSR_PRE;
gen_helper_csrrc(tcg_ctx, dest, tcg_ctx->cpu_env, rs1_pass, csr_store, rs1_pass);
RISCV_OP_CSR_POST;
return true;
}

View file

@ -1545,16 +1545,11 @@ static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
TCGv source1, dest;
source1 = tcg_temp_new(tcg_ctx);
csr_store = tcg_temp_new(tcg_ctx);
dest = tcg_temp_new(tcg_ctx);
rs1_pass = tcg_temp_new(tcg_ctx);
imm_rs1 = tcg_temp_new(tcg_ctx);
gen_get_gpr(ctx, source1, rs1);
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->base.pc_next);
tcg_gen_movi_tl(tcg_ctx, rs1_pass, rs1);
tcg_gen_movi_tl(tcg_ctx, csr_store, csr); /* copy into temp reg to feed to helper */
#ifndef CONFIG_USER_ONLY
/* Extract funct7 value and check whether it matches SFENCE.VMA */
@ -1625,47 +1620,9 @@ static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
break;
}
break;
default:
tcg_gen_movi_tl(tcg_ctx, imm_rs1, rs1);
// Unicorn: Commented out
//gen_io_start();
switch (opc) {
case OPC_RISC_CSRRW:
gen_helper_csrrw(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store);
break;
case OPC_RISC_CSRRS:
gen_helper_csrrs(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store, rs1_pass);
break;
case OPC_RISC_CSRRC:
gen_helper_csrrc(tcg_ctx, dest, tcg_ctx->cpu_env, source1, csr_store, rs1_pass);
break;
case OPC_RISC_CSRRWI:
gen_helper_csrrw(tcg_ctx, dest, tcg_ctx->cpu_env, imm_rs1, csr_store);
break;
case OPC_RISC_CSRRSI:
gen_helper_csrrs(tcg_ctx, dest, tcg_ctx->cpu_env, imm_rs1, csr_store, rs1_pass);
break;
case OPC_RISC_CSRRCI:
gen_helper_csrrc(tcg_ctx, dest, tcg_ctx->cpu_env, imm_rs1, csr_store, rs1_pass);
break;
default:
gen_exception_illegal(ctx);
return;
}
// Unicorn: Commented out
//gen_io_end();
gen_set_gpr(ctx, rd, dest);
/* end tb since we may be changing priv modes, to get mmu_index right */
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->pc_succ_insn);
tcg_gen_exit_tb(tcg_ctx, NULL, 0); /* no chaining */
ctx->base.is_jmp = DISAS_NORETURN;
break;
}
tcg_temp_free(tcg_ctx, source1);
tcg_temp_free(tcg_ctx, csr_store);
tcg_temp_free(tcg_ctx, dest);
tcg_temp_free(tcg_ctx, rs1_pass);
tcg_temp_free(tcg_ctx, imm_rs1);
}
static void decode_RV32_64C0(DisasContext *ctx)