Unify 4 functions, sharing code.
Reviewed-by: Alistair Francis <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
---
disas/riscv.c | 70 ++++++++++++++++-----------------------------------
1 file changed, 21 insertions(+), 49 deletions(-)
diff --git a/disas/riscv.c b/disas/riscv.c
index af43940732..47fae7316c 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -5377,64 +5377,36 @@ static void decode_inst_lift_pseudo(rv_decode *dec)
/* decompress instruction */
-static void decode_inst_decompress_rv32(rv_decode *dec)
+static const rv_opcode_data *decode_inst_decompress(rv_decode *dec, rv_isa isa,
+ const rv_opcode_data *op)
{
- const rv_opcode_data *opcode_data = dec->opcode_data;
- int decomp_op = opcode_data[dec->op].decomp_rv32;
- if (decomp_op != rv_op_illegal) {
- if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
- && dec->imm == 0) {
- dec->op = rv_op_illegal;
- } else {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
- }
- }
-}
+ int decomp_op;
-static void decode_inst_decompress_rv64(rv_decode *dec)
-{
- const rv_opcode_data *opcode_data = dec->opcode_data;
- int decomp_op = opcode_data[dec->op].decomp_rv64;
- if (decomp_op != rv_op_illegal) {
- if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
- && dec->imm == 0) {
- dec->op = rv_op_illegal;
- } else {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
- }
- }
-}
-
-static void decode_inst_decompress_rv128(rv_decode *dec)
-{
- const rv_opcode_data *opcode_data = dec->opcode_data;
- int decomp_op = opcode_data[dec->op].decomp_rv128;
- if (decomp_op != rv_op_illegal) {
- if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
- && dec->imm == 0) {
- dec->op = rv_op_illegal;
- } else {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
- }
- }
-}
-
-static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
-{
switch (isa) {
case rv32:
- decode_inst_decompress_rv32(dec);
+ decomp_op = op->decomp_rv32;
break;
case rv64:
- decode_inst_decompress_rv64(dec);
+ decomp_op = op->decomp_rv64;
break;
case rv128:
- decode_inst_decompress_rv128(dec);
+ decomp_op = op->decomp_rv128;
break;
+ default:
+ g_assert_not_reached();
}
+
+ if (decomp_op != rv_op_illegal) {
+ if ((op->decomp_data & rvcd_imm_nz) && dec->imm == 0) {
+ dec->opcode_data = rvi_opcode_data;
+ dec->op = rv_op_illegal;
+ } else {
+ dec->op = decomp_op;
+ }
+ op = &dec->opcode_data[decomp_op];
+ dec->codec = op->codec;
+ }
+ return op;
}
/* disassemble instruction */
@@ -5491,7 +5463,7 @@ static GString *disasm_inst(rv_isa isa, uint64_t pc,
rv_inst inst,
op = &dec.opcode_data[dec.op];
decode_inst_operands(&dec, isa, op);
- decode_inst_decompress(&dec, isa);
+ op = decode_inst_decompress(&dec, isa, op);
decode_inst_lift_pseudo(&dec);
return format_inst(24, &dec);
}
--
2.43.0