target/riscv: Convert RVXI csr insns to decodetree
Acked-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
This commit is contained in:
parent
0c865e856a
commit
771fbe156a
@ -22,6 +22,7 @@
|
|||||||
%rd 7:5
|
%rd 7:5
|
||||||
|
|
||||||
%sh10 20:10
|
%sh10 20:10
|
||||||
|
%csr 20:12
|
||||||
|
|
||||||
# immediates:
|
# immediates:
|
||||||
%imm_i 20:s12
|
%imm_i 20:s12
|
||||||
@ -43,6 +44,7 @@
|
|||||||
@j .................... ..... ....... imm=%imm_j %rd
|
@j .................... ..... ....... imm=%imm_j %rd
|
||||||
|
|
||||||
@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
|
@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
|
||||||
|
@csr ............ ..... ... ..... ....... %csr %rs1 %rd
|
||||||
|
|
||||||
# *** RV32I Base Instruction Set ***
|
# *** RV32I Base Instruction Set ***
|
||||||
lui .................... ..... 0110111 @u
|
lui .................... ..... 0110111 @u
|
||||||
@ -84,3 +86,9 @@ or 0000000 ..... ..... 110 ..... 0110011 @r
|
|||||||
and 0000000 ..... ..... 111 ..... 0110011 @r
|
and 0000000 ..... ..... 111 ..... 0110011 @r
|
||||||
fence ---- pred:4 succ:4 ----- 000 ----- 0001111
|
fence ---- pred:4 succ:4 ----- 000 ----- 0001111
|
||||||
fence_i ---- ---- ---- ----- 001 ----- 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
|
||||||
|
@ -337,3 +337,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
|||||||
ctx->base.is_jmp = DISAS_NORETURN;
|
ctx->base.is_jmp = DISAS_NORETURN;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RISCV_OP_CSR_PRE do {\
|
||||||
|
source1 = tcg_temp_new(); \
|
||||||
|
csr_store = tcg_temp_new(); \
|
||||||
|
dest = tcg_temp_new(); \
|
||||||
|
rs1_pass = tcg_temp_new(); \
|
||||||
|
gen_get_gpr(source1, a->rs1); \
|
||||||
|
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
|
||||||
|
tcg_gen_movi_tl(rs1_pass, a->rs1); \
|
||||||
|
tcg_gen_movi_tl(csr_store, a->csr); \
|
||||||
|
gen_io_start();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define RISCV_OP_CSR_POST do {\
|
||||||
|
gen_io_end(); \
|
||||||
|
gen_set_gpr(a->rd, dest); \
|
||||||
|
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
|
||||||
|
tcg_gen_exit_tb(NULL, 0); \
|
||||||
|
ctx->base.is_jmp = DISAS_NORETURN; \
|
||||||
|
tcg_temp_free(source1); \
|
||||||
|
tcg_temp_free(csr_store); \
|
||||||
|
tcg_temp_free(dest); \
|
||||||
|
tcg_temp_free(rs1_pass); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrw(dest, cpu_env, source1, csr_store);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
|
||||||
|
{
|
||||||
|
TCGv source1, csr_store, dest, rs1_pass;
|
||||||
|
RISCV_OP_CSR_PRE;
|
||||||
|
gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
|
||||||
|
RISCV_OP_CSR_POST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -1476,16 +1476,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
|
|||||||
static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
||||||
int csr)
|
int csr)
|
||||||
{
|
{
|
||||||
TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
|
TCGv source1, dest;
|
||||||
source1 = tcg_temp_new();
|
source1 = tcg_temp_new();
|
||||||
csr_store = tcg_temp_new();
|
|
||||||
dest = tcg_temp_new();
|
dest = tcg_temp_new();
|
||||||
rs1_pass = tcg_temp_new();
|
|
||||||
imm_rs1 = tcg_temp_new();
|
|
||||||
gen_get_gpr(source1, rs1);
|
gen_get_gpr(source1, rs1);
|
||||||
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
||||||
tcg_gen_movi_tl(rs1_pass, rs1);
|
|
||||||
tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
|
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
/* Extract funct7 value and check whether it matches SFENCE.VMA */
|
/* Extract funct7 value and check whether it matches SFENCE.VMA */
|
||||||
@ -1556,45 +1551,9 @@ static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
tcg_gen_movi_tl(imm_rs1, rs1);
|
|
||||||
gen_io_start();
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_CSRRW:
|
|
||||||
gen_helper_csrrw(dest, cpu_env, source1, csr_store);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_CSRRS:
|
|
||||||
gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_CSRRC:
|
|
||||||
gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_CSRRWI:
|
|
||||||
gen_helper_csrrw(dest, cpu_env, imm_rs1, csr_store);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_CSRRSI:
|
|
||||||
gen_helper_csrrs(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_CSRRCI:
|
|
||||||
gen_helper_csrrc(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gen_io_end();
|
|
||||||
gen_set_gpr(rd, dest);
|
|
||||||
/* end tb since we may be changing priv modes, to get mmu_index right */
|
|
||||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
|
||||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
|
||||||
ctx->base.is_jmp = DISAS_NORETURN;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
tcg_temp_free(source1);
|
tcg_temp_free(source1);
|
||||||
tcg_temp_free(csr_store);
|
|
||||||
tcg_temp_free(dest);
|
tcg_temp_free(dest);
|
||||||
tcg_temp_free(rs1_pass);
|
|
||||||
tcg_temp_free(imm_rs1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_RV32_64C0(DisasContext *ctx)
|
static void decode_RV32_64C0(DisasContext *ctx)
|
||||||
|
Loading…
Reference in New Issue
Block a user