From 2c84ab9e96cb9247978ae24a2ac844a6b3789dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sat, 25 Apr 2026 23:42:01 +0300 Subject: [PATCH 01/10] lifting the base (integer) extension of RISC-V and some compressed variants of the instructions in it for 32-bit arch variant only, and add some tests --- librz/arch/il/analysis_il.c | 1 + librz/arch/isa/riscv/riscv_il.c | 292 +++++++++++++++++++++ librz/arch/isa/riscv/riscv_il.h | 20 ++ librz/arch/meson.build | 1 + librz/arch/p/analysis/analysis_riscv_cs.c | 10 +- test/db/asm/riscv_32 | 296 ++++++++++++---------- 6 files changed, 479 insertions(+), 141 deletions(-) create mode 100644 librz/arch/isa/riscv/riscv_il.c create mode 100644 librz/arch/isa/riscv/riscv_il.h diff --git a/librz/arch/il/analysis_il.c b/librz/arch/il/analysis_il.c index 8101846aa04..84cebddda77 100644 --- a/librz/arch/il/analysis_il.c +++ b/librz/arch/il/analysis_il.c @@ -140,6 +140,7 @@ static RzILRegBinding *setup_reg_binding(RzAnalysis *a, RzAnalysisILConfig *cfg) goto new_real; } succ = rz_reg_set_profile_string(reg, profile); + free(profile); if (!succ) { goto new_real; diff --git a/librz/arch/isa/riscv/riscv_il.c b/librz/arch/isa/riscv/riscv_il.c new file mode 100644 index 00000000000..37a2b1601eb --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il.c @@ -0,0 +1,292 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause +#include "analysis_private.h" +#include "riscv.h" +#include "rz_il/rz_il_opcodes.h" +#include "rz_types.h" +#include "rz_util/rz_assert.h" +#include +#include "riscv_il.h" + +#include +static const char *riscv_register_names[] = { + [RISCV_REG_X1] = "ra", + [RISCV_REG_X2] = "sp", + [RISCV_REG_X3] = "gp", + [RISCV_REG_X4] = "tp", + [RISCV_REG_X5] = "t0", + [RISCV_REG_X6] = "t1", + [RISCV_REG_X7] = "t2", + [RISCV_REG_X8] = "s0", + [RISCV_REG_X9] = "s1", + [RISCV_REG_X10] = "a0", + [RISCV_REG_X11] = "a1", + [RISCV_REG_X12] = "a2", + [RISCV_REG_X13] = "a3", + [RISCV_REG_X14] = "a4", + [RISCV_REG_X15] = "a5", + [RISCV_REG_X16] = "a6", + [RISCV_REG_X17] = "a7", + [RISCV_REG_X18] = "s2", + [RISCV_REG_X19] = "s3", + [RISCV_REG_X20] = "s4", + [RISCV_REG_X21] = "s5", + [RISCV_REG_X22] = "s6", + [RISCV_REG_X23] = "s7", + [RISCV_REG_X24] = "s8", + [RISCV_REG_X25] = "s9", + [RISCV_REG_X26] = "s10", + [RISCV_REG_X27] = "s11", + [RISCV_REG_X28] = "t3", + [RISCV_REG_X29] = "t4", + [RISCV_REG_X30] = "t5", + [RISCV_REG_X31] = "t6", +}; + +#define RISCV_GET_REG(reg) (((reg) != RISCV_REG_X0) ? (VARG(riscv_register_names[reg])) : UN(analysis->bits, 0)) +#define RISCV_SET_REG(reg, r) (((reg) != RISCV_REG_X0) ? (SETG(riscv_register_names[reg], r)) : ((rz_il_op_pure_free(r), NOP()))) + +#define DEFINE_LIFTER(name, decoder, result) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ + decoder(analysis, insn); \ + return RISCV_SET_REG(rd, result); \ + } + +// by default, a RISC-V jump both sets a destination and sets the PC (i.e., jumps) +#define DEFINE_LIFTER_FOR_JUMP(name, decoder, result, jmp_effect) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ + decoder(analysis, insn); \ + return SEQ2( \ + RISCV_SET_REG(rd, result), \ + jmp_effect); \ + } + +#define DEFINE_LIFTER_WITH_EFFECT(name, decoder, effect) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ + decoder(analysis, insn); \ + return effect; \ + } + +// oneway jumps are those that don't have a destination register +#define DEFINE_LIFTER_FOR_ONEWAY_JUMP DEFINE_LIFTER_WITH_EFFECT + +#define TWICE_FOR(name1, name2, lifter, ...) \ + lifter(name1, __VA_ARGS__) \ + lifter(name2, __VA_ARGS__) + +#define THRICE_FOR(name1, name2, name3, lifter, ...) \ + TWICE_FOR(name1, name2, lifter, __VA_ARGS__) \ + lifter(name3, __VA_ARGS__) + +#define FOR_4(name1, name2, name3, name4, lifter, ...) \ + TWICE_FOR(name1, name2, lifter, __VA_ARGS__) \ + TWICE_FOR(name3, name4, lifter, __VA_ARGS__) + +#define DECODE_RD_RS_IMM(analysis, insn) \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); + +#define DECODE_RD_RS_RS(analysis, insn) \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[2].reg); + +#define DECODE_RS_IMM(analysis, insn) \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); + +#define DECODE_RS_RS_IMM(analysis, insn) \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); + +#define DECODE_RD_RS(analysis, insn) \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); + +#define DECODE_IMM(analysis, insn) \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[0].imm); + +#define DECODE_RD_IMM(analysis, insn) \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); + +#define DECODE_RS_RS_IMM_MEM(analysis, insn) \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); + +#define DECODE_RD_RS_IMM_MEM(analysis, insn) \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); + +#define USE_LIFTER(name, uppername) [RISCV_INS_##uppername] = rz_riscv_lift_##name + +FOR_4(addi, c_addi, c_addi16sp, c_addi4spn, + DEFINE_LIFTER, DECODE_RD_RS_IMM, ADD(rs, imm)) +TWICE_FOR(slli, c_slli, + DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTL0(rs, imm)) +TWICE_FOR(andi, c_andi, + DEFINE_LIFTER, DECODE_RD_RS_IMM, LOGAND(rs, imm)) +DEFINE_LIFTER(ori, DECODE_RD_RS_IMM, LOGOR(rs, imm)) +DEFINE_LIFTER(xori, DECODE_RD_RS_IMM, LOGXOR(rs, imm)) +DEFINE_LIFTER(slti, DECODE_RD_RS_IMM, BOOL_TO_BV(SLT(rs, imm), analysis->bits)) +DEFINE_LIFTER(sltiu, DECODE_RD_RS_IMM, BOOL_TO_BV(ULT(rs, imm), analysis->bits)) +TWICE_FOR(srli, c_srli, + DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTR0(rs, imm)) +TWICE_FOR(srai, c_srai, + DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTRA(rs, imm)) + +DEFINE_LIFTER(add, DECODE_RD_RS_RS, ADD(rs1, rs2)) +DEFINE_LIFTER(sub, DECODE_RD_RS_RS, SUB(rs1, rs2)) +DEFINE_LIFTER(and, DECODE_RD_RS_RS, LOGAND(rs1, rs2)) +DEFINE_LIFTER(or, DECODE_RD_RS_RS, LOGOR(rs1, rs2)) +DEFINE_LIFTER(xor, DECODE_RD_RS_RS, LOGXOR(rs1, rs2)) +DEFINE_LIFTER(slt, DECODE_RD_RS_RS, BOOL_TO_BV(SLT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sltu, DECODE_RD_RS_RS, BOOL_TO_BV(ULT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sll, DECODE_RD_RS_RS, SHIFTL0(rs1, rs2)) +DEFINE_LIFTER(srl, DECODE_RD_RS_RS, SHIFTR0(rs1, rs2)) +DEFINE_LIFTER(sra, DECODE_RD_RS_RS, SHIFTRA(rs1, rs2)) + +#define DEFINE_LIFTER_FOR_BRANCH(name, decoder, condition) \ + DEFINE_LIFTER_FOR_ONEWAY_JUMP(name, decoder, BRANCH(condition, JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) + +DEFINE_LIFTER_FOR_BRANCH(beq, DECODE_RS_RS_IMM, EQ(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bne, DECODE_RS_RS_IMM, NE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(blt, DECODE_RS_RS_IMM, SLT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bge, DECODE_RS_RS_IMM, SGE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bltu, DECODE_RS_RS_IMM, ULT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bgeu, DECODE_RS_RS_IMM, UGE(rs1, rs2)) + +DEFINE_LIFTER_FOR_BRANCH(c_beqz, DECODE_RS_IMM, EQ(rs, UN(analysis->bits, 0))) +DEFINE_LIFTER_FOR_BRANCH(c_bnez, DECODE_RS_IMM, NE(rs, UN(analysis->bits, 0))) + +DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) + +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_IMM, JMP(imm)) + +DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(imm)) + +TWICE_FOR(jalr, c_jr, + DEFINE_LIFTER_FOR_JUMP, DECODE_RD_RS_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) + +TWICE_FOR(lui, c_lui, + DEFINE_LIFTER, DECODE_RD_IMM, SHIFTL0(imm, UN(analysis->bits, 12))) +DEFINE_LIFTER(c_li, DECODE_RD_IMM, DUP(imm)) +DEFINE_LIFTER(auipc, DECODE_RD_IMM, ADD(UN(analysis->bits, current_addr), SHIFTL0(imm, UN(analysis->bits, 12)))) + +DEFINE_LIFTER_WITH_EFFECT(sb, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(8, IL_FALSE, rs1))) +DEFINE_LIFTER_WITH_EFFECT(sh, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(16, IL_FALSE, rs1))) + +THRICE_FOR(sw, c_sw, c_swsp, + DEFINE_LIFTER_WITH_EFFECT, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), analysis->bits == 32 ? rs1 : CAST(64, IL_FALSE, rs1))) + +TWICE_FOR(sd, c_sd, + DEFINE_LIFTER_WITH_EFFECT, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), rs1)) + +THRICE_FOR(lw, c_lwsp, c_lw, + DEFINE_LIFTER, DECODE_RD_RS_IMM_MEM, analysis->bits == 32 ? LOADW(32, ADD(rs, imm)) : SIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) +DEFINE_LIFTER(lb, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lh, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) +DEFINE_LIFTER(lbu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lhu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) + +TWICE_FOR(ld, c_ld, + DEFINE_LIFTER, DECODE_RD_RS_IMM_MEM, LOADW(64, ADD(rs, imm))) + +#include + +static const RiscvInstructionLifter riscv_lifters[] = { + USE_LIFTER(addi, ADDI), + USE_LIFTER(c_addi, C_ADDI), + USE_LIFTER(c_addi16sp, C_ADDI16SP), + USE_LIFTER(c_addi4spn, C_ADDI4SPN), + USE_LIFTER(andi, ANDI), + USE_LIFTER(c_andi, C_ANDI), + USE_LIFTER(ori, ORI), + USE_LIFTER(xori, XORI), + USE_LIFTER(slti, SLTI), + USE_LIFTER(sltiu, SLTIU), + USE_LIFTER(slli, SLLI), + USE_LIFTER(srli, SRLI), + USE_LIFTER(srai, SRAI), + USE_LIFTER(c_slli, C_SLLI), + USE_LIFTER(c_srli, C_SRLI), + USE_LIFTER(c_srai, C_SRAI), + USE_LIFTER(jalr, JALR), + USE_LIFTER(c_jr, C_JR), + USE_LIFTER(lb, LB), + USE_LIFTER(lh, LH), + USE_LIFTER(lw, LW), + USE_LIFTER(lbu, LBU), + USE_LIFTER(lhu, LHU), + USE_LIFTER(c_lwsp, C_LWSP), + USE_LIFTER(c_lw, C_LW), + USE_LIFTER(ld, LD), + USE_LIFTER(c_ld, C_LD), + USE_LIFTER(lui, LUI), + USE_LIFTER(c_lui, C_LUI), + USE_LIFTER(c_li, C_LI), + USE_LIFTER(auipc, AUIPC), + USE_LIFTER(beq, BEQ), + USE_LIFTER(bne, BNE), + USE_LIFTER(blt, BLT), + USE_LIFTER(bge, BGE), + USE_LIFTER(bltu, BLTU), + USE_LIFTER(bgeu, BGEU), + USE_LIFTER(c_beqz, C_BEQZ), + USE_LIFTER(c_bnez, C_BNEZ), + USE_LIFTER(sb, SB), + USE_LIFTER(sh, SH), + USE_LIFTER(sw, SW), + USE_LIFTER(c_sw, C_SW), + USE_LIFTER(c_swsp, C_SWSP), + USE_LIFTER(sd, SD), + USE_LIFTER(c_sd, C_SD), + USE_LIFTER(add, ADD), + USE_LIFTER(sub, SUB), + USE_LIFTER(and, AND), + USE_LIFTER(or, OR), + USE_LIFTER(xor, XOR), + USE_LIFTER(slt, SLT), + USE_LIFTER(sltu, SLTU), + USE_LIFTER(sll, SLL), + USE_LIFTER(srl, SRL), + USE_LIFTER(sra, SRA), + USE_LIFTER(jal, JAL), + USE_LIFTER(c_mv, C_MV), + USE_LIFTER(c_j, C_J), +}; + +RZ_OWN RZ_IPI RzILOpEffect * +rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { + rz_return_val_if_fail(analysis && op && insn, NULL); + + if (insn->id > 0 && insn->id < RZ_ARRAY_SIZE(riscv_lifters)) { + RiscvInstructionLifter lifter = riscv_lifters[insn->id]; + if (lifter) { + return lifter(analysis, op, insn, current_addr, size); + } else { + RZ_LOG_ERROR("No lifter found for instruction %s (id: %d) (0x%08x)", insn->mnemonic, insn->id, rz_read_le32(insn->bytes)); + } + } + rz_warn_if_reached(); + return NULL; +} + +RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis) { + rz_return_val_if_fail(analysis, NULL); + + RzAnalysisILConfig *conf = rz_analysis_il_config_new(analysis->bits, analysis->big_endian, analysis->bits); + + return conf; +} \ No newline at end of file diff --git a/librz/arch/isa/riscv/riscv_il.h b/librz/arch/isa/riscv/riscv_il.h new file mode 100644 index 00000000000..eb398ed9042 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RZ_ARCH_ISA_RISCV_IL_H +#define RZ_ARCH_ISA_RISCV_IL_H + +#include +#include + +#include +#include +typedef RzILOpEffect *(*RiscvInstructionLifter)(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size); + +RZ_OWN RZ_IPI RzILOpEffect * +rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size); + +RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis); + +#endif \ No newline at end of file diff --git a/librz/arch/meson.build b/librz/arch/meson.build index 93056607361..acbc825e2ef 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -302,6 +302,7 @@ arch_isa_sources = [ 'isa/pyc/opcode_analysis.c', 'isa/pyc/opcode_arg_fmt.c', 'isa/pyc/pyc_dis.c', + 'isa/riscv/riscv_il.c', 'isa/rl78/rl78.c', 'isa/rl78/rl78_instr.c', 'isa/rl78/rl78_maps.c', diff --git a/librz/arch/p/analysis/analysis_riscv_cs.c b/librz/arch/p/analysis/analysis_riscv_cs.c index aa6725346b9..545378548b4 100644 --- a/librz/arch/p/analysis/analysis_riscv_cs.c +++ b/librz/arch/p/analysis/analysis_riscv_cs.c @@ -14,6 +14,8 @@ #include "analysis_riscv_utils.h" #include +#include + #define OPERAND(x) insn->detail->riscv.operands[x] #define REGID(x) insn->detail->riscv.operands[x].reg #define REG(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].reg) @@ -1922,6 +1924,11 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf set_op_family(op, insn); set_op_extra_metadata(analysis, op, ctx->hndl, insn); set_stack_effect(op, insn); + + if (mask & RZ_ANALYSIS_OP_MASK_IL) { + RzILOpEffect *il_op = rz_riscv_lift_instr(analysis, op, insn, addr, op->size); + op->il_op = il_op; + } } set_opdir(op); if (insn && mask & RZ_ANALYSIS_OP_MASK_OPEX) { @@ -2148,7 +2155,7 @@ static char *get_reg_profile(RzAnalysis *analysis) { "gpr ft9 .64 488 0\n" // =f29 "gpr ft10 .64 496 0\n" // =f30 "gpr ft11 .64 504 0\n" // =f31 - "gpr fcsr .32 512 0\n" + "gpr fcsr .64 512 0\n" // vector registers // assume each register is 512 bits (64 bytes) for maximum compatibility // TODO: make the width accurately reflect the exact width defined in the binary @@ -2276,6 +2283,7 @@ RzAnalysisPlugin rz_analysis_plugin_riscv_cs = { .archinfo = archinfo, .bits = 32 | 64, .op = &analyze_op, + .il_config = rz_riscv_il_config, .init = riscv_init, .fini = riscv_fini, }; diff --git a/test/db/asm/riscv_32 b/test/db/asm/riscv_32 index 29165a9578d..269ff99bf7a 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -1,138 +1,145 @@ -d "addi sp, sp, -0x90" 7571 -d "lui a5, 0x10" c167 -d "sw a5, 0x1c(sp)" 3ece -d "lui a5, 0x30" b7070300 -d "sw a5, 0x24(sp)" 3ed2 -d "lui a5, 0xc" b167 -d "sw a5, 0x3c(sp)" 3ede -d "lui a5, 0xffff8" e177 -d "sw s1, 0x84(sp)" 26c3 -d "sw ra, 0x8c(sp)" 06c7 -d "sw s0, 0x88(sp)" 22c5 -d "sw s2, 0x80(sp)" 4ac1 -d "sw s3, 0x7c(sp)" cede -d "sw s4, 0x78(sp)" d2dc -d "sw s5, 0x74(sp)" d6da -d "sw s6, 0x70(sp)" dad8 -d "sw s7, 0x6c(sp)" ded6 -d "sw s8, 0x68(sp)" e2d4 -d "sw s9, 0x64(sp)" e6d2 -d "sw s10, 0x60(sp)" ead0 -d "sw s11, 0x5c(sp)" eece -d "sw zero, 0x28(sp)" 02d4 -d "sw zero, 0x20(sp)" 02d0 -d "sw zero, 0x38(sp)" 02dc -d "sw zero, 0x30(sp)" 02d8 -d "sw a5, 0x34(sp)" 3eda -d "sw zero, 0x18(sp)" 02cc -d "lui s1, 0x40" b7040400 0x38 -d "lui a5, 0x10013" b7370110 -d "lw a5, 4(a5)" dc43 0x40 -d "blez a5, 0x64" 6351f002 0x42 -d "lw ra, 0x8c(sp)" ba40 0x40 -d "lw s0, 0x88(sp)" 2a44 0x40 -d "lw s1, 0x84(sp)" 9a44 0x40 -d "lw s2, 0x80(sp)" 0a49 0x40 -d "lw s3, 0x7c(sp)" f659 0x40 -d "lw s4, 0x78(sp)" 665a 0x44 -d "lw s5, 0x74(sp)" d65a 0x48 -d "lw s6, 0x70(sp)" 465b 0x40 -d "lw s7, 0x6c(sp)" b65b 0x40 -d "lw s8, 0x68(sp)" 265c 0x40 -d "lw s9, 0x64(sp)" 965c 0x40 -d "lw s10, 0x60(sp)" 065d 0x40 -d "lw s11, 0x5c(sp)" f64d 0x40 +# ----------------------------- C_ADDI16SP ----------------------------- +d "addi sp, sp, -0x90" 7571 0x0 (set sp (+ (var sp) (bv 32 0xffffff70))) +# ----------------------------- ADDI ----------------------------- +d "addi a1, a1, 0x700" 93850570 0x0 (set a1 (+ (var a1) (bv 32 0x700))) +# ----------------------------- C_ADDI4SPN ----------------------------- +d "addi s0, sp, 0x80" 0001 0x0 (set s0 (+ (var sp) (bv 32 0x80))) +# ----------------------------- C_ADDI --------------------------------- +d "addi sp, sp, -0x20" 0111 0x0 (set sp (+ (var sp) (bv 32 0xffffffe0))) +d "lui a5, 0x10" c167 0x0 (set a5 (<< (bv 32 0x10) (bv 32 0xc) false)) +d "sw a5, 0x1c(sp)" 3ece 0x0 (storew 0 (+ (var sp) (bv 32 0x1c)) (var a5)) +d "lui a5, 0x30" b7070300 0x0 (set a5 (<< (bv 32 0x30) (bv 32 0xc) false)) +d "sw a5, 0x24(sp)" 3ed2 0x0 (storew 0 (+ (var sp) (bv 32 0x24)) (var a5)) +d "lui a5, 0xc" b167 0x0 (set a5 (<< (bv 32 0xc) (bv 32 0xc) false)) +d "sw a5, 0x3c(sp)" 3ede 0x0 (storew 0 (+ (var sp) (bv 32 0x3c)) (var a5)) +d "lui a5, 0xffff8" e177 0x0 (set a5 (<< (bv 32 0xffff8) (bv 32 0xc) false)) +d "sw s1, 0x84(sp)" 26c3 0x0 (storew 0 (+ (var sp) (bv 32 0x84)) (var s1)) +d "sw ra, 0x8c(sp)" 06c7 0x0 (storew 0 (+ (var sp) (bv 32 0x8c)) (var ra)) +d "sw s0, 0x88(sp)" 22c5 0x0 (storew 0 (+ (var sp) (bv 32 0x88)) (var s0)) +d "sw s2, 0x80(sp)" 4ac1 0x0 (storew 0 (+ (var sp) (bv 32 0x80)) (var s2)) +d "sw s3, 0x7c(sp)" cede 0x0 (storew 0 (+ (var sp) (bv 32 0x7c)) (var s3)) +d "sw s4, 0x78(sp)" d2dc 0x0 (storew 0 (+ (var sp) (bv 32 0x78)) (var s4)) +d "sw s5, 0x74(sp)" d6da 0x0 (storew 0 (+ (var sp) (bv 32 0x74)) (var s5)) +d "sw s6, 0x70(sp)" dad8 0x0 (storew 0 (+ (var sp) (bv 32 0x70)) (var s6)) +d "sw s7, 0x6c(sp)" ded6 0x0 (storew 0 (+ (var sp) (bv 32 0x6c)) (var s7)) +d "sw s8, 0x68(sp)" e2d4 0x0 (storew 0 (+ (var sp) (bv 32 0x68)) (var s8)) +d "sw s9, 0x64(sp)" e6d2 0x0 (storew 0 (+ (var sp) (bv 32 0x64)) (var s9)) +d "sw s10, 0x60(sp)" ead0 0x0 (storew 0 (+ (var sp) (bv 32 0x60)) (var s10)) +d "sw s11, 0x5c(sp)" eece 0x0 (storew 0 (+ (var sp) (bv 32 0x5c)) (var s11)) +d "sw zero, 0x28(sp)" 02d4 0x0 (storew 0 (+ (var sp) (bv 32 0x28)) (bv 32 0x0)) +d "sw zero, 0x20(sp)" 02d0 0x0 (storew 0 (+ (var sp) (bv 32 0x20)) (bv 32 0x0)) +d "sw zero, 0x38(sp)" 02dc 0x0 (storew 0 (+ (var sp) (bv 32 0x38)) (bv 32 0x0)) +d "sw zero, 0x30(sp)" 02d8 0x0 (storew 0 (+ (var sp) (bv 32 0x30)) (bv 32 0x0)) +d "sw a5, 0x34(sp)" 3eda 0x0 (storew 0 (+ (var sp) (bv 32 0x34)) (var a5)) +d "sw zero, 0x18(sp)" 02cc 0x0 (storew 0 (+ (var sp) (bv 32 0x18)) (bv 32 0x0)) +d "lui s1, 0x40" b7040400 0x38 (set s1 (<< (bv 32 0x40) (bv 32 0xc) false)) +d "lui a5, 0x10013" b7370110 0x0 (set a5 (<< (bv 32 0x10013) (bv 32 0xc) false)) +d "lw a5, 4(a5)" dc43 0x40 (set a5 (loadw 0 32 (+ (var a5) (bv 32 0x4)))) +d "blez a5, 0x64" 6351f002 0x42 (branch (|| (! (sle (bv 32 0x0) (var a5))) (== (bv 32 0x0) (var a5))) (jmp (bv 32 0x64)) (jmp (bv 32 0x46))) +d "lw ra, 0x8c(sp)" ba40 0x40 (set ra (loadw 0 32 (+ (var sp) (bv 32 0x8c)))) +d "lw s0, 0x88(sp)" 2a44 0x40 (set s0 (loadw 0 32 (+ (var sp) (bv 32 0x88)))) +d "lw s1, 0x84(sp)" 9a44 0x40 (set s1 (loadw 0 32 (+ (var sp) (bv 32 0x84)))) +d "lw s2, 0x80(sp)" 0a49 0x40 (set s2 (loadw 0 32 (+ (var sp) (bv 32 0x80)))) +d "lw s3, 0x7c(sp)" f659 0x40 (set s3 (loadw 0 32 (+ (var sp) (bv 32 0x7c)))) +d "lw s4, 0x78(sp)" 665a 0x44 (set s4 (loadw 0 32 (+ (var sp) (bv 32 0x78)))) +d "lw s5, 0x74(sp)" d65a 0x48 (set s5 (loadw 0 32 (+ (var sp) (bv 32 0x74)))) +d "lw s6, 0x70(sp)" 465b 0x40 (set s6 (loadw 0 32 (+ (var sp) (bv 32 0x70)))) +d "lw s7, 0x6c(sp)" b65b 0x40 (set s7 (loadw 0 32 (+ (var sp) (bv 32 0x6c)))) +d "lw s8, 0x68(sp)" 265c 0x40 (set s8 (loadw 0 32 (+ (var sp) (bv 32 0x68)))) +d "lw s9, 0x64(sp)" 965c 0x40 (set s9 (loadw 0 32 (+ (var sp) (bv 32 0x64)))) +d "lw s10, 0x60(sp)" 065d 0x40 (set s10 (loadw 0 32 (+ (var sp) (bv 32 0x60)))) +d "lw s11, 0x5c(sp)" f64d 0x40 (set s11 (loadw 0 32 (+ (var sp) (bv 32 0x5c)))) d "addi sp, sp, 0x90" 4961 0x40 -d "ret" 8280 0x40 -d "lw a5, 0x18(sp)" e247 0x40 +d "ret" 8280 0x40 NONE +d "lw a5, 0x18(sp)" e247 0x40 (set a5 (loadw 0 32 (+ (var sp) (bv 32 0x18)))) d "beqz a5, 0x2d8" 63890726 0x66 -d "lw s0, 0x1c(sp)" 7244 0x40 -d "lw a0, 0x24(sp)" 1255 0x40 -d "lw a6, 0x28(sp)" 2258 0x40 -d "lw t3, 0x38(sp)" 625e 0x40 +d "lw s0, 0x1c(sp)" 7244 0x40 (set s0 (loadw 0 32 (+ (var sp) (bv 32 0x1c)))) +d "lw a0, 0x24(sp)" 1255 0x40 (set a0 (loadw 0 32 (+ (var sp) (bv 32 0x24)))) +d "lw a6, 0x28(sp)" 2258 0x40 (set a6 (loadw 0 32 (+ (var sp) (bv 32 0x28)))) +d "lw t3, 0x38(sp)" 625e 0x40 (set t3 (loadw 0 32 (+ (var sp) (bv 32 0x38)))) d "srai a5, s0, 0x1f" 9357f441 0x40 -d "lw a2, 0x20(sp)" 0256 0x40 -d "andi a5, a5, 0xf" bd8b 0x40 +d "lw a2, 0x20(sp)" 0256 0x40 (set a2 (loadw 0 32 (+ (var sp) (bv 32 0x20)))) +d "andi a5, a5, 0xf" bd8b 0x40 (set a5 (& (var a5) (bv 32 0xf))) d "srai a4, a0, 0x1f" 1357f541 0x40 -d "lw a7, 0x30(sp)" c258 0x40 -d "add a3, a5, a6" b3860701 0x80 -d "sub s2, t3, a6" 33090e41 0x80 -d "andi a4, a4, 0x3f" 1377f703 0x80 -d "lw a6, 0x34(sp)" 5258 0x80 -d "add a1, a4, a2" b305c700 0x80 -d "sltu a4, a1, a4" 33b7e500 0x80 -d "sub a2, a7, a2" 3386c840 0x80 -d "sltu s7, a3, a5" b3bbf600 0x80 -d "sltu a7, a7, a2" b3b8c800 0x80 -d "add a5, a4, a0" b307a700 0x80 -d "mv a4, a2" 3287 0x80 -d "sub a2, a6, a0" 3306a840 0x80 -d "sltu a6, t3, s2" 33382e01 0x80 -d "lw t3, 0x3c(sp)" 725e 0x80 -d "mv t1, a0" 2a83 0x80 -d "srli a1, a1, 6" 9981 0x80 -d "slli a0, a5, 0x1a" 1395a701 0x80 -d "sw a4, 0x40(sp)" bac0 0x80 -d "sub a4, a2, a7" 33071641 0x80 -d "add s7, s7, s0" a29b 0xc0 -d "sw a4, 0x44(sp)" bac2 0xc0 -d "srai a5, a5, 6" 9987 0xc0 -d "or a4, a0, a1" 3367b500 0xc0 -d "slli s8, s7, 0x1c" 139ccb01 0xc0 -d "sub s0, t3, s0" 33048e40 0xc0 -d "srli a3, a3, 4" 9182 0xc0 -d "sw a4, 0x10(sp)" 3ac8 0xc0 -d "sw a5, 0x14(sp)" 3eca 0xc0 -d "lui a4, 1" 0567 0xc0 -d "sub s0, s0, a6" 33040441 0xc0 -d "or s8, s8, a3" 336cdc00 0xc0 -d "srai s7, s7, 4" 93db4b40 0xc0 -d "blt t1, a4, 0x2d4" 6347e31e 0xe6 -d "lw a5, 0x1c(sp)" f247 0xc0 -d "lui a4, 1" 0567 0xc0 -d "blt a5, a4, 0x2d4" 63c3e71e 0xee -d "srli a5, s8, 0x1d" 9357dc01 0xc0 -d "slli a4, s7, 3" 13973b00 0xc0 -d "or a5, a5, a4" d98f 0xc0 -d "sw a5, 0x4c(sp)" bec6 0xc0 -d "slli a5, s8, 3" 93173c00 0xc0 -d "addi a5, sp, 8" 3c00 0x100 -d "li s11, 0xff" 930df00f 0x100 -d "sw a5, 0x48(sp)" bec4 0x100 -d "sw s2, 0xc(sp)" 4ac6 0x100 -d "li a5, 4" 9147 0x100 -d "li s2, 0" 0149 0x100 -d "mv s3, s11" ee89 0x100 -d "sw a5, 0x2c(sp)" 3ed6 0x100 -d "li s6, 0x10" 414b 0x100 -d "li s9, 8" a14c 0x100 -d "mv s11, s2" ca8d 0x100 -d "lw s10, 0x40(sp)" 064d 0x100 -d "lw s5, 0x44(sp)" 964a 0x100 -d "li s2, 0x80" 13090008 0x100 -d "mv s4, s3" 4e8a 0x100 -d "mv s3, s2" ca89 0x100 -d "lw t2, 0xc(sp)" b243 0x100 -d "mv t6, s0" a28f 0x100 -d "li ra, 0" 8140 0x100 -d "li s2, 0" 0149 0x100 -d "li a1, 0" 8145 0x100 -d "li a4, 0" 0147 0x100 -d "li t3, 0" 014e 0x100 -d "li a6, 0" 0148 0x100 -d "li a5, 0" 8147 0x100 -d "li a3, 0" 8146 0x100 -d "li t1, 0" 0143 0x100 -d "li a2, 0" 0146 0x100 -d "li a0, 0" 0145 0x100 -d "j 0x176" 25a8 0x13e +d "lw a7, 0x30(sp)" c258 0x40 (set a7 (loadw 0 32 (+ (var sp) (bv 32 0x30)))) +d "add a3, a5, a6" b3860701 0x80 (set a3 (+ (var a5) (var a6))) +d "sub s2, t3, a6" 33090e41 0x80 (set s2 (- (var t3) (var a6))) +d "andi a4, a4, 0x3f" 1377f703 0x80 (set a4 (& (var a4) (bv 32 0x3f))) +d "lw a6, 0x34(sp)" 5258 0x80 (set a6 (loadw 0 32 (+ (var sp) (bv 32 0x34)))) +d "add a1, a4, a2" b305c700 0x80 (set a1 (+ (var a4) (var a2))) +d "sltu a4, a1, a4" 33b7e500 0x80 (set a4 (ite (&& (ule (var a1) (var a4)) (! (== (var a1) (var a4)))) (bv 32 0x1) (bv 32 0x0))) +d "sub a2, a7, a2" 3386c840 0x80 (set a2 (- (var a7) (var a2))) +d "sltu s7, a3, a5" b3bbf600 0x80 (set s7 (ite (&& (ule (var a3) (var a5)) (! (== (var a3) (var a5)))) (bv 32 0x1) (bv 32 0x0))) +d "sltu a7, a7, a2" b3b8c800 0x80 (set a7 (ite (&& (ule (var a7) (var a2)) (! (== (var a7) (var a2)))) (bv 32 0x1) (bv 32 0x0))) +d "add a5, a4, a0" b307a700 0x80 (set a5 (+ (var a4) (var a0))) +d "mv a4, a2" 3287 0x80 (set a4 (var a2)) +d "sub a2, a6, a0" 3306a840 0x80 (set a2 (- (var a6) (var a0))) +d "sltu a6, t3, s2" 33382e01 0x80 (set a6 (ite (&& (ule (var t3) (var s2)) (! (== (var t3) (var s2)))) (bv 32 0x1) (bv 32 0x0))) +d "lw t3, 0x3c(sp)" 725e 0x80 (set t3 (loadw 0 32 (+ (var sp) (bv 32 0x3c)))) +d "mv t1, a0" 2a83 0x80 (set t1 (var a0)) +d "srli a1, a1, 6" 9981 0x80 (set a1 (>> (var a1) (bv 32 0x6) false)) +d "slli a0, a5, 0x1a" 1395a701 0x80 (set a0 (<< (var a5) (bv 32 0x1a) false)) +d "sw a4, 0x40(sp)" bac0 0x80 (storew 0 (+ (var sp) (bv 32 0x40)) (var a4)) +d "sub a4, a2, a7" 33071641 0x80 (set a4 (- (var a2) (var a7))) +d "add s7, s7, s0" a29b 0xc0 NONE +d "sw a4, 0x44(sp)" bac2 0xc0 (storew 0 (+ (var sp) (bv 32 0x44)) (var a4)) +d "srai a5, a5, 6" 9987 0xc0 (set a5 (>> (var a5) (bv 32 0x6) (msb (var a5)))) +d "or a4, a0, a1" 3367b500 0xc0 (set a4 (| (var a0) (var a1))) +d "slli s8, s7, 0x1c" 139ccb01 0xc0 (set s8 (<< (var s7) (bv 32 0x1c) false)) +d "sub s0, t3, s0" 33048e40 0xc0 (set s0 (- (var t3) (var s0))) +d "srli a3, a3, 4" 9182 0xc0 (set a3 (>> (var a3) (bv 32 0x4) false)) +d "sw a4, 0x10(sp)" 3ac8 0xc0 (storew 0 (+ (var sp) (bv 32 0x10)) (var a4)) +d "sw a5, 0x14(sp)" 3eca 0xc0 (storew 0 (+ (var sp) (bv 32 0x14)) (var a5)) +d "lui a4, 1" 0567 0xc0 (set a4 (<< (bv 32 0x1) (bv 32 0xc) false)) +d "sub s0, s0, a6" 33040441 0xc0 (set s0 (- (var s0) (var a6))) +d "or s8, s8, a3" 336cdc00 0xc0 (set s8 (| (var s8) (var a3))) +d "srai s7, s7, 4" 93db4b40 0xc0 (set s7 (>> (var s7) (bv 32 0x4) (msb (var s7)))) +d "blt t1, a4, 0x2d4" 6347e31e 0xe6 (branch (&& (sle (var t1) (var a4)) (! (== (var t1) (var a4)))) (jmp (bv 32 0x2d4)) (jmp (bv 32 0xea))) +d "lw a5, 0x1c(sp)" f247 0xc0 (set a5 (loadw 0 32 (+ (var sp) (bv 32 0x1c)))) +d "lui a4, 1" 0567 0xc0 (set a4 (<< (bv 32 0x1) (bv 32 0xc) false)) +d "blt a5, a4, 0x2d4" 63c3e71e 0xee (branch (&& (sle (var a5) (var a4)) (! (== (var a5) (var a4)))) (jmp (bv 32 0x2d4)) (jmp (bv 32 0xf2))) +d "srli a5, s8, 0x1d" 9357dc01 0xc0 (set a5 (>> (var s8) (bv 32 0x1d) false)) +d "slli a4, s7, 3" 13973b00 0xc0 (set a4 (<< (var s7) (bv 32 0x3) false)) +d "or a5, a5, a4" d98f 0xc0 NONE +d "sw a5, 0x4c(sp)" bec6 0xc0 (storew 0 (+ (var sp) (bv 32 0x4c)) (var a5)) +d "slli a5, s8, 3" 93173c00 0xc0 (set a5 (<< (var s8) (bv 32 0x3) false)) +d "addi a5, sp, 8" 3c00 0x100 (set a5 (+ (var sp) (bv 32 0x8))) +d "li s11, 0xff" 930df00f 0x100 (set s11 (+ (bv 32 0x0) (bv 32 0xff))) +d "sw a5, 0x48(sp)" bec4 0x100 (storew 0 (+ (var sp) (bv 32 0x48)) (var a5)) +d "sw s2, 0xc(sp)" 4ac6 0x100 (storew 0 (+ (var sp) (bv 32 0xc)) (var s2)) +d "li a5, 4" 9147 0x100 (set a5 (bv 32 0x4)) +d "li s2, 0" 0149 0x100 (set s2 (bv 32 0x0)) +d "mv s3, s11" ee89 0x100 (set s3 (var s11)) +d "sw a5, 0x2c(sp)" 3ed6 0x100 (storew 0 (+ (var sp) (bv 32 0x2c)) (var a5)) +d "li s6, 0x10" 414b 0x100 (set s6 (bv 32 0x10)) +d "li s9, 8" a14c 0x100 (set s9 (bv 32 0x8)) +d "mv s11, s2" ca8d 0x100 (set s11 (var s2)) +d "lw s10, 0x40(sp)" 064d 0x100 (set s10 (loadw 0 32 (+ (var sp) (bv 32 0x40)))) +d "lw s5, 0x44(sp)" 964a 0x100 (set s5 (loadw 0 32 (+ (var sp) (bv 32 0x44)))) +d "li s2, 0x80" 13090008 0x100 (set s2 (+ (bv 32 0x0) (bv 32 0x80))) +d "mv s4, s3" 4e8a 0x100 (set s4 (var s3)) +d "mv s3, s2" ca89 0x100 (set s3 (var s2)) +d "lw t2, 0xc(sp)" b243 0x100 (set t2 (loadw 0 32 (+ (var sp) (bv 32 0xc)))) +d "mv t6, s0" a28f 0x100 (set t6 (var s0)) +d "li ra, 0" 8140 0x100 (set ra (bv 32 0x0)) +d "li s2, 0" 0149 0x100 (set s2 (bv 32 0x0)) +d "li a1, 0" 8145 0x100 (set a1 (bv 32 0x0)) +d "li a4, 0" 0147 0x100 (set a4 (bv 32 0x0)) +d "li t3, 0" 014e 0x100 (set t3 (bv 32 0x0)) +d "li a6, 0" 0148 0x100 (set a6 (bv 32 0x0)) +d "li a5, 0" 8147 0x100 (set a5 (bv 32 0x0)) +d "li a3, 0" 8146 0x100 (set a3 (bv 32 0x0)) +d "li t1, 0" 0143 0x100 (set t1 (bv 32 0x0)) +d "li a2, 0" 0146 0x100 (set a2 (bv 32 0x0)) +d "li a0, 0" 0145 0x100 (set a0 (bv 32 0x0)) +d "j 0x176" 25a8 0x13e (jmp (bv 32 0x176)) d "mul a4, a0, a2" 3307c502 0x140 d "mulhu t1, a2, a2" 3333c602 0x140 -d "slli a4, a4, 1" 0607 0x140 +d "slli a4, a4, 1" 0607 0x140 (set a4 (<< (var a4) (bv 32 0x1) false)) d "mul a7, a5, a6" b3880703 0x140 d "add t1, t1, a4" 3a93 0x140 d "mul a3, a2, a2" b306c602 0x140 -d "slli a7, a7, 1" 8608 0x140 +d "slli a7, a7, 1" 8608 0x140 (set a7 (<< (var a7) (bv 32 0x1) false)) d "mulhu t3, a6, a6" 333e0803 0x140 d "mul a4, a6, a6" 33070803 0x140 d "add t3, t3, a7" 469e 0x140 @@ -140,8 +147,8 @@ d "add t5, t1, t3" 330fc301 0x140 d "add t4, a3, a4" b38ee600 0x140 d "sltu a7, t4, a3" b3b8de00 0x140 d "add a7, a7, t5" fa98 0x140 -d "blt s1, a7, 0x2c6" 63cc1415 0x16e -d "beq a7, s1, 0x2c2" 63889814 0x172 +d "blt s1, a7, 0x2c6" 63cc1415 0x16e (branch (&& (sle (var s1) (var a7)) (! (== (var s1) (var a7)))) (jmp (bv 32 0x2c6)) (jmp (bv 32 0x172))) +d "beq a7, s1, 0x2c2" 63889814 0x172 (branch (== (var a7) (var s1)) (jmp (bv 32 0x2c2)) (jmp (bv 32 0x176))) d "sub a4, a3, a4" 3387e640 0x140 d "sub t3, t1, t3" 330ec341 0x140 d "sltu a3, ra, zero" b3b60000 0x140 @@ -151,35 +158,44 @@ d "sltu a4, a7, a4" 33b7e800 0x180 d "add a3, a3, s5" d696 0x180 d "add a3, a3, a4" ba96 0x180 d "mul a5, a5, a2" b387c702 0x180 -d "slli t1, a3, 8" 13938600 0x180 -d "addi a1, a1, 1" 8505 0x180 +d "slli t1, a3, 8" 13938600 0x180 (set t1 (<< (var a3) (bv 32 0x8) false)) +d "addi a1, a1, 1" 8505 0x180 (set a1 (+ (var a1) (bv 32 0x1))) d "mul a4, a0, a6" 33070503 0x180 -d "srai a0, a3, 0x18" 13d58641 0x180 +d "srai a0, a3, 0x18" 13d58641 0x180 (set a0 (>> (var a3) (bv 32 0x18) (msb (var a3)))) d "mulhu a3, a6, a2" b336c802 0x180 d "add a4, a4, a5" 3e97 0x180 d "mul a6, a6, a2" 3308c802 0x180 d "add a4, a4, a3" 3697 0x180 -d "srli a2, a7, 0x18" 13d68801 0x180 -d "slli a4, a4, 1" 0607 0x180 +d "srli a2, a7, 0x18" 13d68801 0x180 (set a2 (>> (var a7) (bv 32 0x18) false)) +d "slli a4, a4, 1" 0607 0x180 (set a4 (<< (var a4) (bv 32 0x1) false)) d "or a2, t1, a2" 3366c300 0x180 -d "slli a7, a6, 1" 93181800 0x180 -d "srli a3, a6, 0x1f" 9356f801 0x180 +d "slli a7, a6, 1" 93181800 0x180 (set a7 (<< (var a6) (bv 32 0x1) false)) +d "srli a3, a6, 0x1f" 9356f801 0x180 (set a3 (>> (var a6) (bv 32 0x1f) false)) d "add a5, a7, t2" b3877800 0x1c0 d "or a4, a4, a3" 558f 0x1c0 -d "srli a6, a5, 0x18" 13d88701 0x1c0 +d "srli a6, a5, 0x18" 13d88701 0x1c0 (set a6 (>> (var a5) (bv 32 0x18) false)) d "add a4, a4, t6" 7e97 0x1c0 d "sltu a5, a5, a7" b3b71701 0x1c0 d "add a4, a4, a5" 3e97 0x1c0 -d "slli a5, a4, 8" 93178700 0x1c0 +d "slli a5, a4, 8" 93178700 0x1c0 (set a5 (<< (var a4) (bv 32 0x8) false)) d "or a6, a5, a6" 33e80701 0x1c0 d "srai a5, a4, 0x18" 93578741 0x1c0 -d "bne a1, s6, 0x140" e39065f7 0x1e0 +d "bne a1, s6, 0x140" e39065f7 0x1e0 (branch (! (== (var a1) (var s6))) (jmp (bv 32 0x140)) (jmp (bv 32 0x1e4))) d "li a5, 0" 8147 0x1c0 d "add a4, t2, s8" 33878301 0x1c0 d "sltu a3, a4, t2" b3367700 0x1c0 d "or s2, a5, s2" 33e92701 0x1c0 d "add t6, t6, s7" de9f 0x1c0 -d "addi ra, ra, 1" 8500 0x1c0 -d "andi s2, s2, 0xff" 1379f90f 0x1c0 +d "addi ra, ra, 1" 8500 0x1c0 (set ra (+ (var ra) (bv 32 0x1))) +d "andi s2, s2, 0xff" 1379f90f 0x1c0 (set s2 (& (var s2) (bv 32 0xff))) d "mv t2, a4" ba83 0x1c0 d "add t6, t6, a3" b69f 0x1c0 +d "ori a5, a5, 0x89" 93e79708 0x0 (set a5 (| (var a5) (bv 32 0x89))) +d "xori a5, a5, 0x431" 93c71743 0x0 (set a5 (^ (var a5) (bv 32 0x431))) +d "jalr ra" e7800000 0x30 (seq (set ra (bv 32 0x34)) (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "slti zero, ra, 0xc" 13a0c000 0x0 nop +d "sltiu zero, ra, 0xc" 13b0c000 0x0 nop +d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 32 0xc)) (! (== (var ra) (bv 32 0xc)))) (bv 32 0x1) (bv 32 0x0))) +d "sltiu t1, sp, 0x14" 13334101 0x0 (set t1 (ite (&& (ule (var sp) (bv 32 0x14)) (! (== (var sp) (bv 32 0x14)))) (bv 32 0x1) (bv 32 0x0))) +d "jal t0, 0x14" ef024001 0x0 (seq (set t0 (bv 32 0x4)) (jmp (bv 32 0x14))) +d "jal t0, 0x4a" ef024001 0x36 (seq (set t0 (bv 32 0x3a)) (jmp (bv 32 0x4a))) From 8eb26ca4f23dd8046dbd54a85adb9791191028e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Thu, 14 May 2026 22:02:17 +0300 Subject: [PATCH 02/10] refactor implementation to more declarative style --- librz/arch/isa/riscv/riscv_il.c | 318 +++++------------- librz/arch/isa/riscv/riscv_il.h | 4 +- librz/arch/isa/riscv/riscv_il_base.h | 199 +++++++++++ librz/arch/isa/riscv/riscv_il_compressed.h | 71 ++++ librz/arch/isa/riscv/riscv_il_integer.h | 99 ++++++ .../isa/riscv/riscv_il_integer_reg_names.h | 53 +++ librz/arch/isa/riscv/riscv_il_m.h | 21 ++ test/db/asm/riscv_32 | 96 +++--- 8 files changed, 577 insertions(+), 284 deletions(-) create mode 100644 librz/arch/isa/riscv/riscv_il_base.h create mode 100644 librz/arch/isa/riscv/riscv_il_compressed.h create mode 100644 librz/arch/isa/riscv/riscv_il_integer.h create mode 100644 librz/arch/isa/riscv/riscv_il_integer_reg_names.h create mode 100644 librz/arch/isa/riscv/riscv_il_m.h diff --git a/librz/arch/isa/riscv/riscv_il.c b/librz/arch/isa/riscv/riscv_il.c index 37a2b1601eb..61f99b2fb14 100644 --- a/librz/arch/isa/riscv/riscv_il.c +++ b/librz/arch/isa/riscv/riscv_il.c @@ -1,217 +1,20 @@ // SPDX-FileCopyrightText: 2026 Mostafa Mahmoud // SPDX-License-Identifier: BSD-3-Clause -#include "analysis_private.h" -#include "riscv.h" -#include "rz_il/rz_il_opcodes.h" -#include "rz_types.h" -#include "rz_util/rz_assert.h" -#include -#include "riscv_il.h" - -#include -static const char *riscv_register_names[] = { - [RISCV_REG_X1] = "ra", - [RISCV_REG_X2] = "sp", - [RISCV_REG_X3] = "gp", - [RISCV_REG_X4] = "tp", - [RISCV_REG_X5] = "t0", - [RISCV_REG_X6] = "t1", - [RISCV_REG_X7] = "t2", - [RISCV_REG_X8] = "s0", - [RISCV_REG_X9] = "s1", - [RISCV_REG_X10] = "a0", - [RISCV_REG_X11] = "a1", - [RISCV_REG_X12] = "a2", - [RISCV_REG_X13] = "a3", - [RISCV_REG_X14] = "a4", - [RISCV_REG_X15] = "a5", - [RISCV_REG_X16] = "a6", - [RISCV_REG_X17] = "a7", - [RISCV_REG_X18] = "s2", - [RISCV_REG_X19] = "s3", - [RISCV_REG_X20] = "s4", - [RISCV_REG_X21] = "s5", - [RISCV_REG_X22] = "s6", - [RISCV_REG_X23] = "s7", - [RISCV_REG_X24] = "s8", - [RISCV_REG_X25] = "s9", - [RISCV_REG_X26] = "s10", - [RISCV_REG_X27] = "s11", - [RISCV_REG_X28] = "t3", - [RISCV_REG_X29] = "t4", - [RISCV_REG_X30] = "t5", - [RISCV_REG_X31] = "t6", -}; - -#define RISCV_GET_REG(reg) (((reg) != RISCV_REG_X0) ? (VARG(riscv_register_names[reg])) : UN(analysis->bits, 0)) -#define RISCV_SET_REG(reg, r) (((reg) != RISCV_REG_X0) ? (SETG(riscv_register_names[reg], r)) : ((rz_il_op_pure_free(r), NOP()))) - -#define DEFINE_LIFTER(name, decoder, result) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ - RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ - decoder(analysis, insn); \ - return RISCV_SET_REG(rd, result); \ - } - -// by default, a RISC-V jump both sets a destination and sets the PC (i.e., jumps) -#define DEFINE_LIFTER_FOR_JUMP(name, decoder, result, jmp_effect) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ - RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ - decoder(analysis, insn); \ - return SEQ2( \ - RISCV_SET_REG(rd, result), \ - jmp_effect); \ - } - -#define DEFINE_LIFTER_WITH_EFFECT(name, decoder, effect) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ - RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { \ - decoder(analysis, insn); \ - return effect; \ - } - -// oneway jumps are those that don't have a destination register -#define DEFINE_LIFTER_FOR_ONEWAY_JUMP DEFINE_LIFTER_WITH_EFFECT - -#define TWICE_FOR(name1, name2, lifter, ...) \ - lifter(name1, __VA_ARGS__) \ - lifter(name2, __VA_ARGS__) - -#define THRICE_FOR(name1, name2, name3, lifter, ...) \ - TWICE_FOR(name1, name2, lifter, __VA_ARGS__) \ - lifter(name3, __VA_ARGS__) - -#define FOR_4(name1, name2, name3, name4, lifter, ...) \ - TWICE_FOR(name1, name2, lifter, __VA_ARGS__) \ - TWICE_FOR(name3, name4, lifter, __VA_ARGS__) - -#define DECODE_RD_RS_IMM(analysis, insn) \ - uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); - -#define DECODE_RD_RS_RS(analysis, insn) \ - uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[2].reg); - -#define DECODE_RS_IMM(analysis, insn) \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); - -#define DECODE_RS_RS_IMM(analysis, insn) \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); - -#define DECODE_RD_RS(analysis, insn) \ - uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); - -#define DECODE_IMM(analysis, insn) \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[0].imm); - -#define DECODE_RD_IMM(analysis, insn) \ - uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); - -#define DECODE_RS_RS_IMM_MEM(analysis, insn) \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); - -#define DECODE_RD_RS_IMM_MEM(analysis, insn) \ - uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ - RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); - -#define USE_LIFTER(name, uppername) [RISCV_INS_##uppername] = rz_riscv_lift_##name - -FOR_4(addi, c_addi, c_addi16sp, c_addi4spn, - DEFINE_LIFTER, DECODE_RD_RS_IMM, ADD(rs, imm)) -TWICE_FOR(slli, c_slli, - DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTL0(rs, imm)) -TWICE_FOR(andi, c_andi, - DEFINE_LIFTER, DECODE_RD_RS_IMM, LOGAND(rs, imm)) -DEFINE_LIFTER(ori, DECODE_RD_RS_IMM, LOGOR(rs, imm)) -DEFINE_LIFTER(xori, DECODE_RD_RS_IMM, LOGXOR(rs, imm)) -DEFINE_LIFTER(slti, DECODE_RD_RS_IMM, BOOL_TO_BV(SLT(rs, imm), analysis->bits)) -DEFINE_LIFTER(sltiu, DECODE_RD_RS_IMM, BOOL_TO_BV(ULT(rs, imm), analysis->bits)) -TWICE_FOR(srli, c_srli, - DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTR0(rs, imm)) -TWICE_FOR(srai, c_srai, - DEFINE_LIFTER, DECODE_RD_RS_IMM, SHIFTRA(rs, imm)) - -DEFINE_LIFTER(add, DECODE_RD_RS_RS, ADD(rs1, rs2)) -DEFINE_LIFTER(sub, DECODE_RD_RS_RS, SUB(rs1, rs2)) -DEFINE_LIFTER(and, DECODE_RD_RS_RS, LOGAND(rs1, rs2)) -DEFINE_LIFTER(or, DECODE_RD_RS_RS, LOGOR(rs1, rs2)) -DEFINE_LIFTER(xor, DECODE_RD_RS_RS, LOGXOR(rs1, rs2)) -DEFINE_LIFTER(slt, DECODE_RD_RS_RS, BOOL_TO_BV(SLT(rs1, rs2), analysis->bits)) -DEFINE_LIFTER(sltu, DECODE_RD_RS_RS, BOOL_TO_BV(ULT(rs1, rs2), analysis->bits)) -DEFINE_LIFTER(sll, DECODE_RD_RS_RS, SHIFTL0(rs1, rs2)) -DEFINE_LIFTER(srl, DECODE_RD_RS_RS, SHIFTR0(rs1, rs2)) -DEFINE_LIFTER(sra, DECODE_RD_RS_RS, SHIFTRA(rs1, rs2)) -#define DEFINE_LIFTER_FOR_BRANCH(name, decoder, condition) \ - DEFINE_LIFTER_FOR_ONEWAY_JUMP(name, decoder, BRANCH(condition, JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) - -DEFINE_LIFTER_FOR_BRANCH(beq, DECODE_RS_RS_IMM, EQ(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bne, DECODE_RS_RS_IMM, NE(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(blt, DECODE_RS_RS_IMM, SLT(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bge, DECODE_RS_RS_IMM, SGE(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bltu, DECODE_RS_RS_IMM, ULT(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bgeu, DECODE_RS_RS_IMM, UGE(rs1, rs2)) - -DEFINE_LIFTER_FOR_BRANCH(c_beqz, DECODE_RS_IMM, EQ(rs, UN(analysis->bits, 0))) -DEFINE_LIFTER_FOR_BRANCH(c_bnez, DECODE_RS_IMM, NE(rs, UN(analysis->bits, 0))) - -DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) - -DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_IMM, JMP(imm)) - -DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, - /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), - /*GOTO ADDR*/ JMP(imm)) - -TWICE_FOR(jalr, c_jr, - DEFINE_LIFTER_FOR_JUMP, DECODE_RD_RS_IMM, - /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), - /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) - -TWICE_FOR(lui, c_lui, - DEFINE_LIFTER, DECODE_RD_IMM, SHIFTL0(imm, UN(analysis->bits, 12))) -DEFINE_LIFTER(c_li, DECODE_RD_IMM, DUP(imm)) -DEFINE_LIFTER(auipc, DECODE_RD_IMM, ADD(UN(analysis->bits, current_addr), SHIFTL0(imm, UN(analysis->bits, 12)))) - -DEFINE_LIFTER_WITH_EFFECT(sb, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(8, IL_FALSE, rs1))) -DEFINE_LIFTER_WITH_EFFECT(sh, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(16, IL_FALSE, rs1))) - -THRICE_FOR(sw, c_sw, c_swsp, - DEFINE_LIFTER_WITH_EFFECT, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), analysis->bits == 32 ? rs1 : CAST(64, IL_FALSE, rs1))) - -TWICE_FOR(sd, c_sd, - DEFINE_LIFTER_WITH_EFFECT, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), rs1)) - -THRICE_FOR(lw, c_lwsp, c_lw, - DEFINE_LIFTER, DECODE_RD_RS_IMM_MEM, analysis->bits == 32 ? LOADW(32, ADD(rs, imm)) : SIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) -DEFINE_LIFTER(lb, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) -DEFINE_LIFTER(lh, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) -DEFINE_LIFTER(lbu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) -DEFINE_LIFTER(lhu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) - -TWICE_FOR(ld, c_ld, - DEFINE_LIFTER, DECODE_RD_RS_IMM_MEM, LOADW(64, ADD(rs, imm))) +#include "riscv_il.h" +#include "riscv_il_integer.h" +#include "riscv_il_m.h" +#include "riscv_il_compressed.h" -#include +static void label_ecall(RzILVM *vm, RzILOpEffect *op) { + // stub: ecall is handled at the analysis layer +} static const RiscvInstructionLifter riscv_lifters[] = { + /* ---------------------------------- Integer ---------------------------------*/ + // arithmetic, immediate USE_LIFTER(addi, ADDI), - USE_LIFTER(c_addi, C_ADDI), - USE_LIFTER(c_addi16sp, C_ADDI16SP), - USE_LIFTER(c_addi4spn, C_ADDI4SPN), USE_LIFTER(andi, ANDI), - USE_LIFTER(c_andi, C_ANDI), USE_LIFTER(ori, ORI), USE_LIFTER(xori, XORI), USE_LIFTER(slti, SLTI), @@ -219,56 +22,99 @@ static const RiscvInstructionLifter riscv_lifters[] = { USE_LIFTER(slli, SLLI), USE_LIFTER(srli, SRLI), USE_LIFTER(srai, SRAI), - USE_LIFTER(c_slli, C_SLLI), - USE_LIFTER(c_srli, C_SRLI), - USE_LIFTER(c_srai, C_SRAI), - USE_LIFTER(jalr, JALR), - USE_LIFTER(c_jr, C_JR), + // immediate constants + USE_LIFTER(lui, LUI), + USE_LIFTER(auipc, AUIPC), + // arithmetic + USE_LIFTER(add, ADD), + USE_LIFTER(sub, SUB), + USE_LIFTER(and, AND), + USE_LIFTER(or, OR), + USE_LIFTER(xor, XOR), + USE_LIFTER(slt, SLT), + USE_LIFTER(sltu, SLTU), + USE_LIFTER(sll, SLL), + USE_LIFTER(srl, SRL), + USE_LIFTER(sra, SRA), + // arithmetic, 32-bit operations in 64-bit mode + USE_LIFTER(addw, ADDW), + USE_LIFTER(subw, SUBW), + USE_LIFTER(sllw, SLLW), + USE_LIFTER(srlw, SRLW), + USE_LIFTER(sraw, SRAW), + USE_LIFTER(addiw, ADDIW), + USE_LIFTER(slliw, SLLIW), + USE_LIFTER(srliw, SRLIW), + USE_LIFTER(sraiw, SRAIW), + // memory USE_LIFTER(lb, LB), USE_LIFTER(lh, LH), USE_LIFTER(lw, LW), USE_LIFTER(lbu, LBU), USE_LIFTER(lhu, LHU), - USE_LIFTER(c_lwsp, C_LWSP), - USE_LIFTER(c_lw, C_LW), USE_LIFTER(ld, LD), - USE_LIFTER(c_ld, C_LD), - USE_LIFTER(lui, LUI), - USE_LIFTER(c_lui, C_LUI), - USE_LIFTER(c_li, C_LI), - USE_LIFTER(auipc, AUIPC), + USE_LIFTER(sb, SB), + USE_LIFTER(sh, SH), + USE_LIFTER(sw, SW), + USE_LIFTER(sd, SD), + // branches USE_LIFTER(beq, BEQ), USE_LIFTER(bne, BNE), USE_LIFTER(blt, BLT), USE_LIFTER(bge, BGE), USE_LIFTER(bltu, BLTU), USE_LIFTER(bgeu, BGEU), + USE_LIFTER(jalr, JALR), + USE_LIFTER(jal, JAL), + // concurrency, no-ops in RzIL + USE_LIFTER(fence, FENCE), + USE_LIFTER(fence_i, FENCE_I), + // system + USE_LIFTER(ecall, ECALL), + // RV64I extra loads + USE_LIFTER(lwu, LWU), + // M extension + USE_LIFTER(mul, MUL), + USE_LIFTER(mulhu, MULHU), + USE_LIFTER(divu, DIVU), + USE_LIFTER(remu, REMU), + USE_LIFTER(remuw, REMUW), + /* ---------------------------------- Compressed ---------------------------------*/ + USE_LIFTER(c_addi, C_ADDI), + USE_LIFTER(c_addi16sp, C_ADDI16SP), + USE_LIFTER(c_addi4spn, C_ADDI4SPN), + USE_LIFTER(c_add, C_ADD), + USE_LIFTER(c_andi, C_ANDI), + USE_LIFTER(c_slli, C_SLLI), + USE_LIFTER(c_srli, C_SRLI), + USE_LIFTER(c_srai, C_SRAI), + USE_LIFTER(c_jr, C_JR), + USE_LIFTER(c_jalr, C_JALR), + USE_LIFTER(c_lwsp, C_LWSP), + USE_LIFTER(c_lw, C_LW), + USE_LIFTER(c_ld, C_LD), + USE_LIFTER(c_lui, C_LUI), + USE_LIFTER(c_li, C_LI), USE_LIFTER(c_beqz, C_BEQZ), USE_LIFTER(c_bnez, C_BNEZ), - USE_LIFTER(sb, SB), - USE_LIFTER(sh, SH), - USE_LIFTER(sw, SW), USE_LIFTER(c_sw, C_SW), USE_LIFTER(c_swsp, C_SWSP), - USE_LIFTER(sd, SD), USE_LIFTER(c_sd, C_SD), - USE_LIFTER(add, ADD), - USE_LIFTER(sub, SUB), - USE_LIFTER(and, AND), - USE_LIFTER(or, OR), - USE_LIFTER(xor, XOR), - USE_LIFTER(slt, SLT), - USE_LIFTER(sltu, SLTU), - USE_LIFTER(sll, SLL), - USE_LIFTER(srl, SRL), - USE_LIFTER(sra, SRA), - USE_LIFTER(jal, JAL), USE_LIFTER(c_mv, C_MV), USE_LIFTER(c_j, C_J), + USE_LIFTER(c_or, C_OR), + USE_LIFTER(c_ldsp, C_LDSP), + USE_LIFTER(c_sdsp, C_SDSP), + USE_LIFTER(c_sub, C_SUB), + USE_LIFTER(c_and, C_AND), + USE_LIFTER(c_xor, C_XOR), + USE_LIFTER(c_addw, C_ADDW), + USE_LIFTER(c_addiw, C_ADDIW), + USE_LIFTER(c_subw, C_SUBW), }; RZ_OWN RZ_IPI RzILOpEffect * -rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size) { +rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { rz_return_val_if_fail(analysis && op && insn, NULL); if (insn->id > 0 && insn->id < RZ_ARRAY_SIZE(riscv_lifters)) { @@ -288,5 +134,9 @@ RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis) { RzAnalysisILConfig *conf = rz_analysis_il_config_new(analysis->bits, analysis->big_endian, analysis->bits); + RzILEffectLabel *ecall_label = rz_il_effect_label_new("ecall", EFFECT_LABEL_SYSCALL); + ecall_label->hook = label_ecall; + rz_analysis_il_config_add_label(conf, ecall_label); + return conf; } \ No newline at end of file diff --git a/librz/arch/isa/riscv/riscv_il.h b/librz/arch/isa/riscv/riscv_il.h index eb398ed9042..03c42770f59 100644 --- a/librz/arch/isa/riscv/riscv_il.h +++ b/librz/arch/isa/riscv/riscv_il.h @@ -9,11 +9,11 @@ #include #include -typedef RzILOpEffect *(*RiscvInstructionLifter)(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size); +typedef RzILOpEffect *(*RiscvInstructionLifter)(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size); RZ_OWN RZ_IPI RzILOpEffect * rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, - RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, int size); + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size); RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis); diff --git a/librz/arch/isa/riscv/riscv_il_base.h b/librz/arch/isa/riscv/riscv_il_base.h new file mode 100644 index 00000000000..c52516ed77e --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_base.h @@ -0,0 +1,199 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RISCV_IL_BASE_H +#define RISCV_IL_BASE_H + +#include "riscv.h" +#include "rz_types.h" +#include + +#include "riscv_il.h" +#include "riscv_il_integer_reg_names.h" + +#include + +#define RISCV_GET_REG(reg) (((reg) != RISCV_REG_X0) ? (VARG(riscv_integer_reg_name(reg))) : UN(analysis->bits, 0)) +#define RISCV_SET_REG(reg, r) (((reg) != RISCV_REG_X0) ? (SETG(riscv_integer_reg_name(reg), r)) : ((rz_il_op_pure_free(r), NOP()))) + +#define DEFINE_LIFTER(name, decoder, result) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ + decoder(analysis, insn); \ + return RISCV_SET_REG(rd, result); \ + } + +// by default, a RISC-V jump both sets a destination and sets the PC (i.e., jumps) +#define DEFINE_LIFTER_FOR_JUMP(name, decoder, result, jmp_effect) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ + decoder(analysis, insn); \ + return SEQ2( \ + RISCV_SET_REG(rd, result), \ + jmp_effect); \ + } + +#define DEFINE_LIFTER_WITH_EFFECT(name, decoder, effect) \ + static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ + decoder(analysis, insn); \ + return effect; \ + } + +// oneway jumps are those that don't have a destination register +#define DEFINE_LIFTER_FOR_ONEWAY_JUMP DEFINE_LIFTER_WITH_EFFECT + +// A more intuitive definition would be: +// static const RiscvInstructionLifter rz_riscv_lift_##alias = ...; +// but C (unlike C++) does not treat const-qualified variables as constant expressions +// (C11 ยง6.6), so they cannot appear in a static array initializer. Most compilers +// accept it tolerantly, but TCC enforces the standard strictly and rejects it. +// A forced-inline wrapper is an alternative for 0-indirection aliasing. +#define DEFINE_ALIAS_LIFTER(alias, name) \ + static inline FUNC_ATTR_ALWAYS_INLINE RzILOpEffect *rz_riscv_lift_##alias(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ + return rz_riscv_lift_##name(analysis, op, insn, current_addr, size); \ + } + +#define TWICE_FOR(name1, name2, def_lifter, ...) \ + def_lifter(name1, __VA_ARGS__) \ + def_lifter(name2, __VA_ARGS__) + +#define THRICE_FOR(name1, name2, name3, def_lifter, ...) \ + TWICE_FOR(name1, name2, def_lifter, __VA_ARGS__) \ + def_lifter(name3, __VA_ARGS__) + +#define FOR_4(name1, name2, name3, name4, def_lifter, ...) \ + TWICE_FOR(name1, name2, def_lifter, __VA_ARGS__) \ + TWICE_FOR(name3, name4, def_lifter, __VA_ARGS__) + +#if RZ_CHECKS_LEVEL > 0 +#define REQUIRE_OP(idx, t) \ + if (insn->detail->riscv.operands[idx].type != (t) || insn->detail->riscv.operands[idx].type == RISCV_OP_INVALID) { \ + RZ_LOG_ERROR("[%s (%d) @ 0x%08" PFMT64x "] Expected type %d (%s) at index %d, found type %d instead\n", insn->mnemonic, insn->id, current_addr, t, #t, idx, insn->detail->riscv.operands[idx].type); \ + RZ_LOG_ERROR("op_str: %s\n", insn->op_str); \ + RZ_LOG_ERROR("need_effective_addr: %d\n", insn->detail->riscv.need_effective_addr); \ + RZ_LOG_ERROR("op_count: %u\n", insn->detail->riscv.op_count); \ + for (int _i = 0; _i < insn->detail->riscv.op_count; _i++) { \ + RZ_LOG_ERROR("operands[%d].type: %d\n", _i, insn->detail->riscv.operands[_i].type); \ + if (insn->detail->riscv.operands[_i].type == RISCV_OP_REG) { \ + RZ_LOG_ERROR(" REG = %d\n", insn->detail->riscv.operands[_i].reg); \ + } else if (insn->detail->riscv.operands[_i].type == RISCV_OP_IMM) { \ + RZ_LOG_ERROR(" IMM = 0x%" PFMT64x "\n", (ut64)insn->detail->riscv.operands[_i].imm); \ + } else if (insn->detail->riscv.operands[_i].type == RISCV_OP_MEM) { \ + RZ_LOG_ERROR(" MEM base = %d, disp = 0x%" PFMT64x "\n", insn->detail->riscv.operands[_i].mem.base, (ut64)insn->detail->riscv.operands[_i].mem.disp); \ + } \ + } \ + return NULL; \ + } + +#define REQUIRE_64_BIT(analysis) \ + if (analysis->bits != 64) { \ + RZ_LOG_ERROR("[%s (%d)] Expected 64-bit analysis, found %d bits\n", insn->mnemonic, insn->id, analysis->bits); \ + return NULL; \ + } +#else +#define REQUIRE_OP(idx, t) \ + do { \ + } while (0) +#define REQUIRE_64_BIT(analysis) \ + do { \ + } while (0) +#endif + +// Decoders, every instruction defines how its own transformation of capstone operands to IL operands + +#define DECODE_RD_RS_IMM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_OP(2, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); + +#define DECODE_RD_RS_RS(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_OP(2, RISCV_OP_REG); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[2].reg); + +#define DECODE_RS_IMM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_IMM); \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); + +#define DECODE_RS_RS_IMM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_OP(2, RISCV_OP_IMM); \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); + +#define DECODE_RD_RS(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); + +#define DECODE_IMM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_IMM); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[0].imm); + +#define DECODE_RD_IMM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); + +#define DECODE_RS_RS_IMM_MEM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_MEM); \ + RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); + +#define DECODE_RD_RS_IMM_MEM(analysis, insn) \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_MEM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); + +// used for *w instructions in RV64 that truncate the operands to 32 bits then does the operation +#define DECODE_RD_RS_RS_TRUNCATE32(analysis, insn) \ + REQUIRE_64_BIT(analysis); \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_OP(2, RISCV_OP_REG); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs1 = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[1].reg)); \ + RzILOpBitVector *rs2 = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[2].reg)); + +#define DECODE_RD_RS_IMM_TRUNCATE32(analysis, insn) \ + REQUIRE_64_BIT(analysis); \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_OP(2, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[1].reg)); \ + RzILOpBitVector *imm = SN(32, insn->detail->riscv.operands[2].imm); + +#define DECODE_RD_IMM_TRUNCATE32(analysis, insn) \ + REQUIRE_64_BIT(analysis); \ + REQUIRE_OP(0, RISCV_OP_REG); \ + REQUIRE_OP(1, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *imm = SN(32, insn->detail->riscv.operands[1].imm); + +#define DECODE_NONE(analysis, insn) \ + (void)analysis; \ + (void)insn; + +#define USE_LIFTER(name, uppername) [RISCV_INS_##uppername] = rz_riscv_lift_##name + +#include + +#endif // RISCV_IL_BASE_H \ No newline at end of file diff --git a/librz/arch/isa/riscv/riscv_il_compressed.h b/librz/arch/isa/riscv/riscv_il_compressed.h new file mode 100644 index 00000000000..955a112a31f --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_compressed.h @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RISCV_IL_COMPRESSED_H +#define RISCV_IL_COMPRESSED_H + +#include "riscv/riscv_il_base.h" +#include "riscv_il_integer.h" +#include "rz_util/rz_buf.h" + +#include + +// Compressed instruction decoder variants that suppress operands not consumed by the lifter +#define DECODE_RD_RS_IMM_NO_RS(analysis, insn) \ + DECODE_RD_RS_IMM(analysis, insn) \ + (void)(rs); + +#define DECODE_RD_IMM_NO_RD(analysis, insn) \ + DECODE_RD_IMM(analysis, insn) \ + (void)(rd); + +#define DECODE_RS_RS_IMM_NO_RS2(analysis, insn) \ + DECODE_RS_RS_IMM(analysis, insn) \ + (void)(rs2); + +DEFINE_ALIAS_LIFTER(c_addi, addi) +DEFINE_ALIAS_LIFTER(c_addi16sp, addi) +DEFINE_ALIAS_LIFTER(c_addi4spn, addi) +DEFINE_ALIAS_LIFTER(c_add, add) +DEFINE_ALIAS_LIFTER(c_slli, slli) +DEFINE_ALIAS_LIFTER(c_andi, andi) +DEFINE_ALIAS_LIFTER(c_srli, srli) +DEFINE_ALIAS_LIFTER(c_srai, srai) +DEFINE_ALIAS_LIFTER(c_or, or) +DEFINE_ALIAS_LIFTER(c_sub, sub) +DEFINE_ALIAS_LIFTER(c_and, and) +DEFINE_ALIAS_LIFTER(c_xor, xor) +DEFINE_ALIAS_LIFTER(c_addw, addw) + +DEFINE_ALIAS_LIFTER(c_addiw, addiw) + +DEFINE_ALIAS_LIFTER(c_subw, subw) + +DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) +DEFINE_LIFTER(c_li, DECODE_RD_RS_IMM_NO_RS, DUP(imm)) + +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_RD_IMM_NO_RD, JMP(imm)) +DEFINE_ALIAS_LIFTER(c_jr, jalr) + +DEFINE_ALIAS_LIFTER(c_jalr, jalr) + +DEFINE_ALIAS_LIFTER(c_lui, lui) + +DEFINE_ALIAS_LIFTER(c_sw, sw) +DEFINE_ALIAS_LIFTER(c_swsp, sw) + +DEFINE_ALIAS_LIFTER(c_sd, sd) +DEFINE_ALIAS_LIFTER(c_sdsp, sd) + +DEFINE_ALIAS_LIFTER(c_lwsp, lw) +DEFINE_ALIAS_LIFTER(c_lw, lw) + +DEFINE_ALIAS_LIFTER(c_ld, ld) +DEFINE_ALIAS_LIFTER(c_ldsp, ld) + +DEFINE_LIFTER_FOR_BRANCH(c_beqz, DECODE_RS_RS_IMM_NO_RS2, EQ(rs1, UN(analysis->bits, 0))) +DEFINE_LIFTER_FOR_BRANCH(c_bnez, DECODE_RS_RS_IMM_NO_RS2, NE(rs1, UN(analysis->bits, 0))) + +#include + +#endif // RISCV_IL_COMPRESSED_H diff --git a/librz/arch/isa/riscv/riscv_il_integer.h b/librz/arch/isa/riscv/riscv_il_integer.h new file mode 100644 index 00000000000..6159636594f --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_integer.h @@ -0,0 +1,99 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RISCV_IL_INTEGER_H +#define RISCV_IL_INTEGER_H + +#include "analysis_private.h" +#include "capstone.h" +#include "riscv_il_base.h" + +#include + +DEFINE_LIFTER(addi, DECODE_RD_RS_IMM, ADD(rs, imm)) +DEFINE_LIFTER(slli, DECODE_RD_RS_IMM, SHIFTL0(rs, imm)) +DEFINE_LIFTER(andi, DECODE_RD_RS_IMM, LOGAND(rs, imm)) +DEFINE_LIFTER(ori, DECODE_RD_RS_IMM, LOGOR(rs, imm)) +DEFINE_LIFTER(xori, DECODE_RD_RS_IMM, LOGXOR(rs, imm)) +DEFINE_LIFTER(slti, DECODE_RD_RS_IMM, BOOL_TO_BV(SLT(rs, imm), analysis->bits)) +DEFINE_LIFTER(sltiu, DECODE_RD_RS_IMM, BOOL_TO_BV(ULT(rs, imm), analysis->bits)) +DEFINE_LIFTER(srli, DECODE_RD_RS_IMM, SHIFTR0(rs, imm)) +DEFINE_LIFTER(srai, DECODE_RD_RS_IMM, SHIFTRA(rs, imm)) + +DEFINE_LIFTER(add, DECODE_RD_RS_RS, ADD(rs1, rs2)) +DEFINE_LIFTER(sub, DECODE_RD_RS_RS, SUB(rs1, rs2)) +DEFINE_LIFTER(and, DECODE_RD_RS_RS, LOGAND(rs1, rs2)) +DEFINE_LIFTER(or, DECODE_RD_RS_RS, LOGOR(rs1, rs2)) +DEFINE_LIFTER(xor, DECODE_RD_RS_RS, LOGXOR(rs1, rs2)) +DEFINE_LIFTER(slt, DECODE_RD_RS_RS, BOOL_TO_BV(SLT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sltu, DECODE_RD_RS_RS, BOOL_TO_BV(ULT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sll, DECODE_RD_RS_RS, SHIFTL0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) +DEFINE_LIFTER(srl, DECODE_RD_RS_RS, SHIFTR0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) +DEFINE_LIFTER(sra, DECODE_RD_RS_RS, SHIFTRA(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) + +#define DEFINE_LIFTER_FOR_BRANCH(name, decoder, condition) \ + DEFINE_LIFTER_FOR_ONEWAY_JUMP(name, decoder, BRANCH(condition, JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) + +DEFINE_LIFTER_FOR_BRANCH(beq, DECODE_RS_RS_IMM, EQ(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bne, DECODE_RS_RS_IMM, NE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(blt, DECODE_RS_RS_IMM, SLT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bge, DECODE_RS_RS_IMM, SGE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bltu, DECODE_RS_RS_IMM, ULT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bgeu, DECODE_RS_RS_IMM, UGE(rs1, rs2)) + +DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(imm)) + +DEFINE_LIFTER_FOR_JUMP(jalr, DECODE_RD_RS_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) + +// Intentional: on RV32 imm is already 32-bit and the result needs no sign-extension, +// so CAST(32) and SIGNED(32) would both be no-ops; on RV64 CAST(32) truncates imm and SIGNED(64) +// sign-extends the shifted 32-bit result to XLEN. +DEFINE_LIFTER(lui, DECODE_RD_IMM, + analysis->bits == 32 + ? SHIFTL0(imm, UN(32, 12)) + : SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12)))) +DEFINE_LIFTER(auipc, DECODE_RD_IMM, ADD(UN(analysis->bits, current_addr), SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12))))) + +DEFINE_LIFTER_WITH_EFFECT(sb, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(8, IL_FALSE, rs1))) +DEFINE_LIFTER_WITH_EFFECT(sh, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(16, IL_FALSE, rs1))) +// Intentional: on RV32 rs1 is already 32-bit so CAST(32) would be a redundant no-op; +// on RV64 it is needed to truncate the 64-bit register value to 32 bits before storing. +DEFINE_LIFTER_WITH_EFFECT(sw, DECODE_RS_RS_IMM_MEM, + analysis->bits == 32 + ? STOREW(ADD(rs2, imm), rs1) + : STOREW(ADD(rs2, imm), CAST(32, IL_FALSE, rs1))) +DEFINE_LIFTER_WITH_EFFECT(sd, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), rs1)) + +DEFINE_LIFTER(lw, DECODE_RD_RS_IMM_MEM, analysis->bits == 32 ? LOADW(32, ADD(rs, imm)) : SIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) +DEFINE_LIFTER(lb, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lh, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) +DEFINE_LIFTER(lbu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lhu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) +DEFINE_LIFTER(ld, DECODE_RD_RS_IMM_MEM, LOADW(64, ADD(rs, imm))) + +TWICE_FOR(fence, fence_i, + DEFINE_LIFTER_WITH_EFFECT, DECODE_NONE, NOP()) + +DEFINE_LIFTER(addw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, ADD(rs1, rs2))) +DEFINE_LIFTER(subw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SUB(rs1, rs2))) +DEFINE_LIFTER(sllw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(srlw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(sraw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(addiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, ADD(rs, imm))) +DEFINE_LIFTER(slliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs, imm))) +DEFINE_LIFTER(srliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs, imm))) +DEFINE_LIFTER(sraiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs, imm))) + +// RV64I: load word unsigned (zero-extend 32-bit load to XLEN) +DEFINE_LIFTER(lwu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) + +// System: environment call (trap to OS / hypervisor) +DEFINE_LIFTER_WITH_EFFECT(ecall, DECODE_NONE, GOTO("ecall")) + +#include + +#endif // RISCV_IL_INTEGER_H \ No newline at end of file diff --git a/librz/arch/isa/riscv/riscv_il_integer_reg_names.h b/librz/arch/isa/riscv/riscv_il_integer_reg_names.h new file mode 100644 index 00000000000..80cadb58790 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_integer_reg_names.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RISCV_IL_INTEGER_REG_NAMES_H +#define RISCV_IL_INTEGER_REG_NAMES_H + +#include +#include + +static const char *riscv_integer_reg_names[] = { + /* x0 */ "zero", + /* x1 */ "ra", + /* x2 */ "sp", + /* x3 */ "gp", + /* x4 */ "tp", + /* x5 */ "t0", + /* x6 */ "t1", + /* x7 */ "t2", + /* x8 */ "s0", + /* x9 */ "s1", + /* x10 */ "a0", + /* x11 */ "a1", + /* x12 */ "a2", + /* x13 */ "a3", + /* x14 */ "a4", + /* x15 */ "a5", + /* x16 */ "a6", + /* x17 */ "a7", + /* x18 */ "s2", + /* x19 */ "s3", + /* x20 */ "s4", + /* x21 */ "s5", + /* x22 */ "s6", + /* x23 */ "s7", + /* x24 */ "s8", + /* x25 */ "s9", + /* x26 */ "s10", + /* x27 */ "s11", + /* x28 */ "t3", + /* x29 */ "t4", + /* x30 */ "t5", + /* x31 */ "t6", +}; + +static inline const char *riscv_integer_reg_name(uint32_t reg) { + int idx = (int)reg - RISCV_REG_X0; + if (idx < 0 || idx >= 32) { + return ""; + } + return riscv_integer_reg_names[idx]; +} + +#endif // RISCV_IL_INTEGER_REG_NAMES_H diff --git a/librz/arch/isa/riscv/riscv_il_m.h b/librz/arch/isa/riscv/riscv_il_m.h new file mode 100644 index 00000000000..e3f666f6a44 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_m.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef RISCV_IL_M_H +#define RISCV_IL_M_H + +#include "riscv_il_base.h" + +#include + +// M extension: multiply/divide/remainder (RV32M / RV64M) +DEFINE_LIFTER(mul, DECODE_RD_RS_RS, MUL(rs1, rs2)) +DEFINE_LIFTER(mulhu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(UNSIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) +DEFINE_LIFTER(divu, DECODE_RD_RS_RS, DIV(rs1, rs2)) +DEFINE_LIFTER(remu, DECODE_RD_RS_RS, MOD(rs1, rs2)) +// RV64M: unsigned remainder of 32-bit operands, result sign-extended to 64 bits +DEFINE_LIFTER(remuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MOD(rs1, rs2))) + +#include + +#endif // RISCV_IL_M_H diff --git a/test/db/asm/riscv_32 b/test/db/asm/riscv_32 index 269ff99bf7a..87831e4ba54 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -49,18 +49,18 @@ d "lw s8, 0x68(sp)" 265c 0x40 (set s8 (loadw 0 32 (+ (var sp) (bv 32 0x68)))) d "lw s9, 0x64(sp)" 965c 0x40 (set s9 (loadw 0 32 (+ (var sp) (bv 32 0x64)))) d "lw s10, 0x60(sp)" 065d 0x40 (set s10 (loadw 0 32 (+ (var sp) (bv 32 0x60)))) d "lw s11, 0x5c(sp)" f64d 0x40 (set s11 (loadw 0 32 (+ (var sp) (bv 32 0x5c)))) -d "addi sp, sp, 0x90" 4961 0x40 -d "ret" 8280 0x40 NONE +d "addi sp, sp, 0x90" 4961 0x40 (set sp (+ (var sp) (bv 32 0x90))) +d "ret" 8280 0x40 (seq nop (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) d "lw a5, 0x18(sp)" e247 0x40 (set a5 (loadw 0 32 (+ (var sp) (bv 32 0x18)))) -d "beqz a5, 0x2d8" 63890726 0x66 +d "beqz a5, 0x2d8" 63890726 0x66 (branch (== (var a5) (bv 32 0x0)) (jmp (bv 32 0x2d8)) (jmp (bv 32 0x6a))) d "lw s0, 0x1c(sp)" 7244 0x40 (set s0 (loadw 0 32 (+ (var sp) (bv 32 0x1c)))) d "lw a0, 0x24(sp)" 1255 0x40 (set a0 (loadw 0 32 (+ (var sp) (bv 32 0x24)))) d "lw a6, 0x28(sp)" 2258 0x40 (set a6 (loadw 0 32 (+ (var sp) (bv 32 0x28)))) d "lw t3, 0x38(sp)" 625e 0x40 (set t3 (loadw 0 32 (+ (var sp) (bv 32 0x38)))) -d "srai a5, s0, 0x1f" 9357f441 0x40 +d "srai a5, s0, 0x1f" 9357f441 0x40 (set a5 (>> (var s0) (bv 32 0x1f) (msb (var s0)))) d "lw a2, 0x20(sp)" 0256 0x40 (set a2 (loadw 0 32 (+ (var sp) (bv 32 0x20)))) d "andi a5, a5, 0xf" bd8b 0x40 (set a5 (& (var a5) (bv 32 0xf))) -d "srai a4, a0, 0x1f" 1357f541 0x40 +d "srai a4, a0, 0x1f" 1357f541 0x40 (set a4 (>> (var a0) (bv 32 0x1f) (msb (var a0)))) d "lw a7, 0x30(sp)" c258 0x40 (set a7 (loadw 0 32 (+ (var sp) (bv 32 0x30)))) d "add a3, a5, a6" b3860701 0x80 (set a3 (+ (var a5) (var a6))) d "sub s2, t3, a6" 33090e41 0x80 (set s2 (- (var t3) (var a6))) @@ -81,7 +81,7 @@ d "srli a1, a1, 6" 9981 0x80 (set a1 (>> (var a1) (bv 32 0x6) false)) d "slli a0, a5, 0x1a" 1395a701 0x80 (set a0 (<< (var a5) (bv 32 0x1a) false)) d "sw a4, 0x40(sp)" bac0 0x80 (storew 0 (+ (var sp) (bv 32 0x40)) (var a4)) d "sub a4, a2, a7" 33071641 0x80 (set a4 (- (var a2) (var a7))) -d "add s7, s7, s0" a29b 0xc0 NONE +d "add s7, s7, s0" a29b 0xc0 (set s7 (+ (var s7) (var s0))) d "sw a4, 0x44(sp)" bac2 0xc0 (storew 0 (+ (var sp) (bv 32 0x44)) (var a4)) d "srai a5, a5, 6" 9987 0xc0 (set a5 (>> (var a5) (bv 32 0x6) (msb (var a5)))) d "or a4, a0, a1" 3367b500 0xc0 (set a4 (| (var a0) (var a1))) @@ -100,7 +100,7 @@ d "lui a4, 1" 0567 0xc0 (set a4 (<< (bv 32 0x1) (bv 32 0xc) false)) d "blt a5, a4, 0x2d4" 63c3e71e 0xee (branch (&& (sle (var a5) (var a4)) (! (== (var a5) (var a4)))) (jmp (bv 32 0x2d4)) (jmp (bv 32 0xf2))) d "srli a5, s8, 0x1d" 9357dc01 0xc0 (set a5 (>> (var s8) (bv 32 0x1d) false)) d "slli a4, s7, 3" 13973b00 0xc0 (set a4 (<< (var s7) (bv 32 0x3) false)) -d "or a5, a5, a4" d98f 0xc0 NONE +d "or a5, a5, a4" d98f 0xc0 (set a5 (| (var a5) (var a4))) d "sw a5, 0x4c(sp)" bec6 0xc0 (storew 0 (+ (var sp) (bv 32 0x4c)) (var a5)) d "slli a5, s8, 3" 93173c00 0xc0 (set a5 (<< (var s8) (bv 32 0x3) false)) d "addi a5, sp, 8" 3c00 0x100 (set a5 (+ (var sp) (bv 32 0x8))) @@ -133,63 +133,63 @@ d "li t1, 0" 0143 0x100 (set t1 (bv 32 0x0)) d "li a2, 0" 0146 0x100 (set a2 (bv 32 0x0)) d "li a0, 0" 0145 0x100 (set a0 (bv 32 0x0)) d "j 0x176" 25a8 0x13e (jmp (bv 32 0x176)) -d "mul a4, a0, a2" 3307c502 0x140 -d "mulhu t1, a2, a2" 3333c602 0x140 +d "mul a4, a0, a2" 3307c502 0x140 (set a4 (* (var a0) (var a2))) +d "mulhu t1, a2, a2" 3333c602 0x140 (set t1 (cast 32 false (>> (* (cast 64 false (var a2)) (cast 64 false (var a2))) (bv 8 0x20) false))) d "slli a4, a4, 1" 0607 0x140 (set a4 (<< (var a4) (bv 32 0x1) false)) -d "mul a7, a5, a6" b3880703 0x140 -d "add t1, t1, a4" 3a93 0x140 -d "mul a3, a2, a2" b306c602 0x140 +d "mul a7, a5, a6" b3880703 0x140 (set a7 (* (var a5) (var a6))) +d "add t1, t1, a4" 3a93 0x140 (set t1 (+ (var t1) (var a4))) +d "mul a3, a2, a2" b306c602 0x140 (set a3 (* (var a2) (var a2))) d "slli a7, a7, 1" 8608 0x140 (set a7 (<< (var a7) (bv 32 0x1) false)) -d "mulhu t3, a6, a6" 333e0803 0x140 -d "mul a4, a6, a6" 33070803 0x140 -d "add t3, t3, a7" 469e 0x140 -d "add t5, t1, t3" 330fc301 0x140 -d "add t4, a3, a4" b38ee600 0x140 -d "sltu a7, t4, a3" b3b8de00 0x140 -d "add a7, a7, t5" fa98 0x140 +d "mulhu t3, a6, a6" 333e0803 0x140 (set t3 (cast 32 false (>> (* (cast 64 false (var a6)) (cast 64 false (var a6))) (bv 8 0x20) false))) +d "mul a4, a6, a6" 33070803 0x140 (set a4 (* (var a6) (var a6))) +d "add t3, t3, a7" 469e 0x140 (set t3 (+ (var t3) (var a7))) +d "add t5, t1, t3" 330fc301 0x140 (set t5 (+ (var t1) (var t3))) +d "add t4, a3, a4" b38ee600 0x140 (set t4 (+ (var a3) (var a4))) +d "sltu a7, t4, a3" b3b8de00 0x140 (set a7 (ite (&& (ule (var t4) (var a3)) (! (== (var t4) (var a3)))) (bv 32 0x1) (bv 32 0x0))) +d "add a7, a7, t5" fa98 0x140 (set a7 (+ (var a7) (var t5))) d "blt s1, a7, 0x2c6" 63cc1415 0x16e (branch (&& (sle (var s1) (var a7)) (! (== (var s1) (var a7)))) (jmp (bv 32 0x2c6)) (jmp (bv 32 0x172))) d "beq a7, s1, 0x2c2" 63889814 0x172 (branch (== (var a7) (var s1)) (jmp (bv 32 0x2c2)) (jmp (bv 32 0x176))) -d "sub a4, a3, a4" 3387e640 0x140 -d "sub t3, t1, t3" 330ec341 0x140 -d "sltu a3, ra, zero" b3b60000 0x140 -d "add a7, a4, s10" b308a701 0x180 -d "sub a3, t3, a3" b306de40 0x180 -d "sltu a4, a7, a4" 33b7e800 0x180 -d "add a3, a3, s5" d696 0x180 -d "add a3, a3, a4" ba96 0x180 -d "mul a5, a5, a2" b387c702 0x180 +d "sub a4, a3, a4" 3387e640 0x140 (set a4 (- (var a3) (var a4))) +d "sub t3, t1, t3" 330ec341 0x140 (set t3 (- (var t1) (var t3))) +d "sltu a3, ra, zero" b3b60000 0x140 (set a3 (ite (&& (ule (var ra) (bv 32 0x0)) (! (== (var ra) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0))) +d "add a7, a4, s10" b308a701 0x180 (set a7 (+ (var a4) (var s10))) +d "sub a3, t3, a3" b306de40 0x180 (set a3 (- (var t3) (var a3))) +d "sltu a4, a7, a4" 33b7e800 0x180 (set a4 (ite (&& (ule (var a7) (var a4)) (! (== (var a7) (var a4)))) (bv 32 0x1) (bv 32 0x0))) +d "add a3, a3, s5" d696 0x180 (set a3 (+ (var a3) (var s5))) +d "add a3, a3, a4" ba96 0x180 (set a3 (+ (var a3) (var a4))) +d "mul a5, a5, a2" b387c702 0x180 (set a5 (* (var a5) (var a2))) d "slli t1, a3, 8" 13938600 0x180 (set t1 (<< (var a3) (bv 32 0x8) false)) d "addi a1, a1, 1" 8505 0x180 (set a1 (+ (var a1) (bv 32 0x1))) -d "mul a4, a0, a6" 33070503 0x180 +d "mul a4, a0, a6" 33070503 0x180 (set a4 (* (var a0) (var a6))) d "srai a0, a3, 0x18" 13d58641 0x180 (set a0 (>> (var a3) (bv 32 0x18) (msb (var a3)))) -d "mulhu a3, a6, a2" b336c802 0x180 -d "add a4, a4, a5" 3e97 0x180 -d "mul a6, a6, a2" 3308c802 0x180 -d "add a4, a4, a3" 3697 0x180 +d "mulhu a3, a6, a2" b336c802 0x180 (set a3 (cast 32 false (>> (* (cast 64 false (var a6)) (cast 64 false (var a2))) (bv 8 0x20) false))) +d "add a4, a4, a5" 3e97 0x180 (set a4 (+ (var a4) (var a5))) +d "mul a6, a6, a2" 3308c802 0x180 (set a6 (* (var a6) (var a2))) +d "add a4, a4, a3" 3697 0x180 (set a4 (+ (var a4) (var a3))) d "srli a2, a7, 0x18" 13d68801 0x180 (set a2 (>> (var a7) (bv 32 0x18) false)) d "slli a4, a4, 1" 0607 0x180 (set a4 (<< (var a4) (bv 32 0x1) false)) -d "or a2, t1, a2" 3366c300 0x180 +d "or a2, t1, a2" 3366c300 0x180 (set a2 (| (var t1) (var a2))) d "slli a7, a6, 1" 93181800 0x180 (set a7 (<< (var a6) (bv 32 0x1) false)) d "srli a3, a6, 0x1f" 9356f801 0x180 (set a3 (>> (var a6) (bv 32 0x1f) false)) -d "add a5, a7, t2" b3877800 0x1c0 -d "or a4, a4, a3" 558f 0x1c0 +d "add a5, a7, t2" b3877800 0x1c0 (set a5 (+ (var a7) (var t2))) +d "or a4, a4, a3" 558f 0x1c0 (set a4 (| (var a4) (var a3))) d "srli a6, a5, 0x18" 13d88701 0x1c0 (set a6 (>> (var a5) (bv 32 0x18) false)) -d "add a4, a4, t6" 7e97 0x1c0 -d "sltu a5, a5, a7" b3b71701 0x1c0 -d "add a4, a4, a5" 3e97 0x1c0 +d "add a4, a4, t6" 7e97 0x1c0 (set a4 (+ (var a4) (var t6))) +d "sltu a5, a5, a7" b3b71701 0x1c0 (set a5 (ite (&& (ule (var a5) (var a7)) (! (== (var a5) (var a7)))) (bv 32 0x1) (bv 32 0x0))) +d "add a4, a4, a5" 3e97 0x1c0 (set a4 (+ (var a4) (var a5))) d "slli a5, a4, 8" 93178700 0x1c0 (set a5 (<< (var a4) (bv 32 0x8) false)) -d "or a6, a5, a6" 33e80701 0x1c0 -d "srai a5, a4, 0x18" 93578741 0x1c0 +d "or a6, a5, a6" 33e80701 0x1c0 (set a6 (| (var a5) (var a6))) +d "srai a5, a4, 0x18" 93578741 0x1c0 (set a5 (>> (var a4) (bv 32 0x18) (msb (var a4)))) d "bne a1, s6, 0x140" e39065f7 0x1e0 (branch (! (== (var a1) (var s6))) (jmp (bv 32 0x140)) (jmp (bv 32 0x1e4))) -d "li a5, 0" 8147 0x1c0 -d "add a4, t2, s8" 33878301 0x1c0 -d "sltu a3, a4, t2" b3367700 0x1c0 -d "or s2, a5, s2" 33e92701 0x1c0 -d "add t6, t6, s7" de9f 0x1c0 +d "li a5, 0" 8147 0x1c0 (set a5 (bv 32 0x0)) +d "add a4, t2, s8" 33878301 0x1c0 (set a4 (+ (var t2) (var s8))) +d "sltu a3, a4, t2" b3367700 0x1c0 (set a3 (ite (&& (ule (var a4) (var t2)) (! (== (var a4) (var t2)))) (bv 32 0x1) (bv 32 0x0))) +d "or s2, a5, s2" 33e92701 0x1c0 (set s2 (| (var a5) (var s2))) +d "add t6, t6, s7" de9f 0x1c0 (set t6 (+ (var t6) (var s7))) d "addi ra, ra, 1" 8500 0x1c0 (set ra (+ (var ra) (bv 32 0x1))) d "andi s2, s2, 0xff" 1379f90f 0x1c0 (set s2 (& (var s2) (bv 32 0xff))) -d "mv t2, a4" ba83 0x1c0 -d "add t6, t6, a3" b69f 0x1c0 +d "mv t2, a4" ba83 0x1c0 (set t2 (var a4)) +d "add t6, t6, a3" b69f 0x1c0 (set t6 (+ (var t6) (var a3))) d "ori a5, a5, 0x89" 93e79708 0x0 (set a5 (| (var a5) (bv 32 0x89))) d "xori a5, a5, 0x431" 93c71743 0x0 (set a5 (^ (var a5) (bv 32 0x431))) d "jalr ra" e7800000 0x30 (seq (set ra (bv 32 0x34)) (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) From 5cfb62209fd057608ef6148791575d21e59ec91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:55:02 +0300 Subject: [PATCH 03/10] cut down on macro usage --- librz/arch/isa/riscv/riscv_il_base.h | 149 ++++++++++++++++----------- 1 file changed, 88 insertions(+), 61 deletions(-) diff --git a/librz/arch/isa/riscv/riscv_il_base.h b/librz/arch/isa/riscv/riscv_il_base.h index c52516ed77e..5c31ce4ce80 100644 --- a/librz/arch/isa/riscv/riscv_il_base.h +++ b/librz/arch/isa/riscv/riscv_il_base.h @@ -13,14 +13,19 @@ #include -#define RISCV_GET_REG(reg) (((reg) != RISCV_REG_X0) ? (VARG(riscv_integer_reg_name(reg))) : UN(analysis->bits, 0)) -#define RISCV_SET_REG(reg, r) (((reg) != RISCV_REG_X0) ? (SETG(riscv_integer_reg_name(reg), r)) : ((rz_il_op_pure_free(r), NOP()))) +static inline RzILOpBitVector *riscv_il_get_reg(ut32 bits, uint32_t reg) { + return reg != RISCV_REG_X0 ? VARG(riscv_integer_reg_name(reg)) : UN(bits, 0); +} + +static inline RzILOpEffect *riscv_il_set_reg(uint32_t reg, RZ_OWN RZ_NONNULL RzILOpBitVector *value) { + return reg != RISCV_REG_X0 ? SETG(riscv_integer_reg_name(reg), value) : ((rz_il_op_pure_free(value), NOP())); +} #define DEFINE_LIFTER(name, decoder, result) \ static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ decoder(analysis, insn); \ - return RISCV_SET_REG(rd, result); \ + return riscv_il_set_reg(rd, result); \ } // by default, a RISC-V jump both sets a destination and sets the PC (i.e., jumps) @@ -29,7 +34,7 @@ RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ decoder(analysis, insn); \ return SEQ2( \ - RISCV_SET_REG(rd, result), \ + riscv_il_set_reg(rd, result), \ jmp_effect); \ } @@ -67,30 +72,62 @@ TWICE_FOR(name3, name4, def_lifter, __VA_ARGS__) #if RZ_CHECKS_LEVEL > 0 +static inline void riscv_il_dump_operands(RZ_NONNULL cs_insn *insn) { + RZ_LOG_ERROR("op_str: %s\n", insn->op_str); + RZ_LOG_ERROR("need_effective_addr: %d\n", insn->detail->riscv.need_effective_addr); + RZ_LOG_ERROR("op_count: %u\n", insn->detail->riscv.op_count); + for (int i = 0; i < insn->detail->riscv.op_count; i++) { + RZ_LOG_ERROR("operands[%d].type: %d\n", i, insn->detail->riscv.operands[i].type); + if (insn->detail->riscv.operands[i].type == RISCV_OP_REG) { + RZ_LOG_ERROR(" REG = %d\n", insn->detail->riscv.operands[i].reg); + } else if (insn->detail->riscv.operands[i].type == RISCV_OP_IMM) { + RZ_LOG_ERROR(" IMM = 0x%" PFMT64x "\n", (ut64)insn->detail->riscv.operands[i].imm); + } else if (insn->detail->riscv.operands[i].type == RISCV_OP_MEM) { + RZ_LOG_ERROR(" MEM base = %d, disp = 0x%" PFMT64x "\n", insn->detail->riscv.operands[i].mem.base, (ut64)insn->detail->riscv.operands[i].mem.disp); + } + } +} + +static inline void riscv_il_log_operand_mismatch(RZ_NONNULL cs_insn *insn, ut64 current_addr, int idx, int type, const char *type_name) { + RZ_LOG_ERROR("[%s (%d) @ 0x%08" PFMT64x "] Expected type %d (%s) at index %d, found type %d instead\n", + insn->mnemonic, insn->id, current_addr, type, type_name, idx, insn->detail->riscv.operands[idx].type); + riscv_il_dump_operands(insn); +} + +static inline bool riscv_il_require_op(RZ_NONNULL cs_insn *insn, ut64 current_addr, int idx, int type, const char *type_name) { + if (insn->detail->riscv.operands[idx].type == type && insn->detail->riscv.operands[idx].type != RISCV_OP_INVALID) { + return true; + } + riscv_il_log_operand_mismatch(insn, current_addr, idx, type, type_name); + return false; +} + +static inline bool riscv_il_require_64_bit(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL cs_insn *insn) { + if (analysis->bits == 64) { + return true; + } + RZ_LOG_ERROR("[%s (%d)] Expected 64-bit analysis, found %d bits\n", insn->mnemonic, insn->id, analysis->bits); + return false; +} + #define REQUIRE_OP(idx, t) \ - if (insn->detail->riscv.operands[idx].type != (t) || insn->detail->riscv.operands[idx].type == RISCV_OP_INVALID) { \ - RZ_LOG_ERROR("[%s (%d) @ 0x%08" PFMT64x "] Expected type %d (%s) at index %d, found type %d instead\n", insn->mnemonic, insn->id, current_addr, t, #t, idx, insn->detail->riscv.operands[idx].type); \ - RZ_LOG_ERROR("op_str: %s\n", insn->op_str); \ - RZ_LOG_ERROR("need_effective_addr: %d\n", insn->detail->riscv.need_effective_addr); \ - RZ_LOG_ERROR("op_count: %u\n", insn->detail->riscv.op_count); \ - for (int _i = 0; _i < insn->detail->riscv.op_count; _i++) { \ - RZ_LOG_ERROR("operands[%d].type: %d\n", _i, insn->detail->riscv.operands[_i].type); \ - if (insn->detail->riscv.operands[_i].type == RISCV_OP_REG) { \ - RZ_LOG_ERROR(" REG = %d\n", insn->detail->riscv.operands[_i].reg); \ - } else if (insn->detail->riscv.operands[_i].type == RISCV_OP_IMM) { \ - RZ_LOG_ERROR(" IMM = 0x%" PFMT64x "\n", (ut64)insn->detail->riscv.operands[_i].imm); \ - } else if (insn->detail->riscv.operands[_i].type == RISCV_OP_MEM) { \ - RZ_LOG_ERROR(" MEM base = %d, disp = 0x%" PFMT64x "\n", insn->detail->riscv.operands[_i].mem.base, (ut64)insn->detail->riscv.operands[_i].mem.disp); \ - } \ - } \ + if (!riscv_il_require_op(insn, current_addr, idx, t, #t)) { \ return NULL; \ } #define REQUIRE_64_BIT(analysis) \ - if (analysis->bits != 64) { \ - RZ_LOG_ERROR("[%s (%d)] Expected 64-bit analysis, found %d bits\n", insn->mnemonic, insn->id, analysis->bits); \ + if (!riscv_il_require_64_bit(analysis, insn)) { \ return NULL; \ } + +#define REQUIRE_2OPS(t0, t1) \ + REQUIRE_OP(0, t0); \ + REQUIRE_OP(1, t1) + +#define REQUIRE_3OPS(t0, t1, t2) \ + REQUIRE_OP(0, t0); \ + REQUIRE_OP(1, t1); \ + REQUIRE_OP(2, t2) #else #define REQUIRE_OP(idx, t) \ do { \ @@ -98,93 +135,83 @@ #define REQUIRE_64_BIT(analysis) \ do { \ } while (0) +#define REQUIRE_2OPS(t0, t1) \ + do { \ + } while (0) +#define REQUIRE_3OPS(t0, t1, t2) \ + do { \ + } while (0) #endif // Decoders, every instruction defines how its own transformation of capstone operands to IL operands #define DECODE_RD_RS_IMM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ - REQUIRE_OP(2, RISCV_OP_IMM); \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *rs = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); #define DECODE_RD_RS_RS(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ - REQUIRE_OP(2, RISCV_OP_REG); \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_REG); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[2].reg); + RzILOpBitVector *rs1 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg); \ + RzILOpBitVector *rs2 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[2].reg); #define DECODE_RS_IMM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_IMM); \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_IMM); \ + RzILOpBitVector *rs = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[0].reg); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); #define DECODE_RS_RS_IMM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ - REQUIRE_OP(2, RISCV_OP_IMM); \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ + RzILOpBitVector *rs1 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); #define DECODE_RD_RS(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_REG); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].reg); + RzILOpBitVector *rs = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg); #define DECODE_IMM(analysis, insn) \ REQUIRE_OP(0, RISCV_OP_IMM); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[0].imm); #define DECODE_RD_IMM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_IMM); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_IMM); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].imm); #define DECODE_RS_RS_IMM_MEM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_MEM); \ - RzILOpBitVector *rs1 = RISCV_GET_REG(insn->detail->riscv.operands[0].reg); \ - RzILOpBitVector *rs2 = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_MEM); \ + RzILOpBitVector *rs1 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *rs2 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].mem.base); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); #define DECODE_RD_RS_IMM_MEM(analysis, insn) \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_MEM); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_MEM); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = RISCV_GET_REG(insn->detail->riscv.operands[1].mem.base); \ + RzILOpBitVector *rs = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].mem.base); \ RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[1].mem.disp); // used for *w instructions in RV64 that truncate the operands to 32 bits then does the operation #define DECODE_RD_RS_RS_TRUNCATE32(analysis, insn) \ REQUIRE_64_BIT(analysis); \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ - REQUIRE_OP(2, RISCV_OP_REG); \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_REG); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs1 = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[1].reg)); \ - RzILOpBitVector *rs2 = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[2].reg)); + RzILOpBitVector *rs1 = CAST(32, IL_FALSE, riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg)); \ + RzILOpBitVector *rs2 = CAST(32, IL_FALSE, riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[2].reg)); #define DECODE_RD_RS_IMM_TRUNCATE32(analysis, insn) \ REQUIRE_64_BIT(analysis); \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_REG); \ - REQUIRE_OP(2, RISCV_OP_IMM); \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ - RzILOpBitVector *rs = CAST(32, IL_FALSE, RISCV_GET_REG(insn->detail->riscv.operands[1].reg)); \ + RzILOpBitVector *rs = CAST(32, IL_FALSE, riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg)); \ RzILOpBitVector *imm = SN(32, insn->detail->riscv.operands[2].imm); #define DECODE_RD_IMM_TRUNCATE32(analysis, insn) \ REQUIRE_64_BIT(analysis); \ - REQUIRE_OP(0, RISCV_OP_REG); \ - REQUIRE_OP(1, RISCV_OP_IMM); \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_IMM); \ uint32_t rd = insn->detail->riscv.operands[0].reg; \ RzILOpBitVector *imm = SN(32, insn->detail->riscv.operands[1].imm); From a67fd591bc4332ba03b79a6aa6f35bc8201489d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sat, 20 Jun 2026 22:38:16 +0300 Subject: [PATCH 04/10] fix some tests --- librz/arch/isa/riscv/riscv_il.c | 12 ++++++++---- test/db/cmd/cmd_aL | 2 +- test/db/cmd/cmd_list | 7 ++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/librz/arch/isa/riscv/riscv_il.c b/librz/arch/isa/riscv/riscv_il.c index 61f99b2fb14..08036b7319f 100644 --- a/librz/arch/isa/riscv/riscv_il.c +++ b/librz/arch/isa/riscv/riscv_il.c @@ -117,15 +117,19 @@ RZ_OWN RZ_IPI RzILOpEffect * rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { rz_return_val_if_fail(analysis && op && insn, NULL); - if (insn->id > 0 && insn->id < RZ_ARRAY_SIZE(riscv_lifters)) { + if (insn->id == RISCV_INS_INVALID) { + return NULL; + } + if (insn->id >= RISCV_INS_ENDING) { + RZ_LOG_ERROR("Invalid RISC-V instruction id %u (0x%08x)\n", insn->id, rz_read_le32(insn->bytes)); + return NULL; + } + if (insn->id < RZ_ARRAY_SIZE(riscv_lifters)) { RiscvInstructionLifter lifter = riscv_lifters[insn->id]; if (lifter) { return lifter(analysis, op, insn, current_addr, size); - } else { - RZ_LOG_ERROR("No lifter found for instruction %s (id: %d) (0x%08x)", insn->mnemonic, insn->id, rz_read_le32(insn->bytes)); } } - rz_warn_if_reached(); return NULL; } diff --git a/test/db/cmd/cmd_aL b/test/db/cmd/cmd_aL index 0937f28838c..ba4a94d3242 100644 --- a/test/db/cmd/cmd_aL +++ b/test/db/cmd/cmd_aL @@ -49,7 +49,7 @@ _dAeI 32 64 ppc BSD PowerPC Capstone-based disassembler (by pan a____ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj) _dA__ 32 propeller LGPL3 Parallax Propeller disassembler _dA__ 8 16 pyc LGPL3 Python bytecode (PYC) disassembler -_dA__ 32 64 riscv BSD RISC-V Capstone-based disassembler +_dA_I 32 64 riscv BSD RISC-V Capstone-based disassembler adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin) diff --git a/test/db/cmd/cmd_list b/test/db/cmd/cmd_list index 95199620957..471679c8ba0 100644 --- a/test/db/cmd/cmd_list +++ b/test/db/cmd/cmd_list @@ -788,7 +788,7 @@ _dAeI 32 64 ppc BSD PowerPC Capstone-based disassembler (by pan a____ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj) _dA__ 32 propeller LGPL3 Parallax Propeller disassembler _dA__ 8 16 pyc LGPL3 Python bytecode (PYC) disassembler -_dA__ 32 64 riscv BSD RISC-V Capstone-based disassembler +_dA_I 32 64 riscv BSD RISC-V Capstone-based disassembler adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin) @@ -861,7 +861,7 @@ _dAeI 32 64 ppc BSD pancake PowerPC Capstone-based a____ 32 64 ppc.as LGPL3 eagleoflqj as PPC Assembler (use RZ_PPC_AS environment) _dA__ 32 propeller LGPL3 Parallax Propeller disassembler _dA__ 8 16 pyc LGPL3 Python bytecode (PYC) disassembler -_dA__ 32 64 riscv BSD RISC-V Capstone-based disassembler +_dA_I 32 64 riscv BSD RISC-V Capstone-based disassembler adA__ 32 rl78 LGPL3 Bastian Engel Renesas RL78 disassembler _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Heersin Renesas RX Family disassembler @@ -997,6 +997,7 @@ adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler _dA_I 16 msp430 LGPL3 Texas Instruments MSP430 disassembler _dAeI 16 32 pic LGPL3 Microchip PIC disassembler _dAeI 32 64 ppc BSD PowerPC Capstone-based disassembler (by pancake) +_dA_I 32 64 riscv BSD RISC-V Capstone-based disassembler adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) _dA_I 32 64 sparc BSD Sun SPARC Capstone-based disassembler _dA_I 32 tms320 LGPL3 Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler @@ -1128,7 +1129,7 @@ a____ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler (Use RZ_X86_AS env) a____ 16 32 64 x86.nasm LGPL3 X86 nasm assembler a____ 16 32 64 x86.nz LGPL3 x86 handmade assembler adA__ 8 z80 GPL3 Zilog Z80 disassembler (by condret) -["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4/SuperH-3 disassembler","features":"adAeI","author":"DMaroo"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"}] +["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"riscv":{"bits":"32 64","license":"BSD","description":"RISC-V Capstone-based disassembler","features":"_dA_I"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4/SuperH-3 disassembler","features":"adAeI","author":"DMaroo"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"}] name bits features license version author description ----------------------------------------------------------------------------------------------- _dAeI 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU From b49c5d2541d597f778a0594594d391b47c438b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Wed, 24 Jun 2026 02:16:55 +0300 Subject: [PATCH 05/10] address review --- librz/arch/isa/riscv/riscv_il.c | 35 +++- librz/arch/isa/riscv/riscv_il_base.h | 27 ++- librz/arch/isa/riscv/riscv_il_compressed.c | 73 ++++++++ librz/arch/isa/riscv/riscv_il_compressed.h | 105 +++++------ librz/arch/isa/riscv/riscv_il_integer.c | 102 +++++++++++ librz/arch/isa/riscv/riscv_il_integer.h | 165 ++++++++---------- .../isa/riscv/riscv_il_integer_reg_names.h | 3 +- librz/arch/isa/riscv/riscv_il_m.c | 31 ++++ librz/arch/isa/riscv/riscv_il_m.h | 28 +-- librz/arch/meson.build | 3 + 10 files changed, 382 insertions(+), 190 deletions(-) create mode 100644 librz/arch/isa/riscv/riscv_il_compressed.c create mode 100644 librz/arch/isa/riscv/riscv_il_integer.c create mode 100644 librz/arch/isa/riscv/riscv_il_m.c diff --git a/librz/arch/isa/riscv/riscv_il.c b/librz/arch/isa/riscv/riscv_il.c index 08036b7319f..35ff0001cc5 100644 --- a/librz/arch/isa/riscv/riscv_il.c +++ b/librz/arch/isa/riscv/riscv_il.c @@ -2,6 +2,8 @@ // SPDX-License-Identifier: BSD-3-Clause #include "riscv_il.h" +#include "analysis_private.h" +#include "riscv_il_base.h" #include "riscv_il_integer.h" #include "riscv_il_m.h" #include "riscv_il_compressed.h" @@ -10,6 +12,10 @@ static void label_ecall(RzILVM *vm, RzILOpEffect *op) { // stub: ecall is handled at the analysis layer } +static void label_ebreak(RzILVM *vm, RzILOpEffect *op) { + // stub: ebreak is handled at the analysis layer +} + static const RiscvInstructionLifter riscv_lifters[] = { /* ---------------------------------- Integer ---------------------------------*/ // arithmetic, immediate @@ -71,15 +77,25 @@ static const RiscvInstructionLifter riscv_lifters[] = { USE_LIFTER(fence_i, FENCE_I), // system USE_LIFTER(ecall, ECALL), + USE_LIFTER(ebreak, EBREAK), // RV64I extra loads USE_LIFTER(lwu, LWU), // M extension USE_LIFTER(mul, MUL), + USE_LIFTER(mulh, MULH), + USE_LIFTER(mulhsu, MULHSU), USE_LIFTER(mulhu, MULHU), + USE_LIFTER(div, DIV), USE_LIFTER(divu, DIVU), + USE_LIFTER(rem, REM), USE_LIFTER(remu, REMU), + USE_LIFTER(mulw, MULW), + USE_LIFTER(divw, DIVW), + USE_LIFTER(divuw, DIVUW), + USE_LIFTER(remw, REMW), USE_LIFTER(remuw, REMUW), /* ---------------------------------- Compressed ---------------------------------*/ + USE_LIFTER(c_nop, C_NOP), USE_LIFTER(c_addi, C_ADDI), USE_LIFTER(c_addi16sp, C_ADDI16SP), USE_LIFTER(c_addi4spn, C_ADDI4SPN), @@ -90,6 +106,7 @@ static const RiscvInstructionLifter riscv_lifters[] = { USE_LIFTER(c_srai, C_SRAI), USE_LIFTER(c_jr, C_JR), USE_LIFTER(c_jalr, C_JALR), + USE_LIFTER(c_ebreak, C_EBREAK), USE_LIFTER(c_lwsp, C_LWSP), USE_LIFTER(c_lw, C_LW), USE_LIFTER(c_ld, C_LD), @@ -102,6 +119,7 @@ static const RiscvInstructionLifter riscv_lifters[] = { USE_LIFTER(c_sd, C_SD), USE_LIFTER(c_mv, C_MV), USE_LIFTER(c_j, C_J), + USE_LIFTER(c_jal, C_JAL), USE_LIFTER(c_or, C_OR), USE_LIFTER(c_ldsp, C_LDSP), USE_LIFTER(c_sdsp, C_SDSP), @@ -124,13 +142,14 @@ rz_riscv_lift_instr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnal RZ_LOG_ERROR("Invalid RISC-V instruction id %u (0x%08x)\n", insn->id, rz_read_le32(insn->bytes)); return NULL; } - if (insn->id < RZ_ARRAY_SIZE(riscv_lifters)) { - RiscvInstructionLifter lifter = riscv_lifters[insn->id]; - if (lifter) { - return lifter(analysis, op, insn, current_addr, size); - } + if (insn->id >= RZ_ARRAY_SIZE(riscv_lifters)) { + return NULL; + } + RiscvInstructionLifter lifter = riscv_lifters[insn->id]; + if (!lifter) { + return NULL; } - return NULL; + return lifter(analysis, op, insn, current_addr, size); } RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis) { @@ -142,5 +161,9 @@ RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis) { ecall_label->hook = label_ecall; rz_analysis_il_config_add_label(conf, ecall_label); + RzILEffectLabel *ebreak_label = rz_il_effect_label_new("ebreak", EFFECT_LABEL_SYSCALL); + ebreak_label->hook = label_ebreak; + rz_analysis_il_config_add_label(conf, ebreak_label); + return conf; } \ No newline at end of file diff --git a/librz/arch/isa/riscv/riscv_il_base.h b/librz/arch/isa/riscv/riscv_il_base.h index 5c31ce4ce80..86c0ee3d78c 100644 --- a/librz/arch/isa/riscv/riscv_il_base.h +++ b/librz/arch/isa/riscv/riscv_il_base.h @@ -18,11 +18,16 @@ static inline RzILOpBitVector *riscv_il_get_reg(ut32 bits, uint32_t reg) { } static inline RzILOpEffect *riscv_il_set_reg(uint32_t reg, RZ_OWN RZ_NONNULL RzILOpBitVector *value) { - return reg != RISCV_REG_X0 ? SETG(riscv_integer_reg_name(reg), value) : ((rz_il_op_pure_free(value), NOP())); + if (reg != RISCV_REG_X0) { + return SETG(riscv_integer_reg_name(reg), value); + } + // assigning to x0 is a no-op, so the value will never be referenced in the IL tree + rz_il_op_pure_free(value); + return NOP(); } #define DEFINE_LIFTER(name, decoder, result) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ decoder(analysis, insn); \ return riscv_il_set_reg(rd, result); \ @@ -30,7 +35,7 @@ static inline RzILOpEffect *riscv_il_set_reg(uint32_t reg, RZ_OWN RZ_NONNULL RzI // by default, a RISC-V jump both sets a destination and sets the PC (i.e., jumps) #define DEFINE_LIFTER_FOR_JUMP(name, decoder, result, jmp_effect) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ decoder(analysis, insn); \ return SEQ2( \ @@ -39,7 +44,7 @@ static inline RzILOpEffect *riscv_il_set_reg(uint32_t reg, RZ_OWN RZ_NONNULL RzI } #define DEFINE_LIFTER_WITH_EFFECT(name, decoder, effect) \ - static RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ decoder(analysis, insn); \ return effect; \ @@ -55,22 +60,10 @@ static inline RzILOpEffect *riscv_il_set_reg(uint32_t reg, RZ_OWN RZ_NONNULL RzI // accept it tolerantly, but TCC enforces the standard strictly and rejects it. // A forced-inline wrapper is an alternative for 0-indirection aliasing. #define DEFINE_ALIAS_LIFTER(alias, name) \ - static inline FUNC_ATTR_ALWAYS_INLINE RzILOpEffect *rz_riscv_lift_##alias(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ + RzILOpEffect *rz_riscv_lift_##alias(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { \ return rz_riscv_lift_##name(analysis, op, insn, current_addr, size); \ } -#define TWICE_FOR(name1, name2, def_lifter, ...) \ - def_lifter(name1, __VA_ARGS__) \ - def_lifter(name2, __VA_ARGS__) - -#define THRICE_FOR(name1, name2, name3, def_lifter, ...) \ - TWICE_FOR(name1, name2, def_lifter, __VA_ARGS__) \ - def_lifter(name3, __VA_ARGS__) - -#define FOR_4(name1, name2, name3, name4, def_lifter, ...) \ - TWICE_FOR(name1, name2, def_lifter, __VA_ARGS__) \ - TWICE_FOR(name3, name4, def_lifter, __VA_ARGS__) - #if RZ_CHECKS_LEVEL > 0 static inline void riscv_il_dump_operands(RZ_NONNULL cs_insn *insn) { RZ_LOG_ERROR("op_str: %s\n", insn->op_str); diff --git a/librz/arch/isa/riscv/riscv_il_compressed.c b/librz/arch/isa/riscv/riscv_il_compressed.c new file mode 100644 index 00000000000..c8127570c51 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_compressed.c @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#include "riscv_il_compressed.h" + +#include "analysis_private.h" +#include "riscv/riscv_il_base.h" +#include "riscv_il_integer.h" +#include "rz_util/rz_buf.h" + +#include + +// Compressed instruction decoder variants that suppress operands not consumed by the lifter +#define DECODE_RD_RS_IMM_NO_RS(analysis, insn) \ + DECODE_RD_RS_IMM(analysis, insn) \ + (void)(rs); + +#define DECODE_RD_IMM_NO_RD(analysis, insn) \ + DECODE_RD_IMM(analysis, insn) \ + (void)(rd); + +#define DECODE_RS_RS_IMM_NO_RS2(analysis, insn) \ + DECODE_RS_RS_IMM(analysis, insn) \ + (void)(rs2); + +DEFINE_LIFTER_WITH_EFFECT(c_nop, DECODE_NONE, NOP()) +DEFINE_ALIAS_LIFTER(c_addi, addi) +DEFINE_ALIAS_LIFTER(c_addi16sp, addi) +DEFINE_ALIAS_LIFTER(c_addi4spn, addi) +DEFINE_ALIAS_LIFTER(c_add, add) +DEFINE_ALIAS_LIFTER(c_slli, slli) +DEFINE_ALIAS_LIFTER(c_andi, andi) +DEFINE_ALIAS_LIFTER(c_srli, srli) +DEFINE_ALIAS_LIFTER(c_srai, srai) +DEFINE_ALIAS_LIFTER(c_or, or) +DEFINE_ALIAS_LIFTER(c_sub, sub) +DEFINE_ALIAS_LIFTER(c_and, and) +DEFINE_ALIAS_LIFTER(c_xor, xor) +DEFINE_ALIAS_LIFTER(c_addw, addw) + +DEFINE_ALIAS_LIFTER(c_addiw, addiw) + +DEFINE_ALIAS_LIFTER(c_subw, subw) + +DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) +DEFINE_LIFTER(c_li, DECODE_RD_RS_IMM_NO_RS, DUP(imm)) + +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_IMM, JMP(imm)) +DEFINE_LIFTER_FOR_JUMP(c_jal, DECODE_RD_IMM, UN(analysis->bits, current_addr + size), JMP(imm)) +DEFINE_ALIAS_LIFTER(c_jr, jalr) + +DEFINE_ALIAS_LIFTER(c_jalr, jalr) +DEFINE_ALIAS_LIFTER(c_ebreak, ebreak) + +DEFINE_ALIAS_LIFTER(c_lui, lui) + +DEFINE_ALIAS_LIFTER(c_sw, sw) +DEFINE_ALIAS_LIFTER(c_swsp, sw) + +DEFINE_ALIAS_LIFTER(c_sd, sd) +DEFINE_ALIAS_LIFTER(c_sdsp, sd) + +DEFINE_ALIAS_LIFTER(c_lwsp, lw) +DEFINE_ALIAS_LIFTER(c_lw, lw) + +DEFINE_ALIAS_LIFTER(c_ld, ld) +DEFINE_ALIAS_LIFTER(c_ldsp, ld) + +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_beqz, DECODE_RS_RS_IMM_NO_RS2, BRANCH(EQ(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_bnez, DECODE_RS_RS_IMM_NO_RS2, BRANCH(NE(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) + +#include + diff --git a/librz/arch/isa/riscv/riscv_il_compressed.h b/librz/arch/isa/riscv/riscv_il_compressed.h index 955a112a31f..f998f4acc5f 100644 --- a/librz/arch/isa/riscv/riscv_il_compressed.h +++ b/librz/arch/isa/riscv/riscv_il_compressed.h @@ -4,68 +4,47 @@ #ifndef RISCV_IL_COMPRESSED_H #define RISCV_IL_COMPRESSED_H -#include "riscv/riscv_il_base.h" -#include "riscv_il_integer.h" -#include "rz_util/rz_buf.h" - -#include - -// Compressed instruction decoder variants that suppress operands not consumed by the lifter -#define DECODE_RD_RS_IMM_NO_RS(analysis, insn) \ - DECODE_RD_RS_IMM(analysis, insn) \ - (void)(rs); - -#define DECODE_RD_IMM_NO_RD(analysis, insn) \ - DECODE_RD_IMM(analysis, insn) \ - (void)(rd); - -#define DECODE_RS_RS_IMM_NO_RS2(analysis, insn) \ - DECODE_RS_RS_IMM(analysis, insn) \ - (void)(rs2); - -DEFINE_ALIAS_LIFTER(c_addi, addi) -DEFINE_ALIAS_LIFTER(c_addi16sp, addi) -DEFINE_ALIAS_LIFTER(c_addi4spn, addi) -DEFINE_ALIAS_LIFTER(c_add, add) -DEFINE_ALIAS_LIFTER(c_slli, slli) -DEFINE_ALIAS_LIFTER(c_andi, andi) -DEFINE_ALIAS_LIFTER(c_srli, srli) -DEFINE_ALIAS_LIFTER(c_srai, srai) -DEFINE_ALIAS_LIFTER(c_or, or) -DEFINE_ALIAS_LIFTER(c_sub, sub) -DEFINE_ALIAS_LIFTER(c_and, and) -DEFINE_ALIAS_LIFTER(c_xor, xor) -DEFINE_ALIAS_LIFTER(c_addw, addw) - -DEFINE_ALIAS_LIFTER(c_addiw, addiw) - -DEFINE_ALIAS_LIFTER(c_subw, subw) - -DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) -DEFINE_LIFTER(c_li, DECODE_RD_RS_IMM_NO_RS, DUP(imm)) - -DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_RD_IMM_NO_RD, JMP(imm)) -DEFINE_ALIAS_LIFTER(c_jr, jalr) - -DEFINE_ALIAS_LIFTER(c_jalr, jalr) - -DEFINE_ALIAS_LIFTER(c_lui, lui) - -DEFINE_ALIAS_LIFTER(c_sw, sw) -DEFINE_ALIAS_LIFTER(c_swsp, sw) - -DEFINE_ALIAS_LIFTER(c_sd, sd) -DEFINE_ALIAS_LIFTER(c_sdsp, sd) - -DEFINE_ALIAS_LIFTER(c_lwsp, lw) -DEFINE_ALIAS_LIFTER(c_lw, lw) - -DEFINE_ALIAS_LIFTER(c_ld, ld) -DEFINE_ALIAS_LIFTER(c_ldsp, ld) - -DEFINE_LIFTER_FOR_BRANCH(c_beqz, DECODE_RS_RS_IMM_NO_RS2, EQ(rs1, UN(analysis->bits, 0))) -DEFINE_LIFTER_FOR_BRANCH(c_bnez, DECODE_RS_RS_IMM_NO_RS2, NE(rs1, UN(analysis->bits, 0))) - -#include +#include "riscv_il.h" + +#define DECL_LIFTER(name) \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) + +DECL_LIFTER(c_nop); +DECL_LIFTER(c_addi); +DECL_LIFTER(c_addi16sp); +DECL_LIFTER(c_addi4spn); +DECL_LIFTER(c_add); +DECL_LIFTER(c_andi); +DECL_LIFTER(c_slli); +DECL_LIFTER(c_srli); +DECL_LIFTER(c_srai); +DECL_LIFTER(c_or); +DECL_LIFTER(c_sub); +DECL_LIFTER(c_and); +DECL_LIFTER(c_xor); +DECL_LIFTER(c_addw); +DECL_LIFTER(c_addiw); +DECL_LIFTER(c_subw); +DECL_LIFTER(c_mv); +DECL_LIFTER(c_li); +DECL_LIFTER(c_jal); +DECL_LIFTER(c_j); +DECL_LIFTER(c_jr); +DECL_LIFTER(c_ebreak); +DECL_LIFTER(c_jalr); +DECL_LIFTER(c_lui); +DECL_LIFTER(c_sw); +DECL_LIFTER(c_swsp); +DECL_LIFTER(c_sd); +DECL_LIFTER(c_sdsp); +DECL_LIFTER(c_lwsp); +DECL_LIFTER(c_lw); +DECL_LIFTER(c_ld); +DECL_LIFTER(c_ldsp); +DECL_LIFTER(c_beqz); +DECL_LIFTER(c_bnez); + +#undef DECL_LIFTER #endif // RISCV_IL_COMPRESSED_H diff --git a/librz/arch/isa/riscv/riscv_il_integer.c b/librz/arch/isa/riscv/riscv_il_integer.c new file mode 100644 index 00000000000..da2cf589f65 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_integer.c @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#include "riscv_il_integer.h" + +#include "analysis_private.h" +#include "capstone.h" + +#include "riscv_il_base.h" + +#include + +DEFINE_LIFTER(addi, DECODE_RD_RS_IMM, ADD(rs, imm)) +DEFINE_LIFTER(slli, DECODE_RD_RS_IMM, SHIFTL0(rs, imm)) +DEFINE_LIFTER(andi, DECODE_RD_RS_IMM, LOGAND(rs, imm)) +DEFINE_LIFTER(ori, DECODE_RD_RS_IMM, LOGOR(rs, imm)) +DEFINE_LIFTER(xori, DECODE_RD_RS_IMM, LOGXOR(rs, imm)) +DEFINE_LIFTER(slti, DECODE_RD_RS_IMM, BOOL_TO_BV(SLT(rs, imm), analysis->bits)) +DEFINE_LIFTER(sltiu, DECODE_RD_RS_IMM, BOOL_TO_BV(ULT(rs, imm), analysis->bits)) +DEFINE_LIFTER(srli, DECODE_RD_RS_IMM, SHIFTR0(rs, imm)) +DEFINE_LIFTER(srai, DECODE_RD_RS_IMM, SHIFTRA(rs, imm)) + +DEFINE_LIFTER(add, DECODE_RD_RS_RS, ADD(rs1, rs2)) +DEFINE_LIFTER(sub, DECODE_RD_RS_RS, SUB(rs1, rs2)) +DEFINE_LIFTER(and, DECODE_RD_RS_RS, LOGAND(rs1, rs2)) +DEFINE_LIFTER(or, DECODE_RD_RS_RS, LOGOR(rs1, rs2)) +DEFINE_LIFTER(xor, DECODE_RD_RS_RS, LOGXOR(rs1, rs2)) +DEFINE_LIFTER(slt, DECODE_RD_RS_RS, BOOL_TO_BV(SLT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sltu, DECODE_RD_RS_RS, BOOL_TO_BV(ULT(rs1, rs2), analysis->bits)) +DEFINE_LIFTER(sll, DECODE_RD_RS_RS, SHIFTL0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) +DEFINE_LIFTER(srl, DECODE_RD_RS_RS, SHIFTR0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) +DEFINE_LIFTER(sra, DECODE_RD_RS_RS, SHIFTRA(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) + +#define DEFINE_LIFTER_FOR_BRANCH(name, decoder, condition) \ + DEFINE_LIFTER_FOR_ONEWAY_JUMP(name, decoder, BRANCH(condition, JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) + +DEFINE_LIFTER_FOR_BRANCH(beq, DECODE_RS_RS_IMM, EQ(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bne, DECODE_RS_RS_IMM, NE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(blt, DECODE_RS_RS_IMM, SLT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bge, DECODE_RS_RS_IMM, SGE(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bltu, DECODE_RS_RS_IMM, ULT(rs1, rs2)) +DEFINE_LIFTER_FOR_BRANCH(bgeu, DECODE_RS_RS_IMM, UGE(rs1, rs2)) + +DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(imm)) + +DEFINE_LIFTER_FOR_JUMP(jalr, DECODE_RD_RS_IMM, + /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), + /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) + +// Intentional: on RV32 imm is already 32-bit and the result needs no sign-extension, +// so CAST(32) and SIGNED(32) would both be no-ops; on RV64 CAST(32) truncates imm and SIGNED(64) +// sign-extends the shifted 32-bit result to XLEN. +DEFINE_LIFTER(lui, DECODE_RD_IMM, + analysis->bits == 32 + ? SHIFTL0(imm, UN(32, 12)) + : SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12)))) +DEFINE_LIFTER(auipc, DECODE_RD_IMM, + ADD(UN(analysis->bits, current_addr), + analysis->bits == 32 + ? SHIFTL0(imm, UN(32, 12)) + : SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12))))) + +DEFINE_LIFTER_WITH_EFFECT(sb, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(8, IL_FALSE, rs1))) +DEFINE_LIFTER_WITH_EFFECT(sh, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(16, IL_FALSE, rs1))) +// Intentional: on RV32 rs1 is already 32-bit so CAST(32) would be a redundant no-op; +// on RV64 it is needed to truncate the 64-bit register value to 32 bits before storing. +DEFINE_LIFTER_WITH_EFFECT(sw, DECODE_RS_RS_IMM_MEM, + analysis->bits == 32 + ? STOREW(ADD(rs2, imm), rs1) + : STOREW(ADD(rs2, imm), CAST(32, IL_FALSE, rs1))) +DEFINE_LIFTER_WITH_EFFECT(sd, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), rs1)) + +DEFINE_LIFTER(lw, DECODE_RD_RS_IMM_MEM, analysis->bits == 32 ? LOADW(32, ADD(rs, imm)) : SIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) +DEFINE_LIFTER(lb, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lh, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) +DEFINE_LIFTER(lbu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) +DEFINE_LIFTER(lhu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) +DEFINE_LIFTER(ld, DECODE_RD_RS_IMM_MEM, LOADW(64, ADD(rs, imm))) + +DEFINE_LIFTER_WITH_EFFECT(fence, DECODE_NONE, NOP()) +DEFINE_LIFTER_WITH_EFFECT(fence_i, DECODE_NONE, NOP()) + +DEFINE_LIFTER(addw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, ADD(rs1, rs2))) +DEFINE_LIFTER(subw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SUB(rs1, rs2))) +DEFINE_LIFTER(sllw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(srlw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(sraw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs1, LOGAND(rs2, UN(32, 31))))) +DEFINE_LIFTER(addiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, ADD(rs, imm))) +DEFINE_LIFTER(slliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs, imm))) +DEFINE_LIFTER(srliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs, imm))) +DEFINE_LIFTER(sraiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs, imm))) + +// RV64I: load word unsigned (zero-extend 32-bit load to XLEN) +DEFINE_LIFTER(lwu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) + +// System: environment call / breakpoint (trap to OS / debugger) +DEFINE_LIFTER_WITH_EFFECT(ecall, DECODE_NONE, GOTO("ecall")) +DEFINE_LIFTER_WITH_EFFECT(ebreak, DECODE_NONE, GOTO("ebreak")) + +#include diff --git a/librz/arch/isa/riscv/riscv_il_integer.h b/librz/arch/isa/riscv/riscv_il_integer.h index 6159636594f..135531f057a 100644 --- a/librz/arch/isa/riscv/riscv_il_integer.h +++ b/librz/arch/isa/riscv/riscv_il_integer.h @@ -4,96 +4,75 @@ #ifndef RISCV_IL_INTEGER_H #define RISCV_IL_INTEGER_H -#include "analysis_private.h" -#include "capstone.h" -#include "riscv_il_base.h" - -#include - -DEFINE_LIFTER(addi, DECODE_RD_RS_IMM, ADD(rs, imm)) -DEFINE_LIFTER(slli, DECODE_RD_RS_IMM, SHIFTL0(rs, imm)) -DEFINE_LIFTER(andi, DECODE_RD_RS_IMM, LOGAND(rs, imm)) -DEFINE_LIFTER(ori, DECODE_RD_RS_IMM, LOGOR(rs, imm)) -DEFINE_LIFTER(xori, DECODE_RD_RS_IMM, LOGXOR(rs, imm)) -DEFINE_LIFTER(slti, DECODE_RD_RS_IMM, BOOL_TO_BV(SLT(rs, imm), analysis->bits)) -DEFINE_LIFTER(sltiu, DECODE_RD_RS_IMM, BOOL_TO_BV(ULT(rs, imm), analysis->bits)) -DEFINE_LIFTER(srli, DECODE_RD_RS_IMM, SHIFTR0(rs, imm)) -DEFINE_LIFTER(srai, DECODE_RD_RS_IMM, SHIFTRA(rs, imm)) - -DEFINE_LIFTER(add, DECODE_RD_RS_RS, ADD(rs1, rs2)) -DEFINE_LIFTER(sub, DECODE_RD_RS_RS, SUB(rs1, rs2)) -DEFINE_LIFTER(and, DECODE_RD_RS_RS, LOGAND(rs1, rs2)) -DEFINE_LIFTER(or, DECODE_RD_RS_RS, LOGOR(rs1, rs2)) -DEFINE_LIFTER(xor, DECODE_RD_RS_RS, LOGXOR(rs1, rs2)) -DEFINE_LIFTER(slt, DECODE_RD_RS_RS, BOOL_TO_BV(SLT(rs1, rs2), analysis->bits)) -DEFINE_LIFTER(sltu, DECODE_RD_RS_RS, BOOL_TO_BV(ULT(rs1, rs2), analysis->bits)) -DEFINE_LIFTER(sll, DECODE_RD_RS_RS, SHIFTL0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) -DEFINE_LIFTER(srl, DECODE_RD_RS_RS, SHIFTR0(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) -DEFINE_LIFTER(sra, DECODE_RD_RS_RS, SHIFTRA(rs1, LOGAND(rs2, UN(analysis->bits, analysis->bits - 1)))) - -#define DEFINE_LIFTER_FOR_BRANCH(name, decoder, condition) \ - DEFINE_LIFTER_FOR_ONEWAY_JUMP(name, decoder, BRANCH(condition, JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) - -DEFINE_LIFTER_FOR_BRANCH(beq, DECODE_RS_RS_IMM, EQ(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bne, DECODE_RS_RS_IMM, NE(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(blt, DECODE_RS_RS_IMM, SLT(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bge, DECODE_RS_RS_IMM, SGE(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bltu, DECODE_RS_RS_IMM, ULT(rs1, rs2)) -DEFINE_LIFTER_FOR_BRANCH(bgeu, DECODE_RS_RS_IMM, UGE(rs1, rs2)) - -DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, - /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), - /*GOTO ADDR*/ JMP(imm)) - -DEFINE_LIFTER_FOR_JUMP(jalr, DECODE_RD_RS_IMM, - /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), - /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) - -// Intentional: on RV32 imm is already 32-bit and the result needs no sign-extension, -// so CAST(32) and SIGNED(32) would both be no-ops; on RV64 CAST(32) truncates imm and SIGNED(64) -// sign-extends the shifted 32-bit result to XLEN. -DEFINE_LIFTER(lui, DECODE_RD_IMM, - analysis->bits == 32 - ? SHIFTL0(imm, UN(32, 12)) - : SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12)))) -DEFINE_LIFTER(auipc, DECODE_RD_IMM, ADD(UN(analysis->bits, current_addr), SIGNED(analysis->bits, SHIFTL0(CAST(32, IL_FALSE, imm), UN(32, 12))))) - -DEFINE_LIFTER_WITH_EFFECT(sb, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(8, IL_FALSE, rs1))) -DEFINE_LIFTER_WITH_EFFECT(sh, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), CAST(16, IL_FALSE, rs1))) -// Intentional: on RV32 rs1 is already 32-bit so CAST(32) would be a redundant no-op; -// on RV64 it is needed to truncate the 64-bit register value to 32 bits before storing. -DEFINE_LIFTER_WITH_EFFECT(sw, DECODE_RS_RS_IMM_MEM, - analysis->bits == 32 - ? STOREW(ADD(rs2, imm), rs1) - : STOREW(ADD(rs2, imm), CAST(32, IL_FALSE, rs1))) -DEFINE_LIFTER_WITH_EFFECT(sd, DECODE_RS_RS_IMM_MEM, STOREW(ADD(rs2, imm), rs1)) - -DEFINE_LIFTER(lw, DECODE_RD_RS_IMM_MEM, analysis->bits == 32 ? LOADW(32, ADD(rs, imm)) : SIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) -DEFINE_LIFTER(lb, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) -DEFINE_LIFTER(lh, DECODE_RD_RS_IMM_MEM, SIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) -DEFINE_LIFTER(lbu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(8, ADD(rs, imm)))) -DEFINE_LIFTER(lhu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(16, ADD(rs, imm)))) -DEFINE_LIFTER(ld, DECODE_RD_RS_IMM_MEM, LOADW(64, ADD(rs, imm))) - -TWICE_FOR(fence, fence_i, - DEFINE_LIFTER_WITH_EFFECT, DECODE_NONE, NOP()) - -DEFINE_LIFTER(addw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, ADD(rs1, rs2))) -DEFINE_LIFTER(subw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SUB(rs1, rs2))) -DEFINE_LIFTER(sllw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs1, LOGAND(rs2, UN(32, 31))))) -DEFINE_LIFTER(srlw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs1, LOGAND(rs2, UN(32, 31))))) -DEFINE_LIFTER(sraw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs1, LOGAND(rs2, UN(32, 31))))) -DEFINE_LIFTER(addiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, ADD(rs, imm))) -DEFINE_LIFTER(slliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTL0(rs, imm))) -DEFINE_LIFTER(srliw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTR0(rs, imm))) -DEFINE_LIFTER(sraiw, DECODE_RD_RS_IMM_TRUNCATE32, SIGNED(analysis->bits, SHIFTRA(rs, imm))) - -// RV64I: load word unsigned (zero-extend 32-bit load to XLEN) -DEFINE_LIFTER(lwu, DECODE_RD_RS_IMM_MEM, UNSIGNED(analysis->bits, LOADW(32, ADD(rs, imm)))) - -// System: environment call (trap to OS / hypervisor) -DEFINE_LIFTER_WITH_EFFECT(ecall, DECODE_NONE, GOTO("ecall")) - -#include - -#endif // RISCV_IL_INTEGER_H \ No newline at end of file +#include "riscv_il.h" + +#define DECL_LIFTER(name) \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) + +DECL_LIFTER(addi); +DECL_LIFTER(slli); +DECL_LIFTER(andi); +DECL_LIFTER(ori); +DECL_LIFTER(xori); +DECL_LIFTER(slti); +DECL_LIFTER(sltiu); +DECL_LIFTER(srli); +DECL_LIFTER(srai); + +DECL_LIFTER(add); +DECL_LIFTER(sub); +DECL_LIFTER(and); +DECL_LIFTER(or); +DECL_LIFTER(xor); +DECL_LIFTER(slt); +DECL_LIFTER(sltu); +DECL_LIFTER(sll); +DECL_LIFTER(srl); +DECL_LIFTER(sra); + +DECL_LIFTER(beq); +DECL_LIFTER(bne); +DECL_LIFTER(blt); +DECL_LIFTER(bge); +DECL_LIFTER(bltu); +DECL_LIFTER(bgeu); + +DECL_LIFTER(jal); +DECL_LIFTER(jalr); + +DECL_LIFTER(lui); +DECL_LIFTER(auipc); + +DECL_LIFTER(sb); +DECL_LIFTER(sh); +DECL_LIFTER(sw); +DECL_LIFTER(sd); + +DECL_LIFTER(lw); +DECL_LIFTER(lb); +DECL_LIFTER(lh); +DECL_LIFTER(lbu); +DECL_LIFTER(lhu); +DECL_LIFTER(ld); + +DECL_LIFTER(fence); +DECL_LIFTER(fence_i); + +DECL_LIFTER(addw); +DECL_LIFTER(subw); +DECL_LIFTER(sllw); +DECL_LIFTER(srlw); +DECL_LIFTER(sraw); +DECL_LIFTER(addiw); +DECL_LIFTER(slliw); +DECL_LIFTER(srliw); +DECL_LIFTER(sraiw); + +DECL_LIFTER(lwu); +DECL_LIFTER(ecall); +DECL_LIFTER(ebreak); + +#undef DECL_LIFTER + +#endif // RISCV_IL_INTEGER_H diff --git a/librz/arch/isa/riscv/riscv_il_integer_reg_names.h b/librz/arch/isa/riscv/riscv_il_integer_reg_names.h index 80cadb58790..7206899e17a 100644 --- a/librz/arch/isa/riscv/riscv_il_integer_reg_names.h +++ b/librz/arch/isa/riscv/riscv_il_integer_reg_names.h @@ -44,7 +44,8 @@ static const char *riscv_integer_reg_names[] = { static inline const char *riscv_integer_reg_name(uint32_t reg) { int idx = (int)reg - RISCV_REG_X0; - if (idx < 0 || idx >= 32) { + if (idx < 0 || idx >= RZ_ARRAY_SIZE(riscv_integer_reg_names)) { + RZ_LOG_ERROR("Invalid RISC-V integer register index %d, returning empty str\n", idx); return ""; } return riscv_integer_reg_names[idx]; diff --git a/librz/arch/isa/riscv/riscv_il_m.c b/librz/arch/isa/riscv/riscv_il_m.c new file mode 100644 index 00000000000..34e6199bbd1 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_m.c @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#include "riscv_il_m.h" + +#include "analysis_private.h" + +#include "riscv_il_base.h" + +#include + +// M extension: multiply/divide/remainder (RV32M / RV64M) + +// RV32M +DEFINE_LIFTER(mul, DECODE_RD_RS_RS, MUL(rs1, rs2)) +DEFINE_LIFTER(mulh, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(SIGNED(analysis->bits * 2, rs1), SIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) +DEFINE_LIFTER(mulhsu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(SIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) +DEFINE_LIFTER(mulhu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(UNSIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) +DEFINE_LIFTER(div, DECODE_RD_RS_RS, SDIV(rs1, rs2)) +DEFINE_LIFTER(divu, DECODE_RD_RS_RS, DIV(rs1, rs2)) +DEFINE_LIFTER(rem, DECODE_RD_RS_RS, SMOD(rs1, rs2)) +DEFINE_LIFTER(remu, DECODE_RD_RS_RS, MOD(rs1, rs2)) + +// RV64M: *w instructions operate on lower 32 bits, result sign-extended to 64 bits +DEFINE_LIFTER(mulw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MUL(rs1, rs2))) +DEFINE_LIFTER(divw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SDIV(rs1, rs2))) +DEFINE_LIFTER(divuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, DIV(rs1, rs2))) +DEFINE_LIFTER(remw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SMOD(rs1, rs2))) +DEFINE_LIFTER(remuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MOD(rs1, rs2))) + +#include diff --git a/librz/arch/isa/riscv/riscv_il_m.h b/librz/arch/isa/riscv/riscv_il_m.h index e3f666f6a44..7e0d66dca00 100644 --- a/librz/arch/isa/riscv/riscv_il_m.h +++ b/librz/arch/isa/riscv/riscv_il_m.h @@ -4,18 +4,26 @@ #ifndef RISCV_IL_M_H #define RISCV_IL_M_H -#include "riscv_il_base.h" +#include "riscv_il.h" -#include +#define DECL_LIFTER(name) \ + RzILOpEffect *rz_riscv_lift_##name(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, \ + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) -// M extension: multiply/divide/remainder (RV32M / RV64M) -DEFINE_LIFTER(mul, DECODE_RD_RS_RS, MUL(rs1, rs2)) -DEFINE_LIFTER(mulhu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(UNSIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) -DEFINE_LIFTER(divu, DECODE_RD_RS_RS, DIV(rs1, rs2)) -DEFINE_LIFTER(remu, DECODE_RD_RS_RS, MOD(rs1, rs2)) -// RV64M: unsigned remainder of 32-bit operands, result sign-extended to 64 bits -DEFINE_LIFTER(remuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MOD(rs1, rs2))) +DECL_LIFTER(mul); +DECL_LIFTER(mulh); +DECL_LIFTER(mulhsu); +DECL_LIFTER(mulhu); +DECL_LIFTER(div); +DECL_LIFTER(divu); +DECL_LIFTER(rem); +DECL_LIFTER(remu); +DECL_LIFTER(mulw); +DECL_LIFTER(divw); +DECL_LIFTER(divuw); +DECL_LIFTER(remw); +DECL_LIFTER(remuw); -#include +#undef DECL_LIFTER #endif // RISCV_IL_M_H diff --git a/librz/arch/meson.build b/librz/arch/meson.build index acbc825e2ef..4795b24e76d 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -303,6 +303,9 @@ arch_isa_sources = [ 'isa/pyc/opcode_arg_fmt.c', 'isa/pyc/pyc_dis.c', 'isa/riscv/riscv_il.c', + 'isa/riscv/riscv_il_integer.c', + 'isa/riscv/riscv_il_m.c', + 'isa/riscv/riscv_il_compressed.c', 'isa/rl78/rl78.c', 'isa/rl78/rl78_instr.c', 'isa/rl78/rl78_maps.c', From f93145279814bb00cb2dd111f84cc8bcc1b28424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Fri, 26 Jun 2026 03:14:25 +0300 Subject: [PATCH 06/10] add tests for 64-bit --- librz/arch/isa/riscv/riscv_il_compressed.c | 4 +- test/db/asm/riscv_32 | 2 +- test/db/asm/riscv_64 | 201 +++++++++++++++++++++ 3 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 test/db/asm/riscv_64 diff --git a/librz/arch/isa/riscv/riscv_il_compressed.c b/librz/arch/isa/riscv/riscv_il_compressed.c index c8127570c51..8d8a0c67a61 100644 --- a/librz/arch/isa/riscv/riscv_il_compressed.c +++ b/librz/arch/isa/riscv/riscv_il_compressed.c @@ -45,8 +45,8 @@ DEFINE_ALIAS_LIFTER(c_subw, subw) DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) DEFINE_LIFTER(c_li, DECODE_RD_RS_IMM_NO_RS, DUP(imm)) -DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_j, DECODE_IMM, JMP(imm)) -DEFINE_LIFTER_FOR_JUMP(c_jal, DECODE_RD_IMM, UN(analysis->bits, current_addr + size), JMP(imm)) +DEFINE_ALIAS_LIFTER(c_j, jal) +DEFINE_ALIAS_LIFTER(c_jal, jal) DEFINE_ALIAS_LIFTER(c_jr, jalr) DEFINE_ALIAS_LIFTER(c_jalr, jalr) diff --git a/test/db/asm/riscv_32 b/test/db/asm/riscv_32 index 87831e4ba54..d2036956000 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -132,7 +132,7 @@ d "li a3, 0" 8146 0x100 (set a3 (bv 32 0x0)) d "li t1, 0" 0143 0x100 (set t1 (bv 32 0x0)) d "li a2, 0" 0146 0x100 (set a2 (bv 32 0x0)) d "li a0, 0" 0145 0x100 (set a0 (bv 32 0x0)) -d "j 0x176" 25a8 0x13e (jmp (bv 32 0x176)) +d "j 0x176" 25a8 0x13e (seq nop (jmp (bv 32 0x176))) d "mul a4, a0, a2" 3307c502 0x140 (set a4 (* (var a0) (var a2))) d "mulhu t1, a2, a2" 3333c602 0x140 (set t1 (cast 32 false (>> (* (cast 64 false (var a2)) (cast 64 false (var a2))) (bv 8 0x20) false))) d "slli a4, a4, 1" 0607 0x140 (set a4 (<< (var a4) (bv 32 0x1) false)) diff --git a/test/db/asm/riscv_64 b/test/db/asm/riscv_64 new file mode 100644 index 00000000000..d13c2a527dc --- /dev/null +++ b/test/db/asm/riscv_64 @@ -0,0 +1,201 @@ +# ----------------------------- C_ADDI16SP ----------------------------- +d "addi sp, sp, -0x90" 7571 0x0 (set sp (+ (var sp) (bv 64 0xffffffffffffff70))) +# ----------------------------- ADDI ----------------------------- +d "addi a1, a1, 0x700" 93850570 0x0 (set a1 (+ (var a1) (bv 64 0x700))) +# ----------------------------- C_ADDI4SPN ----------------------------- +d "addi s0, sp, 0x80" 0001 0x0 (set s0 (+ (var sp) (bv 64 0x80))) +# ----------------------------- C_ADDI --------------------------------- +d "addi sp, sp, -0x20" 0111 0x0 (set sp (+ (var sp) (bv 64 0xffffffffffffffe0))) +d "lui a5, 0x10" c167 0x0 (set a5 (cast 64 (msb (<< (cast 32 false (bv 64 0x10)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x10)) (bv 32 0xc) false))) +d "sw a5, 0x1c(sp)" 3ece 0x0 (storew 0 (+ (var sp) (bv 64 0x1c)) (cast 32 false (var a5))) +d "lui a5, 0x30" b7070300 0x0 (set a5 (cast 64 (msb (<< (cast 32 false (bv 64 0x30)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x30)) (bv 32 0xc) false))) +d "sw a5, 0x24(sp)" 3ed2 0x0 (storew 0 (+ (var sp) (bv 64 0x24)) (cast 32 false (var a5))) +d "lui a5, 0xc" b167 0x0 (set a5 (cast 64 (msb (<< (cast 32 false (bv 64 0xc)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0xc)) (bv 32 0xc) false))) +d "sw a5, 0x3c(sp)" 3ede 0x0 (storew 0 (+ (var sp) (bv 64 0x3c)) (cast 32 false (var a5))) +d "lui a5, 0xffff8" e177 0x0 (set a5 (cast 64 (msb (<< (cast 32 false (bv 64 0xffff8)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0xffff8)) (bv 32 0xc) false))) +d "sw s1, 0x84(sp)" 26c3 0x0 (storew 0 (+ (var sp) (bv 64 0x84)) (cast 32 false (var s1))) +d "sw ra, 0x8c(sp)" 06c7 0x0 (storew 0 (+ (var sp) (bv 64 0x8c)) (cast 32 false (var ra))) +d "sw s0, 0x88(sp)" 22c5 0x0 (storew 0 (+ (var sp) (bv 64 0x88)) (cast 32 false (var s0))) +d "sw s2, 0x80(sp)" 4ac1 0x0 (storew 0 (+ (var sp) (bv 64 0x80)) (cast 32 false (var s2))) +d "sw s3, 0x7c(sp)" cede 0x0 (storew 0 (+ (var sp) (bv 64 0x7c)) (cast 32 false (var s3))) +d "sw s4, 0x78(sp)" d2dc 0x0 (storew 0 (+ (var sp) (bv 64 0x78)) (cast 32 false (var s4))) +d "sw s5, 0x74(sp)" d6da 0x0 (storew 0 (+ (var sp) (bv 64 0x74)) (cast 32 false (var s5))) +d "sw s6, 0x70(sp)" dad8 0x0 (storew 0 (+ (var sp) (bv 64 0x70)) (cast 32 false (var s6))) +d "sw s7, 0x6c(sp)" ded6 0x0 (storew 0 (+ (var sp) (bv 64 0x6c)) (cast 32 false (var s7))) +d "sw s8, 0x68(sp)" e2d4 0x0 (storew 0 (+ (var sp) (bv 64 0x68)) (cast 32 false (var s8))) +d "sw s9, 0x64(sp)" e6d2 0x0 (storew 0 (+ (var sp) (bv 64 0x64)) (cast 32 false (var s9))) +d "sw s10, 0x60(sp)" ead0 0x0 (storew 0 (+ (var sp) (bv 64 0x60)) (cast 32 false (var s10))) +d "sw s11, 0x5c(sp)" eece 0x0 (storew 0 (+ (var sp) (bv 64 0x5c)) (cast 32 false (var s11))) +d "sw zero, 0x28(sp)" 02d4 0x0 (storew 0 (+ (var sp) (bv 64 0x28)) (cast 32 false (bv 64 0x0))) +d "sw zero, 0x20(sp)" 02d0 0x0 (storew 0 (+ (var sp) (bv 64 0x20)) (cast 32 false (bv 64 0x0))) +d "sw zero, 0x38(sp)" 02dc 0x0 (storew 0 (+ (var sp) (bv 64 0x38)) (cast 32 false (bv 64 0x0))) +d "sw zero, 0x30(sp)" 02d8 0x0 (storew 0 (+ (var sp) (bv 64 0x30)) (cast 32 false (bv 64 0x0))) +d "sw a5, 0x34(sp)" 3eda 0x0 (storew 0 (+ (var sp) (bv 64 0x34)) (cast 32 false (var a5))) +d "sw zero, 0x18(sp)" 02cc 0x0 (storew 0 (+ (var sp) (bv 64 0x18)) (cast 32 false (bv 64 0x0))) +d "lui s1, 0x40" b7040400 0x38 (set s1 (cast 64 (msb (<< (cast 32 false (bv 64 0x40)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x40)) (bv 32 0xc) false))) +d "lui a5, 0x10013" b7370110 0x0 (set a5 (cast 64 (msb (<< (cast 32 false (bv 64 0x10013)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x10013)) (bv 32 0xc) false))) +d "lw a5, 4(a5)" dc43 0x40 (set a5 (cast 64 (msb (loadw 0 32 (+ (var a5) (bv 64 0x4)))) (loadw 0 32 (+ (var a5) (bv 64 0x4))))) +d "blez a5, 0x64" 6351f002 0x42 (branch (|| (! (sle (bv 64 0x0) (var a5))) (== (bv 64 0x0) (var a5))) (jmp (bv 64 0x64)) (jmp (bv 64 0x46))) +d "lw ra, 0x8c(sp)" ba40 0x40 (set ra (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x8c)))) (loadw 0 32 (+ (var sp) (bv 64 0x8c))))) +d "lw s0, 0x88(sp)" 2a44 0x40 (set s0 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x88)))) (loadw 0 32 (+ (var sp) (bv 64 0x88))))) +d "lw s1, 0x84(sp)" 9a44 0x40 (set s1 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x84)))) (loadw 0 32 (+ (var sp) (bv 64 0x84))))) +d "lw s2, 0x80(sp)" 0a49 0x40 (set s2 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x80)))) (loadw 0 32 (+ (var sp) (bv 64 0x80))))) +d "lw s3, 0x7c(sp)" f659 0x40 (set s3 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x7c)))) (loadw 0 32 (+ (var sp) (bv 64 0x7c))))) +d "lw s4, 0x78(sp)" 665a 0x44 (set s4 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x78)))) (loadw 0 32 (+ (var sp) (bv 64 0x78))))) +d "lw s5, 0x74(sp)" d65a 0x48 (set s5 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x74)))) (loadw 0 32 (+ (var sp) (bv 64 0x74))))) +d "lw s6, 0x70(sp)" 465b 0x40 (set s6 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x70)))) (loadw 0 32 (+ (var sp) (bv 64 0x70))))) +d "lw s7, 0x6c(sp)" b65b 0x40 (set s7 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x6c)))) (loadw 0 32 (+ (var sp) (bv 64 0x6c))))) +d "lw s8, 0x68(sp)" 265c 0x40 (set s8 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x68)))) (loadw 0 32 (+ (var sp) (bv 64 0x68))))) +d "lw s9, 0x64(sp)" 965c 0x40 (set s9 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x64)))) (loadw 0 32 (+ (var sp) (bv 64 0x64))))) +d "lw s10, 0x60(sp)" 065d 0x40 (set s10 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x60)))) (loadw 0 32 (+ (var sp) (bv 64 0x60))))) +d "lw s11, 0x5c(sp)" f64d 0x40 (set s11 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x5c)))) (loadw 0 32 (+ (var sp) (bv 64 0x5c))))) +d "addi sp, sp, 0x90" 4961 0x40 (set sp (+ (var sp) (bv 64 0x90))) +d "ret" 8280 0x40 (seq nop (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "lw a5, 0x18(sp)" e247 0x40 (set a5 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x18)))) (loadw 0 32 (+ (var sp) (bv 64 0x18))))) +d "beqz a5, 0x2d8" 63890726 0x66 (branch (== (var a5) (bv 64 0x0)) (jmp (bv 64 0x2d8)) (jmp (bv 64 0x6a))) +d "lw s0, 0x1c(sp)" 7244 0x40 (set s0 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x1c)))) (loadw 0 32 (+ (var sp) (bv 64 0x1c))))) +d "lw a0, 0x24(sp)" 1255 0x40 (set a0 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x24)))) (loadw 0 32 (+ (var sp) (bv 64 0x24))))) +d "lw a6, 0x28(sp)" 2258 0x40 (set a6 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x28)))) (loadw 0 32 (+ (var sp) (bv 64 0x28))))) +d "lw t3, 0x38(sp)" 625e 0x40 (set t3 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x38)))) (loadw 0 32 (+ (var sp) (bv 64 0x38))))) +d "srai a5, s0, 0x1f" 9357f441 0x40 (set a5 (>> (var s0) (bv 64 0x1f) (msb (var s0)))) +d "lw a2, 0x20(sp)" 0256 0x40 (set a2 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x20)))) (loadw 0 32 (+ (var sp) (bv 64 0x20))))) +d "andi a5, a5, 0xf" bd8b 0x40 (set a5 (& (var a5) (bv 64 0xf))) +d "srai a4, a0, 0x1f" 1357f541 0x40 (set a4 (>> (var a0) (bv 64 0x1f) (msb (var a0)))) +d "lw a7, 0x30(sp)" c258 0x40 (set a7 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x30)))) (loadw 0 32 (+ (var sp) (bv 64 0x30))))) +d "add a3, a5, a6" b3860701 0x80 (set a3 (+ (var a5) (var a6))) +d "sub s2, t3, a6" 33090e41 0x80 (set s2 (- (var t3) (var a6))) +d "andi a4, a4, 0x3f" 1377f703 0x80 (set a4 (& (var a4) (bv 64 0x3f))) +d "lw a6, 0x34(sp)" 5258 0x80 (set a6 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x34)))) (loadw 0 32 (+ (var sp) (bv 64 0x34))))) +d "add a1, a4, a2" b305c700 0x80 (set a1 (+ (var a4) (var a2))) +d "sltu a4, a1, a4" 33b7e500 0x80 (set a4 (ite (&& (ule (var a1) (var a4)) (! (== (var a1) (var a4)))) (bv 64 0x1) (bv 64 0x0))) +d "sub a2, a7, a2" 3386c840 0x80 (set a2 (- (var a7) (var a2))) +d "sltu s7, a3, a5" b3bbf600 0x80 (set s7 (ite (&& (ule (var a3) (var a5)) (! (== (var a3) (var a5)))) (bv 64 0x1) (bv 64 0x0))) +d "sltu a7, a7, a2" b3b8c800 0x80 (set a7 (ite (&& (ule (var a7) (var a2)) (! (== (var a7) (var a2)))) (bv 64 0x1) (bv 64 0x0))) +d "add a5, a4, a0" b307a700 0x80 (set a5 (+ (var a4) (var a0))) +d "mv a4, a2" 3287 0x80 (set a4 (var a2)) +d "sub a2, a6, a0" 3306a840 0x80 (set a2 (- (var a6) (var a0))) +d "sltu a6, t3, s2" 33382e01 0x80 (set a6 (ite (&& (ule (var t3) (var s2)) (! (== (var t3) (var s2)))) (bv 64 0x1) (bv 64 0x0))) +d "lw t3, 0x3c(sp)" 725e 0x80 (set t3 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x3c)))) (loadw 0 32 (+ (var sp) (bv 64 0x3c))))) +d "mv t1, a0" 2a83 0x80 (set t1 (var a0)) +d "srli a1, a1, 6" 9981 0x80 (set a1 (>> (var a1) (bv 64 0x6) false)) +d "slli a0, a5, 0x1a" 1395a701 0x80 (set a0 (<< (var a5) (bv 64 0x1a) false)) +d "sw a4, 0x40(sp)" bac0 0x80 (storew 0 (+ (var sp) (bv 64 0x40)) (cast 32 false (var a4))) +d "sub a4, a2, a7" 33071641 0x80 (set a4 (- (var a2) (var a7))) +d "add s7, s7, s0" a29b 0xc0 (set s7 (+ (var s7) (var s0))) +d "sw a4, 0x44(sp)" bac2 0xc0 (storew 0 (+ (var sp) (bv 64 0x44)) (cast 32 false (var a4))) +d "srai a5, a5, 6" 9987 0xc0 (set a5 (>> (var a5) (bv 64 0x6) (msb (var a5)))) +d "or a4, a0, a1" 3367b500 0xc0 (set a4 (| (var a0) (var a1))) +d "slli s8, s7, 0x1c" 139ccb01 0xc0 (set s8 (<< (var s7) (bv 64 0x1c) false)) +d "sub s0, t3, s0" 33048e40 0xc0 (set s0 (- (var t3) (var s0))) +d "srli a3, a3, 4" 9182 0xc0 (set a3 (>> (var a3) (bv 64 0x4) false)) +d "sw a4, 0x10(sp)" 3ac8 0xc0 (storew 0 (+ (var sp) (bv 64 0x10)) (cast 32 false (var a4))) +d "sw a5, 0x14(sp)" 3eca 0xc0 (storew 0 (+ (var sp) (bv 64 0x14)) (cast 32 false (var a5))) +d "lui a4, 1" 0567 0xc0 (set a4 (cast 64 (msb (<< (cast 32 false (bv 64 0x1)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x1)) (bv 32 0xc) false))) +d "sub s0, s0, a6" 33040441 0xc0 (set s0 (- (var s0) (var a6))) +d "or s8, s8, a3" 336cdc00 0xc0 (set s8 (| (var s8) (var a3))) +d "srai s7, s7, 4" 93db4b40 0xc0 (set s7 (>> (var s7) (bv 64 0x4) (msb (var s7)))) +d "blt t1, a4, 0x2d4" 6347e31e 0xe6 (branch (&& (sle (var t1) (var a4)) (! (== (var t1) (var a4)))) (jmp (bv 64 0x2d4)) (jmp (bv 64 0xea))) +d "lw a5, 0x1c(sp)" f247 0xc0 (set a5 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x1c)))) (loadw 0 32 (+ (var sp) (bv 64 0x1c))))) +d "lui a4, 1" 0567 0xc0 (set a4 (cast 64 (msb (<< (cast 32 false (bv 64 0x1)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x1)) (bv 32 0xc) false))) +d "blt a5, a4, 0x2d4" 63c3e71e 0xee (branch (&& (sle (var a5) (var a4)) (! (== (var a5) (var a4)))) (jmp (bv 64 0x2d4)) (jmp (bv 64 0xf2))) +d "srli a5, s8, 0x1d" 9357dc01 0xc0 (set a5 (>> (var s8) (bv 64 0x1d) false)) +d "slli a4, s7, 3" 13973b00 0xc0 (set a4 (<< (var s7) (bv 64 0x3) false)) +d "or a5, a5, a4" d98f 0xc0 (set a5 (| (var a5) (var a4))) +d "sw a5, 0x4c(sp)" bec6 0xc0 (storew 0 (+ (var sp) (bv 64 0x4c)) (cast 32 false (var a5))) +d "slli a5, s8, 3" 93173c00 0xc0 (set a5 (<< (var s8) (bv 64 0x3) false)) +d "addi a5, sp, 8" 3c00 0x100 (set a5 (+ (var sp) (bv 64 0x8))) +d "li s11, 0xff" 930df00f 0x100 (set s11 (+ (bv 64 0x0) (bv 64 0xff))) +d "sw a5, 0x48(sp)" bec4 0x100 (storew 0 (+ (var sp) (bv 64 0x48)) (cast 32 false (var a5))) +d "sw s2, 0xc(sp)" 4ac6 0x100 (storew 0 (+ (var sp) (bv 64 0xc)) (cast 32 false (var s2))) +d "li a5, 4" 9147 0x100 (set a5 (bv 64 0x4)) +d "li s2, 0" 0149 0x100 (set s2 (bv 64 0x0)) +d "mv s3, s11" ee89 0x100 (set s3 (var s11)) +d "sw a5, 0x2c(sp)" 3ed6 0x100 (storew 0 (+ (var sp) (bv 64 0x2c)) (cast 32 false (var a5))) +d "li s6, 0x10" 414b 0x100 (set s6 (bv 64 0x10)) +d "li s9, 8" a14c 0x100 (set s9 (bv 64 0x8)) +d "mv s11, s2" ca8d 0x100 (set s11 (var s2)) +d "lw s10, 0x40(sp)" 064d 0x100 (set s10 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x40)))) (loadw 0 32 (+ (var sp) (bv 64 0x40))))) +d "lw s5, 0x44(sp)" 964a 0x100 (set s5 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x44)))) (loadw 0 32 (+ (var sp) (bv 64 0x44))))) +d "li s2, 0x80" 13090008 0x100 (set s2 (+ (bv 64 0x0) (bv 64 0x80))) +d "mv s4, s3" 4e8a 0x100 (set s4 (var s3)) +d "mv s3, s2" ca89 0x100 (set s3 (var s2)) +d "lw t2, 0xc(sp)" b243 0x100 (set t2 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0xc)))) (loadw 0 32 (+ (var sp) (bv 64 0xc))))) +d "mv t6, s0" a28f 0x100 (set t6 (var s0)) +d "li ra, 0" 8140 0x100 (set ra (bv 64 0x0)) +d "li s2, 0" 0149 0x100 (set s2 (bv 64 0x0)) +d "li a1, 0" 8145 0x100 (set a1 (bv 64 0x0)) +d "li a4, 0" 0147 0x100 (set a4 (bv 64 0x0)) +d "li t3, 0" 014e 0x100 (set t3 (bv 64 0x0)) +d "li a6, 0" 0148 0x100 (set a6 (bv 64 0x0)) +d "li a5, 0" 8147 0x100 (set a5 (bv 64 0x0)) +d "li a3, 0" 8146 0x100 (set a3 (bv 64 0x0)) +d "li t1, 0" 0143 0x100 (set t1 (bv 64 0x0)) +d "li a2, 0" 0146 0x100 (set a2 (bv 64 0x0)) +d "li a0, 0" 0145 0x100 (set a0 (bv 64 0x0)) +d "j 0x176" 25a8 0x13e (seq nop (jmp (bv 64 0x176))) +d "mul a4, a0, a2" 3307c502 0x140 (set a4 (* (var a0) (var a2))) +d "mulhu t1, a2, a2" 3333c602 0x140 (set t1 (cast 64 false (>> (* (cast 128 false (var a2)) (cast 128 false (var a2))) (bv 8 0x40) false))) +d "slli a4, a4, 1" 0607 0x140 (set a4 (<< (var a4) (bv 64 0x1) false)) +d "mul a7, a5, a6" b3880703 0x140 (set a7 (* (var a5) (var a6))) +d "add t1, t1, a4" 3a93 0x140 (set t1 (+ (var t1) (var a4))) +d "mul a3, a2, a2" b306c602 0x140 (set a3 (* (var a2) (var a2))) +d "slli a7, a7, 1" 8608 0x140 (set a7 (<< (var a7) (bv 64 0x1) false)) +d "mulhu t3, a6, a6" 333e0803 0x140 (set t3 (cast 64 false (>> (* (cast 128 false (var a6)) (cast 128 false (var a6))) (bv 8 0x40) false))) +d "mul a4, a6, a6" 33070803 0x140 (set a4 (* (var a6) (var a6))) +d "add t3, t3, a7" 469e 0x140 (set t3 (+ (var t3) (var a7))) +d "add t5, t1, t3" 330fc301 0x140 (set t5 (+ (var t1) (var t3))) +d "add t4, a3, a4" b38ee600 0x140 (set t4 (+ (var a3) (var a4))) +d "sltu a7, t4, a3" b3b8de00 0x140 (set a7 (ite (&& (ule (var t4) (var a3)) (! (== (var t4) (var a3)))) (bv 64 0x1) (bv 64 0x0))) +d "add a7, a7, t5" fa98 0x140 (set a7 (+ (var a7) (var t5))) +d "blt s1, a7, 0x2c6" 63cc1415 0x16e (branch (&& (sle (var s1) (var a7)) (! (== (var s1) (var a7)))) (jmp (bv 64 0x2c6)) (jmp (bv 64 0x172))) +d "beq a7, s1, 0x2c2" 63889814 0x172 (branch (== (var a7) (var s1)) (jmp (bv 64 0x2c2)) (jmp (bv 64 0x176))) +d "sub a4, a3, a4" 3387e640 0x140 (set a4 (- (var a3) (var a4))) +d "sub t3, t1, t3" 330ec341 0x140 (set t3 (- (var t1) (var t3))) +d "sltu a3, ra, zero" b3b60000 0x140 (set a3 (ite (&& (ule (var ra) (bv 64 0x0)) (! (== (var ra) (bv 64 0x0)))) (bv 64 0x1) (bv 64 0x0))) +d "add a7, a4, s10" b308a701 0x180 (set a7 (+ (var a4) (var s10))) +d "sub a3, t3, a3" b306de40 0x180 (set a3 (- (var t3) (var a3))) +d "sltu a4, a7, a4" 33b7e800 0x180 (set a4 (ite (&& (ule (var a7) (var a4)) (! (== (var a7) (var a4)))) (bv 64 0x1) (bv 64 0x0))) +d "add a3, a3, s5" d696 0x180 (set a3 (+ (var a3) (var s5))) +d "add a3, a3, a4" ba96 0x180 (set a3 (+ (var a3) (var a4))) +d "mul a5, a5, a2" b387c702 0x180 (set a5 (* (var a5) (var a2))) +d "slli t1, a3, 8" 13938600 0x180 (set t1 (<< (var a3) (bv 64 0x8) false)) +d "addi a1, a1, 1" 8505 0x180 (set a1 (+ (var a1) (bv 64 0x1))) +d "mul a4, a0, a6" 33070503 0x180 (set a4 (* (var a0) (var a6))) +d "srai a0, a3, 0x18" 13d58641 0x180 (set a0 (>> (var a3) (bv 64 0x18) (msb (var a3)))) +d "mulhu a3, a6, a2" b336c802 0x180 (set a3 (cast 64 false (>> (* (cast 128 false (var a6)) (cast 128 false (var a2))) (bv 8 0x40) false))) +d "add a4, a4, a5" 3e97 0x180 (set a4 (+ (var a4) (var a5))) +d "mul a6, a6, a2" 3308c802 0x180 (set a6 (* (var a6) (var a2))) +d "add a4, a4, a3" 3697 0x180 (set a4 (+ (var a4) (var a3))) +d "srli a2, a7, 0x18" 13d68801 0x180 (set a2 (>> (var a7) (bv 64 0x18) false)) +d "slli a4, a4, 1" 0607 0x180 (set a4 (<< (var a4) (bv 64 0x1) false)) +d "or a2, t1, a2" 3366c300 0x180 (set a2 (| (var t1) (var a2))) +d "slli a7, a6, 1" 93181800 0x180 (set a7 (<< (var a6) (bv 64 0x1) false)) +d "srli a3, a6, 0x1f" 9356f801 0x180 (set a3 (>> (var a6) (bv 64 0x1f) false)) +d "add a5, a7, t2" b3877800 0x1c0 (set a5 (+ (var a7) (var t2))) +d "or a4, a4, a3" 558f 0x1c0 (set a4 (| (var a4) (var a3))) +d "srli a6, a5, 0x18" 13d88701 0x1c0 (set a6 (>> (var a5) (bv 64 0x18) false)) +d "add a4, a4, t6" 7e97 0x1c0 (set a4 (+ (var a4) (var t6))) +d "sltu a5, a5, a7" b3b71701 0x1c0 (set a5 (ite (&& (ule (var a5) (var a7)) (! (== (var a5) (var a7)))) (bv 64 0x1) (bv 64 0x0))) +d "add a4, a4, a5" 3e97 0x1c0 (set a4 (+ (var a4) (var a5))) +d "slli a5, a4, 8" 93178700 0x1c0 (set a5 (<< (var a4) (bv 64 0x8) false)) +d "or a6, a5, a6" 33e80701 0x1c0 (set a6 (| (var a5) (var a6))) +d "srai a5, a4, 0x18" 93578741 0x1c0 (set a5 (>> (var a4) (bv 64 0x18) (msb (var a4)))) +d "bne a1, s6, 0x140" e39065f7 0x1e0 (branch (! (== (var a1) (var s6))) (jmp (bv 64 0x140)) (jmp (bv 64 0x1e4))) +d "li a5, 0" 8147 0x1c0 (set a5 (bv 64 0x0)) +d "add a4, t2, s8" 33878301 0x1c0 (set a4 (+ (var t2) (var s8))) +d "sltu a3, a4, t2" b3367700 0x1c0 (set a3 (ite (&& (ule (var a4) (var t2)) (! (== (var a4) (var t2)))) (bv 64 0x1) (bv 64 0x0))) +d "or s2, a5, s2" 33e92701 0x1c0 (set s2 (| (var a5) (var s2))) +d "add t6, t6, s7" de9f 0x1c0 (set t6 (+ (var t6) (var s7))) +d "addi ra, ra, 1" 8500 0x1c0 (set ra (+ (var ra) (bv 64 0x1))) +d "andi s2, s2, 0xff" 1379f90f 0x1c0 (set s2 (& (var s2) (bv 64 0xff))) +d "mv t2, a4" ba83 0x1c0 (set t2 (var a4)) +d "add t6, t6, a3" b69f 0x1c0 (set t6 (+ (var t6) (var a3))) +d "ori a5, a5, 0x89" 93e79708 0x0 (set a5 (| (var a5) (bv 64 0x89))) +d "xori a5, a5, 0x431" 93c71743 0x0 (set a5 (^ (var a5) (bv 64 0x431))) +d "jalr ra" e7800000 0x30 (seq (set ra (bv 64 0x34)) (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "slti zero, ra, 0xc" 13a0c000 0x0 nop +d "sltiu zero, ra, 0xc" 13b0c000 0x0 nop +d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 64 0xc)) (! (== (var ra) (bv 64 0xc)))) (bv 64 0x1) (bv 64 0x0))) +d "sltiu t1, sp, 0x14" 13334101 0x0 (set t1 (ite (&& (ule (var sp) (bv 64 0x14)) (! (== (var sp) (bv 64 0x14)))) (bv 64 0x1) (bv 64 0x0))) +d "jal t0, 0x14" ef024001 0x0 (seq (set t0 (bv 64 0x4)) (jmp (bv 64 0x14))) +d "jal t0, 0x4a" ef024001 0x36 (seq (set t0 (bv 64 0x3a)) (jmp (bv 64 0x4a))) From 82bb22be0ad4947e5e9048e677e43ea7deff56af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sun, 28 Jun 2026 00:44:48 +0300 Subject: [PATCH 07/10] add previously untested instructions test cases for lifting --- test/db/asm/riscv_32 | 148 +++++++++++++++++++++++++++++++++++++++++++ test/db/asm/riscv_64 | 148 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) diff --git a/test/db/asm/riscv_32 b/test/db/asm/riscv_32 index d2036956000..aafac96179f 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -199,3 +199,151 @@ d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 32 0xc)) (! d "sltiu t1, sp, 0x14" 13334101 0x0 (set t1 (ite (&& (ule (var sp) (bv 32 0x14)) (! (== (var sp) (bv 32 0x14)))) (bv 32 0x1) (bv 32 0x0))) d "jal t0, 0x14" ef024001 0x0 (seq (set t0 (bv 32 0x4)) (jmp (bv 32 0x14))) d "jal t0, 0x4a" ef024001 0x36 (seq (set t0 (bv 32 0x3a)) (jmp (bv 32 0x4a))) +# ----------------------------- AUIPC ----------------------------- +d "auipc a0, 0x4a" 17a50400 0x0 (set a0 (+ (bv 32 0x0) (<< (bv 32 0x4a) (bv 32 0xc) false))) +d "auipc s5, 0xc8" 978a0c00 0x0 (set s5 (+ (bv 32 0x0) (<< (bv 32 0xc8) (bv 32 0xc) false))) +d "auipc s9, 0x2c" 97cc0200 0x0 (set s9 (+ (bv 32 0x0) (<< (bv 32 0x2c) (bv 32 0xc) false))) +# ----------------------------- AND ----------------------------- +d "and s4, a2, a4" 337ae600 0x0 (set s4 (& (var a2) (var a4))) +d "and a4, a5, s5" 33f75701 0x0 (set a4 (& (var a5) (var s5))) +d "and a5, a5, s10" b3f7a701 0x0 (set a5 (& (var a5) (var s10))) +# ----------------------------- XOR ----------------------------- +d "xor a5, a3, a4" b3c7e600 0x0 (set a5 (^ (var a3) (var a4))) +d "xor a0, a1, a6" 33c50501 0x0 (set a0 (^ (var a1) (var a6))) +d "xor t4, s11, s2" b3ce2d01 0x0 (set t4 (^ (var s11) (var s2))) +# ----------------------------- SLT ----------------------------- +d "slt a5, s4, a5" b327fa00 0x0 (set a5 (ite (&& (sle (var s4) (var a5)) (! (== (var s4) (var a5)))) (bv 32 0x1) (bv 32 0x0))) +d "slt t3, a2, a4" 332ee600 0x0 (set t3 (ite (&& (sle (var a2) (var a4)) (! (== (var a2) (var a4)))) (bv 32 0x1) (bv 32 0x0))) +d "slt a3, a5, a3" b3a6d700 0x0 (set a3 (ite (&& (sle (var a5) (var a3)) (! (== (var a5) (var a3)))) (bv 32 0x1) (bv 32 0x0))) +# ----------------------------- SLL ----------------------------- +d "sll a5, a5, a1" b397b700 0x0 (set a5 (<< (var a5) (& (var a1) (bv 32 0x1f)) false)) +d "sll s10, s3, s10" 339da901 0x0 (set s10 (<< (var s3) (& (var s10) (bv 32 0x1f)) false)) +d "sll a1, a1, t5" b395e501 0x0 (set a1 (<< (var a1) (& (var t5) (bv 32 0x1f)) false)) +# ----------------------------- SRL ----------------------------- +d "srl a5, a5, a4" b3d7e700 0x0 (set a5 (>> (var a5) (& (var a4) (bv 32 0x1f)) false)) +d "srl a6, a3, a4" 33d8e600 0x0 (set a6 (>> (var a3) (& (var a4) (bv 32 0x1f)) false)) +d "srl t3, t3, t4" 335ede01 0x0 (set t3 (>> (var t3) (& (var t4) (bv 32 0x1f)) false)) +# ----------------------------- SRA ----------------------------- +d "sra a4, a0, a4" 3357e540 0x0 (set a4 (>> (var a0) (& (var a4) (bv 32 0x1f)) (msb (var a0)))) +d "sra a4, a1, a4" 33d7e540 0x0 (set a4 (>> (var a1) (& (var a4) (bv 32 0x1f)) (msb (var a1)))) +d "sra a2, a0, a2" 3356c540 0x0 (set a2 (>> (var a0) (& (var a2) (bv 32 0x1f)) (msb (var a0)))) +# ----------------------------- LB ----------------------------- +d "lb a4, 0x108(a0)" 03078510 0x0 (set a4 (cast 32 (msb (loadw 0 8 (+ (var a0) (bv 32 0x108)))) (loadw 0 8 (+ (var a0) (bv 32 0x108))))) +d "lb a7, 0(t3)" 83080e00 0x0 (set a7 (cast 32 (msb (loadw 0 8 (+ (var t3) (bv 32 0x0)))) (loadw 0 8 (+ (var t3) (bv 32 0x0))))) +d "lb a2, 1(a4)" 03061700 0x0 (set a2 (cast 32 (msb (loadw 0 8 (+ (var a4) (bv 32 0x1)))) (loadw 0 8 (+ (var a4) (bv 32 0x1))))) +# ----------------------------- LH ----------------------------- +d "lh a5, 6(a6)" 83176800 0x0 (set a5 (cast 32 (msb (loadw 0 16 (+ (var a6) (bv 32 0x6)))) (loadw 0 16 (+ (var a6) (bv 32 0x6))))) +d "lh a5, 0x334(s7)" 83974b33 0x0 (set a5 (cast 32 (msb (loadw 0 16 (+ (var s7) (bv 32 0x334)))) (loadw 0 16 (+ (var s7) (bv 32 0x334))))) +d "lh a4, -0x148(a4)" 031787eb 0x0 (set a4 (cast 32 (msb (loadw 0 16 (+ (var a4) (bv 32 0xfffffeb8)))) (loadw 0 16 (+ (var a4) (bv 32 0xfffffeb8))))) +# ----------------------------- LW ----------------------------- +d "lw s1, 8(s7)" 83a48b00 0x0 (set s1 (loadw 0 32 (+ (var s7) (bv 32 0x8)))) +d "lw a1, 0x18(sp)" e245 0x0 (set a1 (loadw 0 32 (+ (var sp) (bv 32 0x18)))) +d "lw a4, 0x9c(a4)" 0327c709 0x0 (set a4 (loadw 0 32 (+ (var a4) (bv 32 0x9c)))) +# ----------------------------- LBU ----------------------------- +d "lbu a4, 0x337(s1)" 03c77433 0x0 (set a4 (cast 32 false (loadw 0 8 (+ (var s1) (bv 32 0x337))))) +d "lbu a4, 0x50(sp)" 03470105 0x0 (set a4 (cast 32 false (loadw 0 8 (+ (var sp) (bv 32 0x50))))) +d "lbu a3, -0x77(s0)" 834694f8 0x0 (set a3 (cast 32 false (loadw 0 8 (+ (var s0) (bv 32 0xffffff89))))) +# ----------------------------- LHU ----------------------------- +d "lhu a5, 4(s0)" 83574400 0x0 (set a5 (cast 32 false (loadw 0 16 (+ (var s0) (bv 32 0x4))))) +d "lhu a5, 0xc(s11)" 83d7cd00 0x0 (set a5 (cast 32 false (loadw 0 16 (+ (var s11) (bv 32 0xc))))) +d "lhu a2, 0xa4(sp)" 0356410a 0x0 (set a2 (cast 32 false (loadw 0 16 (+ (var sp) (bv 32 0xa4))))) +# ----------------------------- SB ----------------------------- +d "sb a1, 3(s0)" a301b400 0x0 (storew 0 (+ (var s0) (bv 32 0x3)) (cast 8 false (var a1))) +d "sb a1, -0x74(s0)" 2306b4f8 0x0 (storew 0 (+ (var s0) (bv 32 0xffffff8c)) (cast 8 false (var a1))) +d "sb a3, -1(a4)" a30fd7fe 0x0 (storew 0 (+ (var a4) (bv 32 0xffffffff)) (cast 8 false (var a3))) +# ----------------------------- SH ----------------------------- +d "sh a5, 0(s1)" 2390f400 0x0 (storew 0 (+ (var s1) (bv 32 0x0)) (cast 16 false (var a5))) +d "sh a0, 0x80(s1)" 2390a408 0x0 (storew 0 (+ (var s1) (bv 32 0x80)) (cast 16 false (var a0))) +d "sh s1, 0x32(a5)" 23999702 0x0 (storew 0 (+ (var a5) (bv 32 0x32)) (cast 16 false (var s1))) +# ----------------------------- SW ----------------------------- +d "sw a5, 0x9c(s1)" 23aef408 0x0 (storew 0 (+ (var s1) (bv 32 0x9c)) (var a5)) +d "sw a5, 0(a4)" 1cc3 0x0 (storew 0 (+ (var a4) (bv 32 0x0)) (var a5)) +d "sw s3, -0x6c0(a5)" 23a03795 0x0 (storew 0 (+ (var a5) (bv 32 0xfffff940)) (var s3)) +# ----------------------------- BLTU ----------------------------- +d "bltu a5, s4, 0x48" 63e44705 0x0 (branch (&& (ule (var a5) (var s4)) (! (== (var a5) (var s4)))) (jmp (bv 32 0x48)) (jmp (bv 32 0x4))) +d "bltu a5, a3, 0xfffffff0" e3e8d7fe 0x0 (branch (&& (ule (var a5) (var a3)) (! (== (var a5) (var a3)))) (jmp (bv 32 0xfffffff0)) (jmp (bv 32 0x4))) +d "bltu t3, a1, 0xffffffe6" e363befe 0x0 (branch (&& (ule (var t3) (var a1)) (! (== (var t3) (var a1)))) (jmp (bv 32 0xffffffe6)) (jmp (bv 32 0x4))) +# ----------------------------- BGEU ----------------------------- +d "bgeu a3, a4, 0x1ae" 63f7e61a 0x0 (branch (|| (! (ule (var a3) (var a4))) (== (var a3) (var a4))) (jmp (bv 32 0x1ae)) (jmp (bv 32 0x4))) +d "bgeu s2, a5, 0xfffffff6" e37bf9fe 0x0 (branch (|| (! (ule (var s2) (var a5))) (== (var s2) (var a5))) (jmp (bv 32 0xfffffff6)) (jmp (bv 32 0x4))) +d "bgeu s7, s0, 0xffffff64" e3f28bf6 0x0 (branch (|| (! (ule (var s7) (var s0))) (== (var s7) (var s0))) (jmp (bv 32 0xffffff64)) (jmp (bv 32 0x4))) +# ----------------------------- FENCE ----------------------------- +d "fence rw, rw" 0f003003 0x0 nop +d "fence rw, w" 0f001003 0x0 nop +d "fence r, rw" 0f003002 0x0 nop +# ----------------------------- FENCE_I ----------------------------- +d "fence.i" 0f100000 0x0 nop +d "fence.i" 0f100000 0x0 nop +d "fence.i" 0f100000 0x0 nop +# ----------------------------- ECALL ----------------------------- +d "ecall" 73000000 0x0 (goto ecall) +d "ecall" 73000000 0x0 (goto ecall) +d "ecall" 73000000 0x0 (goto ecall) +# ----------------------------- EBREAK ----------------------------- +d "ebreak" 73001000 0x0 (goto ebreak) +d "ebreak" 73001000 0x0 (goto ebreak) +d "ebreak" 73001000 0x0 (goto ebreak) +# ----------------------------- MULH ----------------------------- +d "mulh t0, t1, t2" b3127302 0x0 (set t0 (cast 32 false (>> (* (cast 64 (msb (var t1)) (var t1)) (cast 64 (msb (var t2)) (var t2))) (bv 8 0x20) false))) +d "mulh a0, a1, a2" 3395c502 0x0 (set a0 (cast 32 false (>> (* (cast 64 (msb (var a1)) (var a1)) (cast 64 (msb (var a2)) (var a2))) (bv 8 0x20) false))) +d "mulh t3, t4, t5" 339eee03 0x0 (set t3 (cast 32 false (>> (* (cast 64 (msb (var t4)) (var t4)) (cast 64 (msb (var t5)) (var t5))) (bv 8 0x20) false))) +# ----------------------------- MULHSU ----------------------------- +d "mulhsu t0, t1, t2" b3227302 0x0 (set t0 (cast 32 false (>> (* (cast 64 (msb (var t1)) (var t1)) (cast 64 false (var t2))) (bv 8 0x20) false))) +d "mulhsu a0, a1, a2" 33a5c502 0x0 (set a0 (cast 32 false (>> (* (cast 64 (msb (var a1)) (var a1)) (cast 64 false (var a2))) (bv 8 0x20) false))) +d "mulhsu t3, t4, t5" 33aeee03 0x0 (set t3 (cast 32 false (>> (* (cast 64 (msb (var t4)) (var t4)) (cast 64 false (var t5))) (bv 8 0x20) false))) +# ----------------------------- DIV ----------------------------- +d "div a3, a3, a7" b3c61603 0x0 (set a3 (sdiv (var a3) (var a7))) +d "div t4, t6, t4" b3cedf03 0x0 (set t4 (sdiv (var t6) (var t4))) +d "div a4, a4, a3" 3347d702 0x0 (set a4 (sdiv (var a4) (var a3))) +# ----------------------------- DIVU ----------------------------- +d "divu a6, s2, s10" 3358a903 0x0 (set a6 (div (var s2) (var s10))) +d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (div (var a5) (var t5))) +d "divu s1, a0, s2" b3542503 0x0 (set s1 (div (var a0) (var s2))) +# ----------------------------- REM ----------------------------- +d "rem t6, a4, a7" b36f1703 0x0 (set t6 (smod (var a4) (var a7))) +d "rem a5, a0, a4" b367e502 0x0 (set a5 (smod (var a0) (var a4))) +d "rem a5, t0, a5" b3e7f202 0x0 (set a5 (smod (var t0) (var a5))) +# ----------------------------- REMU ----------------------------- +d "remu a3, s1, a3" b3f6d402 0x0 (set a3 (mod (var s1) (var a3))) +d "remu a6, a6, s4" 33784803 0x0 (set a6 (mod (var a6) (var s4))) +d "remu a1, s7, s2" b3f52b03 0x0 (set a1 (mod (var s7) (var s2))) +# ----------------------------- C_NOP ----------------------------- +d "nop" 0100 0x0 nop +d "c.nop 1" 0500 0x0 nop +d "c.nop 2" 0900 0x0 nop +# ----------------------------- C_JALR ----------------------------- +d "jalr ra" 8290 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "jalr s0" 0294 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var s0) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "jalr a5" 8297 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var a5) (bv 32 0x0)) (bv 32 0xfffffffe)))) +# ----------------------------- C_EBREAK ----------------------------- +d "ebreak" 0290 0x0 (goto ebreak) +d "ebreak" 0290 0x0 (goto ebreak) +d "ebreak" 0290 0x0 (goto ebreak) +# ----------------------------- C_BEQZ ----------------------------- +d "beqz a0, 0" 01c1 0x0 (branch (== (var a0) (bv 32 0x0)) (jmp (bv 32 0x0)) (jmp (bv 32 0x2))) +d "beqz a1, 2" 89c1 0x0 (branch (== (var a1) (bv 32 0x0)) (jmp (bv 32 0x2)) (jmp (bv 32 0x2))) +d "beqz a5, 0xfffffffc" f5df 0x0 (branch (== (var a5) (bv 32 0x0)) (jmp (bv 32 0xfffffffc)) (jmp (bv 32 0x2))) +# ----------------------------- C_BNEZ ----------------------------- +d "bnez a0, 0" 01e1 0x0 (branch (! (== (var a0) (bv 32 0x0))) (jmp (bv 32 0x0)) (jmp (bv 32 0x2))) +d "bnez a1, 2" 89e1 0x0 (branch (! (== (var a1) (bv 32 0x0))) (jmp (bv 32 0x2)) (jmp (bv 32 0x2))) +d "bnez a5, 0xfffffffc" f5ff 0x0 (branch (! (== (var a5) (bv 32 0x0))) (jmp (bv 32 0xfffffffc)) (jmp (bv 32 0x2))) +# ----------------------------- C_SW ----------------------------- +d "sw a0, 0(s0)" 08c0 0x0 (storew 0 (+ (var s0) (bv 32 0x0)) (var a0)) +d "sw a1, 4(s1)" ccc0 0x0 (storew 0 (+ (var s1) (bv 32 0x4)) (var a1)) +d "sw a5, 0x7c(a5)" fcdf 0x0 (storew 0 (+ (var a5) (bv 32 0x7c)) (var a5)) +# ----------------------------- C_JAL ----------------------------- +d "jal 0xfffffff4" d53f 0x0 (seq (set ra (bv 32 0x2)) (jmp (bv 32 0xfffffff4))) +d "jal 2" 0920 0x0 (seq (set ra (bv 32 0x2)) (jmp (bv 32 0x2))) +d "jal 0xfffffff6" dd3f 0x0 (seq (set ra (bv 32 0x2)) (jmp (bv 32 0xfffffff6))) +# ----------------------------- C_SUB ----------------------------- +d "sub a0, a0, a1" 0d8d 0x0 (set a0 (- (var a0) (var a1))) +d "sub a2, a2, a3" 158e 0x0 (set a2 (- (var a2) (var a3))) +d "sub a5, a5, a4" 998f 0x0 (set a5 (- (var a5) (var a4))) +# ----------------------------- C_AND ----------------------------- +d "and a0, a0, a1" 6d8d 0x0 (set a0 (& (var a0) (var a1))) +d "and a2, a2, a3" 758e 0x0 (set a2 (& (var a2) (var a3))) +d "and a5, a5, a4" f98f 0x0 (set a5 (& (var a5) (var a4))) +# ----------------------------- C_XOR ----------------------------- +d "xor a0, a0, a1" 2d8d 0x0 (set a0 (^ (var a0) (var a1))) +d "xor a2, a2, a3" 358e 0x0 (set a2 (^ (var a2) (var a3))) +d "xor a5, a5, a4" b98f 0x0 (set a5 (^ (var a5) (var a4))) diff --git a/test/db/asm/riscv_64 b/test/db/asm/riscv_64 index d13c2a527dc..278a07e9a82 100644 --- a/test/db/asm/riscv_64 +++ b/test/db/asm/riscv_64 @@ -199,3 +199,151 @@ d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 64 0xc)) (! d "sltiu t1, sp, 0x14" 13334101 0x0 (set t1 (ite (&& (ule (var sp) (bv 64 0x14)) (! (== (var sp) (bv 64 0x14)))) (bv 64 0x1) (bv 64 0x0))) d "jal t0, 0x14" ef024001 0x0 (seq (set t0 (bv 64 0x4)) (jmp (bv 64 0x14))) d "jal t0, 0x4a" ef024001 0x36 (seq (set t0 (bv 64 0x3a)) (jmp (bv 64 0x4a))) +# ----------------------------- AUIPC ----------------------------- +d "auipc a0, 0x4a" 17a50400 0x0 (set a0 (+ (bv 64 0x0) (cast 64 (msb (<< (cast 32 false (bv 64 0x4a)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x4a)) (bv 32 0xc) false)))) +d "auipc s5, 0xc8" 978a0c00 0x0 (set s5 (+ (bv 64 0x0) (cast 64 (msb (<< (cast 32 false (bv 64 0xc8)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0xc8)) (bv 32 0xc) false)))) +d "auipc s9, 0x2c" 97cc0200 0x0 (set s9 (+ (bv 64 0x0) (cast 64 (msb (<< (cast 32 false (bv 64 0x2c)) (bv 32 0xc) false)) (<< (cast 32 false (bv 64 0x2c)) (bv 32 0xc) false)))) +# ----------------------------- AND ----------------------------- +d "and s4, a2, a4" 337ae600 0x0 (set s4 (& (var a2) (var a4))) +d "and a4, a5, s5" 33f75701 0x0 (set a4 (& (var a5) (var s5))) +d "and a5, a5, s10" b3f7a701 0x0 (set a5 (& (var a5) (var s10))) +# ----------------------------- XOR ----------------------------- +d "xor a5, a3, a4" b3c7e600 0x0 (set a5 (^ (var a3) (var a4))) +d "xor a0, a1, a6" 33c50501 0x0 (set a0 (^ (var a1) (var a6))) +d "xor t4, s11, s2" b3ce2d01 0x0 (set t4 (^ (var s11) (var s2))) +# ----------------------------- SLT ----------------------------- +d "slt a5, s4, a5" b327fa00 0x0 (set a5 (ite (&& (sle (var s4) (var a5)) (! (== (var s4) (var a5)))) (bv 64 0x1) (bv 64 0x0))) +d "slt t3, a2, a4" 332ee600 0x0 (set t3 (ite (&& (sle (var a2) (var a4)) (! (== (var a2) (var a4)))) (bv 64 0x1) (bv 64 0x0))) +d "slt a3, a5, a3" b3a6d700 0x0 (set a3 (ite (&& (sle (var a5) (var a3)) (! (== (var a5) (var a3)))) (bv 64 0x1) (bv 64 0x0))) +# ----------------------------- SLL ----------------------------- +d "sll a5, a5, a1" b397b700 0x0 (set a5 (<< (var a5) (& (var a1) (bv 64 0x3f)) false)) +d "sll s10, s3, s10" 339da901 0x0 (set s10 (<< (var s3) (& (var s10) (bv 64 0x3f)) false)) +d "sll a1, a1, t5" b395e501 0x0 (set a1 (<< (var a1) (& (var t5) (bv 64 0x3f)) false)) +# ----------------------------- SRL ----------------------------- +d "srl a5, a5, a4" b3d7e700 0x0 (set a5 (>> (var a5) (& (var a4) (bv 64 0x3f)) false)) +d "srl a6, a3, a4" 33d8e600 0x0 (set a6 (>> (var a3) (& (var a4) (bv 64 0x3f)) false)) +d "srl t3, t3, t4" 335ede01 0x0 (set t3 (>> (var t3) (& (var t4) (bv 64 0x3f)) false)) +# ----------------------------- SRA ----------------------------- +d "sra a4, a0, a4" 3357e540 0x0 (set a4 (>> (var a0) (& (var a4) (bv 64 0x3f)) (msb (var a0)))) +d "sra a4, a1, a4" 33d7e540 0x0 (set a4 (>> (var a1) (& (var a4) (bv 64 0x3f)) (msb (var a1)))) +d "sra a2, a0, a2" 3356c540 0x0 (set a2 (>> (var a0) (& (var a2) (bv 64 0x3f)) (msb (var a0)))) +# ----------------------------- LB ----------------------------- +d "lb a4, 0x108(a0)" 03078510 0x0 (set a4 (cast 64 (msb (loadw 0 8 (+ (var a0) (bv 64 0x108)))) (loadw 0 8 (+ (var a0) (bv 64 0x108))))) +d "lb a7, 0(t3)" 83080e00 0x0 (set a7 (cast 64 (msb (loadw 0 8 (+ (var t3) (bv 64 0x0)))) (loadw 0 8 (+ (var t3) (bv 64 0x0))))) +d "lb a2, 1(a4)" 03061700 0x0 (set a2 (cast 64 (msb (loadw 0 8 (+ (var a4) (bv 64 0x1)))) (loadw 0 8 (+ (var a4) (bv 64 0x1))))) +# ----------------------------- LH ----------------------------- +d "lh a5, 6(a6)" 83176800 0x0 (set a5 (cast 64 (msb (loadw 0 16 (+ (var a6) (bv 64 0x6)))) (loadw 0 16 (+ (var a6) (bv 64 0x6))))) +d "lh a5, 0x334(s7)" 83974b33 0x0 (set a5 (cast 64 (msb (loadw 0 16 (+ (var s7) (bv 64 0x334)))) (loadw 0 16 (+ (var s7) (bv 64 0x334))))) +d "lh a4, -0x148(a4)" 031787eb 0x0 (set a4 (cast 64 (msb (loadw 0 16 (+ (var a4) (bv 64 0xfffffffffffffeb8)))) (loadw 0 16 (+ (var a4) (bv 64 0xfffffffffffffeb8))))) +# ----------------------------- LW ----------------------------- +d "lw s1, 8(s7)" 83a48b00 0x0 (set s1 (cast 64 (msb (loadw 0 32 (+ (var s7) (bv 64 0x8)))) (loadw 0 32 (+ (var s7) (bv 64 0x8))))) +d "lw a1, 0x18(sp)" e245 0x0 (set a1 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x18)))) (loadw 0 32 (+ (var sp) (bv 64 0x18))))) +d "lw a4, 0x9c(a4)" 0327c709 0x0 (set a4 (cast 64 (msb (loadw 0 32 (+ (var a4) (bv 64 0x9c)))) (loadw 0 32 (+ (var a4) (bv 64 0x9c))))) +# ----------------------------- LBU ----------------------------- +d "lbu a4, 0x337(s1)" 03c77433 0x0 (set a4 (cast 64 false (loadw 0 8 (+ (var s1) (bv 64 0x337))))) +d "lbu a4, 0x50(sp)" 03470105 0x0 (set a4 (cast 64 false (loadw 0 8 (+ (var sp) (bv 64 0x50))))) +d "lbu a3, -0x77(s0)" 834694f8 0x0 (set a3 (cast 64 false (loadw 0 8 (+ (var s0) (bv 64 0xffffffffffffff89))))) +# ----------------------------- LHU ----------------------------- +d "lhu a5, 4(s0)" 83574400 0x0 (set a5 (cast 64 false (loadw 0 16 (+ (var s0) (bv 64 0x4))))) +d "lhu a5, 0xc(s11)" 83d7cd00 0x0 (set a5 (cast 64 false (loadw 0 16 (+ (var s11) (bv 64 0xc))))) +d "lhu a2, 0xa4(sp)" 0356410a 0x0 (set a2 (cast 64 false (loadw 0 16 (+ (var sp) (bv 64 0xa4))))) +# ----------------------------- SB ----------------------------- +d "sb a1, 3(s0)" a301b400 0x0 (storew 0 (+ (var s0) (bv 64 0x3)) (cast 8 false (var a1))) +d "sb a1, -0x74(s0)" 2306b4f8 0x0 (storew 0 (+ (var s0) (bv 64 0xffffffffffffff8c)) (cast 8 false (var a1))) +d "sb a3, -1(a4)" a30fd7fe 0x0 (storew 0 (+ (var a4) (bv 64 0xffffffffffffffff)) (cast 8 false (var a3))) +# ----------------------------- SH ----------------------------- +d "sh a5, 0(s1)" 2390f400 0x0 (storew 0 (+ (var s1) (bv 64 0x0)) (cast 16 false (var a5))) +d "sh a0, 0x80(s1)" 2390a408 0x0 (storew 0 (+ (var s1) (bv 64 0x80)) (cast 16 false (var a0))) +d "sh s1, 0x32(a5)" 23999702 0x0 (storew 0 (+ (var a5) (bv 64 0x32)) (cast 16 false (var s1))) +# ----------------------------- SW ----------------------------- +d "sw a5, 0x9c(s1)" 23aef408 0x0 (storew 0 (+ (var s1) (bv 64 0x9c)) (cast 32 false (var a5))) +d "sw a5, 0(a4)" 1cc3 0x0 (storew 0 (+ (var a4) (bv 64 0x0)) (cast 32 false (var a5))) +d "sw s3, -0x6c0(a5)" 23a03795 0x0 (storew 0 (+ (var a5) (bv 64 0xfffffffffffff940)) (cast 32 false (var s3))) +# ----------------------------- BLTU ----------------------------- +d "bltu a5, s4, 0x48" 63e44705 0x0 (branch (&& (ule (var a5) (var s4)) (! (== (var a5) (var s4)))) (jmp (bv 64 0x48)) (jmp (bv 64 0x4))) +d "bltu a5, a3, 0xfffffffffffffff0" e3e8d7fe 0x0 (branch (&& (ule (var a5) (var a3)) (! (== (var a5) (var a3)))) (jmp (bv 64 0xfffffffffffffff0)) (jmp (bv 64 0x4))) +d "bltu t3, a1, 0xffffffffffffffe6" e363befe 0x0 (branch (&& (ule (var t3) (var a1)) (! (== (var t3) (var a1)))) (jmp (bv 64 0xffffffffffffffe6)) (jmp (bv 64 0x4))) +# ----------------------------- BGEU ----------------------------- +d "bgeu a3, a4, 0x1ae" 63f7e61a 0x0 (branch (|| (! (ule (var a3) (var a4))) (== (var a3) (var a4))) (jmp (bv 64 0x1ae)) (jmp (bv 64 0x4))) +d "bgeu s2, a5, 0xfffffffffffffff6" e37bf9fe 0x0 (branch (|| (! (ule (var s2) (var a5))) (== (var s2) (var a5))) (jmp (bv 64 0xfffffffffffffff6)) (jmp (bv 64 0x4))) +d "bgeu s7, s0, 0xffffffffffffff64" e3f28bf6 0x0 (branch (|| (! (ule (var s7) (var s0))) (== (var s7) (var s0))) (jmp (bv 64 0xffffffffffffff64)) (jmp (bv 64 0x4))) +# ----------------------------- FENCE ----------------------------- +d "fence rw, rw" 0f003003 0x0 nop +d "fence rw, w" 0f001003 0x0 nop +d "fence r, rw" 0f003002 0x0 nop +# ----------------------------- FENCE_I ----------------------------- +d "fence.i" 0f100000 0x0 nop +d "fence.i" 0f100000 0x0 nop +d "fence.i" 0f100000 0x0 nop +# ----------------------------- ECALL ----------------------------- +d "ecall" 73000000 0x0 (goto ecall) +d "ecall" 73000000 0x0 (goto ecall) +d "ecall" 73000000 0x0 (goto ecall) +# ----------------------------- EBREAK ----------------------------- +d "ebreak" 73001000 0x0 (goto ebreak) +d "ebreak" 73001000 0x0 (goto ebreak) +d "ebreak" 73001000 0x0 (goto ebreak) +# ----------------------------- MULH ----------------------------- +d "mulh t0, t1, t2" b3127302 0x0 (set t0 (cast 64 false (>> (* (cast 128 (msb (var t1)) (var t1)) (cast 128 (msb (var t2)) (var t2))) (bv 8 0x40) false))) +d "mulh a0, a1, a2" 3395c502 0x0 (set a0 (cast 64 false (>> (* (cast 128 (msb (var a1)) (var a1)) (cast 128 (msb (var a2)) (var a2))) (bv 8 0x40) false))) +d "mulh t3, t4, t5" 339eee03 0x0 (set t3 (cast 64 false (>> (* (cast 128 (msb (var t4)) (var t4)) (cast 128 (msb (var t5)) (var t5))) (bv 8 0x40) false))) +# ----------------------------- MULHSU ----------------------------- +d "mulhsu t0, t1, t2" b3227302 0x0 (set t0 (cast 64 false (>> (* (cast 128 (msb (var t1)) (var t1)) (cast 128 false (var t2))) (bv 8 0x40) false))) +d "mulhsu a0, a1, a2" 33a5c502 0x0 (set a0 (cast 64 false (>> (* (cast 128 (msb (var a1)) (var a1)) (cast 128 false (var a2))) (bv 8 0x40) false))) +d "mulhsu t3, t4, t5" 33aeee03 0x0 (set t3 (cast 64 false (>> (* (cast 128 (msb (var t4)) (var t4)) (cast 128 false (var t5))) (bv 8 0x40) false))) +# ----------------------------- DIV ----------------------------- +d "div a3, a3, a7" b3c61603 0x0 (set a3 (sdiv (var a3) (var a7))) +d "div t4, t6, t4" b3cedf03 0x0 (set t4 (sdiv (var t6) (var t4))) +d "div a4, a4, a3" 3347d702 0x0 (set a4 (sdiv (var a4) (var a3))) +# ----------------------------- DIVU ----------------------------- +d "divu a6, s2, s10" 3358a903 0x0 (set a6 (div (var s2) (var s10))) +d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (div (var a5) (var t5))) +d "divu s1, a0, s2" b3542503 0x0 (set s1 (div (var a0) (var s2))) +# ----------------------------- REM ----------------------------- +d "rem t6, a4, a7" b36f1703 0x0 (set t6 (smod (var a4) (var a7))) +d "rem a5, a0, a4" b367e502 0x0 (set a5 (smod (var a0) (var a4))) +d "rem a5, t0, a5" b3e7f202 0x0 (set a5 (smod (var t0) (var a5))) +# ----------------------------- REMU ----------------------------- +d "remu a3, s1, a3" b3f6d402 0x0 (set a3 (mod (var s1) (var a3))) +d "remu a6, a6, s4" 33784803 0x0 (set a6 (mod (var a6) (var s4))) +d "remu a1, s7, s2" b3f52b03 0x0 (set a1 (mod (var s7) (var s2))) +# ----------------------------- C_NOP ----------------------------- +d "nop" 0100 0x0 nop +d "c.nop 1" 0500 0x0 nop +d "c.nop 2" 0900 0x0 nop +# ----------------------------- C_JALR ----------------------------- +d "jalr ra" 8290 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "jalr s0" 0294 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var s0) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "jalr a5" 8297 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var a5) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +# ----------------------------- C_EBREAK ----------------------------- +d "ebreak" 0290 0x0 (goto ebreak) +d "ebreak" 0290 0x0 (goto ebreak) +d "ebreak" 0290 0x0 (goto ebreak) +# ----------------------------- C_BEQZ ----------------------------- +d "beqz a0, 0" 01c1 0x0 (branch (== (var a0) (bv 64 0x0)) (jmp (bv 64 0x0)) (jmp (bv 64 0x2))) +d "beqz a1, 2" 89c1 0x0 (branch (== (var a1) (bv 64 0x0)) (jmp (bv 64 0x2)) (jmp (bv 64 0x2))) +d "beqz a5, 0xfffffffffffffffc" f5df 0x0 (branch (== (var a5) (bv 64 0x0)) (jmp (bv 64 0xfffffffffffffffc)) (jmp (bv 64 0x2))) +# ----------------------------- C_BNEZ ----------------------------- +d "bnez a0, 0" 01e1 0x0 (branch (! (== (var a0) (bv 64 0x0))) (jmp (bv 64 0x0)) (jmp (bv 64 0x2))) +d "bnez a1, 2" 89e1 0x0 (branch (! (== (var a1) (bv 64 0x0))) (jmp (bv 64 0x2)) (jmp (bv 64 0x2))) +d "bnez a5, 0xfffffffffffffffc" f5ff 0x0 (branch (! (== (var a5) (bv 64 0x0))) (jmp (bv 64 0xfffffffffffffffc)) (jmp (bv 64 0x2))) +# ----------------------------- C_SW ----------------------------- +d "sw a0, 0(s0)" 08c0 0x0 (storew 0 (+ (var s0) (bv 64 0x0)) (cast 32 false (var a0))) +d "sw a1, 4(s1)" ccc0 0x0 (storew 0 (+ (var s1) (bv 64 0x4)) (cast 32 false (var a1))) +d "sw a5, 0x7c(a5)" fcdf 0x0 (storew 0 (+ (var a5) (bv 64 0x7c)) (cast 32 false (var a5))) +# ----------------------------- C_JAL ----------------------------- +d "addiw t6, t6, -0xb" d53f 0x0 (set t6 (cast 64 (msb (+ (cast 32 false (var t6)) (bv 32 0xfffffff5))) (+ (cast 32 false (var t6)) (bv 32 0xfffffff5)))) +d "jal 2" 0920 0x0 (seq (set ra (bv 32 0x2)) (jmp (bv 32 0x2))) +d "addiw t6, t6, -9" dd3f 0x0 (set t6 (cast 64 (msb (+ (cast 32 false (var t6)) (bv 32 0xfffffff7))) (+ (cast 32 false (var t6)) (bv 32 0xfffffff7)))) +# ----------------------------- C_SUB ----------------------------- +d "sub a0, a0, a1" 0d8d 0x0 (set a0 (- (var a0) (var a1))) +d "sub a2, a2, a3" 158e 0x0 (set a2 (- (var a2) (var a3))) +d "sub a5, a5, a4" 998f 0x0 (set a5 (- (var a5) (var a4))) +# ----------------------------- C_AND ----------------------------- +d "and a0, a0, a1" 6d8d 0x0 (set a0 (& (var a0) (var a1))) +d "and a2, a2, a3" 758e 0x0 (set a2 (& (var a2) (var a3))) +d "and a5, a5, a4" f98f 0x0 (set a5 (& (var a5) (var a4))) +# ----------------------------- C_XOR ----------------------------- +d "xor a0, a0, a1" 2d8d 0x0 (set a0 (^ (var a0) (var a1))) +d "xor a2, a2, a3" 358e 0x0 (set a2 (^ (var a2) (var a3))) +d "xor a5, a5, a4" b98f 0x0 (set a5 (^ (var a5) (var a4))) From 80e3eb227569536da15dcd1283898d0b9ad2504d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:14:13 +0300 Subject: [PATCH 08/10] fix leaks, bad test --- librz/arch/isa/riscv/riscv_il_compressed.c | 30 ++++++++++++---------- subprojects/capstone-next.wrap | 4 +-- test/db/asm/riscv_64 | 2 +- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/librz/arch/isa/riscv/riscv_il_compressed.c b/librz/arch/isa/riscv/riscv_il_compressed.c index 8d8a0c67a61..c88dd1d2989 100644 --- a/librz/arch/isa/riscv/riscv_il_compressed.c +++ b/librz/arch/isa/riscv/riscv_il_compressed.c @@ -10,18 +10,20 @@ #include -// Compressed instruction decoder variants that suppress operands not consumed by the lifter -#define DECODE_RD_RS_IMM_NO_RS(analysis, insn) \ - DECODE_RD_RS_IMM(analysis, insn) \ - (void)(rs); +#define DECODE_C_MV(analysis, insn) \ + REQUIRE_2OPS(RISCV_OP_REG, RISCV_OP_REG); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *rs = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[1].reg); -#define DECODE_RD_IMM_NO_RD(analysis, insn) \ - DECODE_RD_IMM(analysis, insn) \ - (void)(rd); +#define DECODE_C_LI(analysis, insn) \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); -#define DECODE_RS_RS_IMM_NO_RS2(analysis, insn) \ - DECODE_RS_RS_IMM(analysis, insn) \ - (void)(rs2); +#define DECODE_C_BRANCH_ZERO(analysis, insn) \ + REQUIRE_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ + RzILOpBitVector *rs1 = riscv_il_get_reg(analysis->bits, insn->detail->riscv.operands[0].reg); \ + RzILOpBitVector *imm = SN(analysis->bits, insn->detail->riscv.operands[2].imm); DEFINE_LIFTER_WITH_EFFECT(c_nop, DECODE_NONE, NOP()) DEFINE_ALIAS_LIFTER(c_addi, addi) @@ -42,8 +44,8 @@ DEFINE_ALIAS_LIFTER(c_addiw, addiw) DEFINE_ALIAS_LIFTER(c_subw, subw) -DEFINE_LIFTER(c_mv, DECODE_RD_RS, DUP(rs)) -DEFINE_LIFTER(c_li, DECODE_RD_RS_IMM_NO_RS, DUP(imm)) +DEFINE_LIFTER(c_mv, DECODE_C_MV, rs) +DEFINE_LIFTER(c_li, DECODE_C_LI, imm) DEFINE_ALIAS_LIFTER(c_j, jal) DEFINE_ALIAS_LIFTER(c_jal, jal) @@ -66,8 +68,8 @@ DEFINE_ALIAS_LIFTER(c_lw, lw) DEFINE_ALIAS_LIFTER(c_ld, ld) DEFINE_ALIAS_LIFTER(c_ldsp, ld) -DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_beqz, DECODE_RS_RS_IMM_NO_RS2, BRANCH(EQ(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) -DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_bnez, DECODE_RS_RS_IMM_NO_RS2, BRANCH(NE(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_beqz, DECODE_C_BRANCH_ZERO, BRANCH(EQ(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) +DEFINE_LIFTER_FOR_ONEWAY_JUMP(c_bnez, DECODE_C_BRANCH_ZERO, BRANCH(NE(rs1, UN(analysis->bits, 0)), JMP(imm), JMP(UN(analysis->bits, current_addr + size)))) #include diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index cd5adda5491..f36ec97f5c5 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] -url = https://github.com/capstone-engine/capstone.git -revision = ae11e4232cb1f0df4847bf2d66825b9f1cb119a2 +url = https://github.com/moste00/capstone.git +revision = 86c8301074c35e86079408783956ada84c6f1d69 directory = capstone-next patch_directory = capstone-next depth = 1 diff --git a/test/db/asm/riscv_64 b/test/db/asm/riscv_64 index 278a07e9a82..31be7e05da5 100644 --- a/test/db/asm/riscv_64 +++ b/test/db/asm/riscv_64 @@ -333,7 +333,7 @@ d "sw a1, 4(s1)" ccc0 0x0 (storew 0 (+ (var s1) (bv 64 0x4)) (cast 32 false (var d "sw a5, 0x7c(a5)" fcdf 0x0 (storew 0 (+ (var a5) (bv 64 0x7c)) (cast 32 false (var a5))) # ----------------------------- C_JAL ----------------------------- d "addiw t6, t6, -0xb" d53f 0x0 (set t6 (cast 64 (msb (+ (cast 32 false (var t6)) (bv 32 0xfffffff5))) (+ (cast 32 false (var t6)) (bv 32 0xfffffff5)))) -d "jal 2" 0920 0x0 (seq (set ra (bv 32 0x2)) (jmp (bv 32 0x2))) +d "invalid" 0920 0x0 d "addiw t6, t6, -9" dd3f 0x0 (set t6 (cast 64 (msb (+ (cast 32 false (var t6)) (bv 32 0xfffffff7))) (+ (cast 32 false (var t6)) (bv 32 0xfffffff7)))) # ----------------------------- C_SUB ----------------------------- d "sub a0, a0, a1" 0d8d 0x0 (set a0 (- (var a0) (var a1))) From 758e59ba31410e7002856b557e6186e8c5dfb8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sun, 19 Jul 2026 01:32:25 +0300 Subject: [PATCH 09/10] fix bad cases of jalr and division instructions --- librz/arch/isa/riscv/riscv_il_integer.c | 13 ++++++++--- librz/arch/isa/riscv/riscv_il_m.c | 20 +++++++++++++---- test/db/asm/riscv_32 | 25 +++++++++++---------- test/db/asm/riscv_64 | 29 +++++++++++++++---------- 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/librz/arch/isa/riscv/riscv_il_integer.c b/librz/arch/isa/riscv/riscv_il_integer.c index da2cf589f65..326f683bb78 100644 --- a/librz/arch/isa/riscv/riscv_il_integer.c +++ b/librz/arch/isa/riscv/riscv_il_integer.c @@ -45,9 +45,16 @@ DEFINE_LIFTER_FOR_JUMP(jal, DECODE_RD_IMM, /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), /*GOTO ADDR*/ JMP(imm)) -DEFINE_LIFTER_FOR_JUMP(jalr, DECODE_RD_RS_IMM, - /*RETURN ADDR*/ UN(analysis->bits, current_addr + size), - /*GOTO ADDR*/ JMP(LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL)))) +RzILOpEffect *rz_riscv_lift_jalr(RZ_BORROW RZ_NONNULL RzAnalysis *analysis, + RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL cs_insn *insn, ut64 current_addr, size_t size) { + DECODE_RD_RS_IMM(analysis, insn); + (void)op; + + return SEQ3( + SETL("jalr_target", LOGAND(ADD(rs, imm), UN(analysis->bits, ~1ULL))), + riscv_il_set_reg(rd, UN(analysis->bits, current_addr + size)), + JMP(VARL("jalr_target"))); +} // Intentional: on RV32 imm is already 32-bit and the result needs no sign-extension, // so CAST(32) and SIGNED(32) would both be no-ops; on RV64 CAST(32) truncates imm and SIGNED(64) diff --git a/librz/arch/isa/riscv/riscv_il_m.c b/librz/arch/isa/riscv/riscv_il_m.c index 34e6199bbd1..aa8e6050602 100644 --- a/librz/arch/isa/riscv/riscv_il_m.c +++ b/librz/arch/isa/riscv/riscv_il_m.c @@ -11,20 +11,32 @@ // M extension: multiply/divide/remainder (RV32M / RV64M) +static inline RzILOpBitVector *riscv_il_div_by_zero_result(ut32 bits) { + return UN(bits, UT64_MAX); +} + +static inline RzILOpBitVector *riscv_il_sdiv(ut32 bits, RZ_OWN RzILOpBitVector *rs1, RZ_OWN RzILOpBitVector *rs2) { + return ITE(IS_ZERO(DUP(rs2)), riscv_il_div_by_zero_result(bits), SDIV(rs1, rs2)); +} + +static inline RzILOpBitVector *riscv_il_divu(ut32 bits, RZ_OWN RzILOpBitVector *rs1, RZ_OWN RzILOpBitVector *rs2) { + return ITE(IS_ZERO(DUP(rs2)), riscv_il_div_by_zero_result(bits), DIV(rs1, rs2)); +} + // RV32M DEFINE_LIFTER(mul, DECODE_RD_RS_RS, MUL(rs1, rs2)) DEFINE_LIFTER(mulh, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(SIGNED(analysis->bits * 2, rs1), SIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) DEFINE_LIFTER(mulhsu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(SIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) DEFINE_LIFTER(mulhu, DECODE_RD_RS_RS, CAST(analysis->bits, IL_FALSE, SHIFTR0(MUL(UNSIGNED(analysis->bits * 2, rs1), UNSIGNED(analysis->bits * 2, rs2)), UN(8, analysis->bits)))) -DEFINE_LIFTER(div, DECODE_RD_RS_RS, SDIV(rs1, rs2)) -DEFINE_LIFTER(divu, DECODE_RD_RS_RS, DIV(rs1, rs2)) +DEFINE_LIFTER(div, DECODE_RD_RS_RS, riscv_il_sdiv(analysis->bits, rs1, rs2)) +DEFINE_LIFTER(divu, DECODE_RD_RS_RS, riscv_il_divu(analysis->bits, rs1, rs2)) DEFINE_LIFTER(rem, DECODE_RD_RS_RS, SMOD(rs1, rs2)) DEFINE_LIFTER(remu, DECODE_RD_RS_RS, MOD(rs1, rs2)) // RV64M: *w instructions operate on lower 32 bits, result sign-extended to 64 bits DEFINE_LIFTER(mulw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MUL(rs1, rs2))) -DEFINE_LIFTER(divw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SDIV(rs1, rs2))) -DEFINE_LIFTER(divuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, DIV(rs1, rs2))) +DEFINE_LIFTER(divw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, riscv_il_sdiv(32, rs1, rs2))) +DEFINE_LIFTER(divuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, riscv_il_divu(32, rs1, rs2))) DEFINE_LIFTER(remw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, SMOD(rs1, rs2))) DEFINE_LIFTER(remuw, DECODE_RD_RS_RS_TRUNCATE32, SIGNED(analysis->bits, MOD(rs1, rs2))) diff --git a/test/db/asm/riscv_32 b/test/db/asm/riscv_32 index aafac96179f..48cb7f11486 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -50,7 +50,7 @@ d "lw s9, 0x64(sp)" 965c 0x40 (set s9 (loadw 0 32 (+ (var sp) (bv 32 0x64)))) d "lw s10, 0x60(sp)" 065d 0x40 (set s10 (loadw 0 32 (+ (var sp) (bv 32 0x60)))) d "lw s11, 0x5c(sp)" f64d 0x40 (set s11 (loadw 0 32 (+ (var sp) (bv 32 0x5c)))) d "addi sp, sp, 0x90" 4961 0x40 (set sp (+ (var sp) (bv 32 0x90))) -d "ret" 8280 0x40 (seq nop (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "ret" 8280 0x40 (seq (set jalr_target (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe))) nop (jmp (var jalr_target))) d "lw a5, 0x18(sp)" e247 0x40 (set a5 (loadw 0 32 (+ (var sp) (bv 32 0x18)))) d "beqz a5, 0x2d8" 63890726 0x66 (branch (== (var a5) (bv 32 0x0)) (jmp (bv 32 0x2d8)) (jmp (bv 32 0x6a))) d "lw s0, 0x1c(sp)" 7244 0x40 (set s0 (loadw 0 32 (+ (var sp) (bv 32 0x1c)))) @@ -192,7 +192,8 @@ d "mv t2, a4" ba83 0x1c0 (set t2 (var a4)) d "add t6, t6, a3" b69f 0x1c0 (set t6 (+ (var t6) (var a3))) d "ori a5, a5, 0x89" 93e79708 0x0 (set a5 (| (var a5) (bv 32 0x89))) d "xori a5, a5, 0x431" 93c71743 0x0 (set a5 (^ (var a5) (bv 32 0x431))) -d "jalr ra" e7800000 0x30 (seq (set ra (bv 32 0x34)) (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "jalr ra" e7800000 0x30 (seq (set jalr_target (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe))) (set ra (bv 32 0x34)) (jmp (var jalr_target))) +d "jalr a0, 4(a0)" 67054500 0x0 (seq (set jalr_target (& (+ (var a0) (bv 32 0x4)) (bv 32 0xfffffffe))) (set a0 (bv 32 0x4)) (jmp (var jalr_target))) d "slti zero, ra, 0xc" 13a0c000 0x0 nop d "sltiu zero, ra, 0xc" 13b0c000 0x0 nop d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 32 0xc)) (! (== (var ra) (bv 32 0xc)))) (bv 32 0x1) (bv 32 0x0))) @@ -292,13 +293,15 @@ d "mulhsu t0, t1, t2" b3227302 0x0 (set t0 (cast 32 false (>> (* (cast 64 (msb ( d "mulhsu a0, a1, a2" 33a5c502 0x0 (set a0 (cast 32 false (>> (* (cast 64 (msb (var a1)) (var a1)) (cast 64 false (var a2))) (bv 8 0x20) false))) d "mulhsu t3, t4, t5" 33aeee03 0x0 (set t3 (cast 32 false (>> (* (cast 64 (msb (var t4)) (var t4)) (cast 64 false (var t5))) (bv 8 0x20) false))) # ----------------------------- DIV ----------------------------- -d "div a3, a3, a7" b3c61603 0x0 (set a3 (sdiv (var a3) (var a7))) -d "div t4, t6, t4" b3cedf03 0x0 (set t4 (sdiv (var t6) (var t4))) -d "div a4, a4, a3" 3347d702 0x0 (set a4 (sdiv (var a4) (var a3))) +d "div a0, a1, a2" 33c5c502 0x0 (set a0 (ite (is_zero (var a2)) (bv 32 0xffffffff) (sdiv (var a1) (var a2)))) +d "div a3, a3, a7" b3c61603 0x0 (set a3 (ite (is_zero (var a7)) (bv 32 0xffffffff) (sdiv (var a3) (var a7)))) +d "div t4, t6, t4" b3cedf03 0x0 (set t4 (ite (is_zero (var t4)) (bv 32 0xffffffff) (sdiv (var t6) (var t4)))) +d "div a4, a4, a3" 3347d702 0x0 (set a4 (ite (is_zero (var a3)) (bv 32 0xffffffff) (sdiv (var a4) (var a3)))) # ----------------------------- DIVU ----------------------------- -d "divu a6, s2, s10" 3358a903 0x0 (set a6 (div (var s2) (var s10))) -d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (div (var a5) (var t5))) -d "divu s1, a0, s2" b3542503 0x0 (set s1 (div (var a0) (var s2))) +d "divu a0, a1, a2" 33d5c502 0x0 (set a0 (ite (is_zero (var a2)) (bv 32 0xffffffff) (div (var a1) (var a2)))) +d "divu a6, s2, s10" 3358a903 0x0 (set a6 (ite (is_zero (var s10)) (bv 32 0xffffffff) (div (var s2) (var s10)))) +d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (ite (is_zero (var t5)) (bv 32 0xffffffff) (div (var a5) (var t5)))) +d "divu s1, a0, s2" b3542503 0x0 (set s1 (ite (is_zero (var s2)) (bv 32 0xffffffff) (div (var a0) (var s2)))) # ----------------------------- REM ----------------------------- d "rem t6, a4, a7" b36f1703 0x0 (set t6 (smod (var a4) (var a7))) d "rem a5, a0, a4" b367e502 0x0 (set a5 (smod (var a0) (var a4))) @@ -312,9 +315,9 @@ d "nop" 0100 0x0 nop d "c.nop 1" 0500 0x0 nop d "c.nop 2" 0900 0x0 nop # ----------------------------- C_JALR ----------------------------- -d "jalr ra" 8290 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe)))) -d "jalr s0" 0294 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var s0) (bv 32 0x0)) (bv 32 0xfffffffe)))) -d "jalr a5" 8297 0x0 (seq (set ra (bv 32 0x2)) (jmp (& (+ (var a5) (bv 32 0x0)) (bv 32 0xfffffffe)))) +d "jalr ra" 8290 0x0 (seq (set jalr_target (& (+ (var ra) (bv 32 0x0)) (bv 32 0xfffffffe))) (set ra (bv 32 0x2)) (jmp (var jalr_target))) +d "jalr s0" 0294 0x0 (seq (set jalr_target (& (+ (var s0) (bv 32 0x0)) (bv 32 0xfffffffe))) (set ra (bv 32 0x2)) (jmp (var jalr_target))) +d "jalr a5" 8297 0x0 (seq (set jalr_target (& (+ (var a5) (bv 32 0x0)) (bv 32 0xfffffffe))) (set ra (bv 32 0x2)) (jmp (var jalr_target))) # ----------------------------- C_EBREAK ----------------------------- d "ebreak" 0290 0x0 (goto ebreak) d "ebreak" 0290 0x0 (goto ebreak) diff --git a/test/db/asm/riscv_64 b/test/db/asm/riscv_64 index 31be7e05da5..3868df627d9 100644 --- a/test/db/asm/riscv_64 +++ b/test/db/asm/riscv_64 @@ -50,7 +50,7 @@ d "lw s9, 0x64(sp)" 965c 0x40 (set s9 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv d "lw s10, 0x60(sp)" 065d 0x40 (set s10 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x60)))) (loadw 0 32 (+ (var sp) (bv 64 0x60))))) d "lw s11, 0x5c(sp)" f64d 0x40 (set s11 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x5c)))) (loadw 0 32 (+ (var sp) (bv 64 0x5c))))) d "addi sp, sp, 0x90" 4961 0x40 (set sp (+ (var sp) (bv 64 0x90))) -d "ret" 8280 0x40 (seq nop (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "ret" 8280 0x40 (seq (set jalr_target (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe))) nop (jmp (var jalr_target))) d "lw a5, 0x18(sp)" e247 0x40 (set a5 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x18)))) (loadw 0 32 (+ (var sp) (bv 64 0x18))))) d "beqz a5, 0x2d8" 63890726 0x66 (branch (== (var a5) (bv 64 0x0)) (jmp (bv 64 0x2d8)) (jmp (bv 64 0x6a))) d "lw s0, 0x1c(sp)" 7244 0x40 (set s0 (cast 64 (msb (loadw 0 32 (+ (var sp) (bv 64 0x1c)))) (loadw 0 32 (+ (var sp) (bv 64 0x1c))))) @@ -192,7 +192,8 @@ d "mv t2, a4" ba83 0x1c0 (set t2 (var a4)) d "add t6, t6, a3" b69f 0x1c0 (set t6 (+ (var t6) (var a3))) d "ori a5, a5, 0x89" 93e79708 0x0 (set a5 (| (var a5) (bv 64 0x89))) d "xori a5, a5, 0x431" 93c71743 0x0 (set a5 (^ (var a5) (bv 64 0x431))) -d "jalr ra" e7800000 0x30 (seq (set ra (bv 64 0x34)) (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "jalr ra" e7800000 0x30 (seq (set jalr_target (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe))) (set ra (bv 64 0x34)) (jmp (var jalr_target))) +d "jalr a0, 4(a0)" 67054500 0x0 (seq (set jalr_target (& (+ (var a0) (bv 64 0x4)) (bv 64 0xfffffffffffffffe))) (set a0 (bv 64 0x4)) (jmp (var jalr_target))) d "slti zero, ra, 0xc" 13a0c000 0x0 nop d "sltiu zero, ra, 0xc" 13b0c000 0x0 nop d "slti t0, ra, 0xc" 93a2c000 0x0 (set t0 (ite (&& (sle (var ra) (bv 64 0xc)) (! (== (var ra) (bv 64 0xc)))) (bv 64 0x1) (bv 64 0x0))) @@ -292,13 +293,19 @@ d "mulhsu t0, t1, t2" b3227302 0x0 (set t0 (cast 64 false (>> (* (cast 128 (msb d "mulhsu a0, a1, a2" 33a5c502 0x0 (set a0 (cast 64 false (>> (* (cast 128 (msb (var a1)) (var a1)) (cast 128 false (var a2))) (bv 8 0x40) false))) d "mulhsu t3, t4, t5" 33aeee03 0x0 (set t3 (cast 64 false (>> (* (cast 128 (msb (var t4)) (var t4)) (cast 128 false (var t5))) (bv 8 0x40) false))) # ----------------------------- DIV ----------------------------- -d "div a3, a3, a7" b3c61603 0x0 (set a3 (sdiv (var a3) (var a7))) -d "div t4, t6, t4" b3cedf03 0x0 (set t4 (sdiv (var t6) (var t4))) -d "div a4, a4, a3" 3347d702 0x0 (set a4 (sdiv (var a4) (var a3))) +d "div a0, a1, a2" 33c5c502 0x0 (set a0 (ite (is_zero (var a2)) (bv 64 0xffffffffffffffff) (sdiv (var a1) (var a2)))) +d "div a3, a3, a7" b3c61603 0x0 (set a3 (ite (is_zero (var a7)) (bv 64 0xffffffffffffffff) (sdiv (var a3) (var a7)))) +d "div t4, t6, t4" b3cedf03 0x0 (set t4 (ite (is_zero (var t4)) (bv 64 0xffffffffffffffff) (sdiv (var t6) (var t4)))) +d "div a4, a4, a3" 3347d702 0x0 (set a4 (ite (is_zero (var a3)) (bv 64 0xffffffffffffffff) (sdiv (var a4) (var a3)))) # ----------------------------- DIVU ----------------------------- -d "divu a6, s2, s10" 3358a903 0x0 (set a6 (div (var s2) (var s10))) -d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (div (var a5) (var t5))) -d "divu s1, a0, s2" b3542503 0x0 (set s1 (div (var a0) (var s2))) +d "divu a0, a1, a2" 33d5c502 0x0 (set a0 (ite (is_zero (var a2)) (bv 64 0xffffffffffffffff) (div (var a1) (var a2)))) +d "divu a6, s2, s10" 3358a903 0x0 (set a6 (ite (is_zero (var s10)) (bv 64 0xffffffffffffffff) (div (var s2) (var s10)))) +d "divu s7, a5, t5" b3dbe703 0x0 (set s7 (ite (is_zero (var t5)) (bv 64 0xffffffffffffffff) (div (var a5) (var t5)))) +d "divu s1, a0, s2" b3542503 0x0 (set s1 (ite (is_zero (var s2)) (bv 64 0xffffffffffffffff) (div (var a0) (var s2)))) +# ----------------------------- DIVW ----------------------------- +d "divw a0, a1, a2" 3bc5c502 0x0 (set a0 (cast 64 (msb (ite (is_zero (cast 32 false (var a2))) (bv 32 0xffffffff) (sdiv (cast 32 false (var a1)) (cast 32 false (var a2))))) (ite (is_zero (cast 32 false (var a2))) (bv 32 0xffffffff) (sdiv (cast 32 false (var a1)) (cast 32 false (var a2)))))) +# ----------------------------- DIVUW ----------------------------- +d "divuw a0, a1, a2" 3bd5c502 0x0 (set a0 (cast 64 (msb (ite (is_zero (cast 32 false (var a2))) (bv 32 0xffffffff) (div (cast 32 false (var a1)) (cast 32 false (var a2))))) (ite (is_zero (cast 32 false (var a2))) (bv 32 0xffffffff) (div (cast 32 false (var a1)) (cast 32 false (var a2)))))) # ----------------------------- REM ----------------------------- d "rem t6, a4, a7" b36f1703 0x0 (set t6 (smod (var a4) (var a7))) d "rem a5, a0, a4" b367e502 0x0 (set a5 (smod (var a0) (var a4))) @@ -312,9 +319,9 @@ d "nop" 0100 0x0 nop d "c.nop 1" 0500 0x0 nop d "c.nop 2" 0900 0x0 nop # ----------------------------- C_JALR ----------------------------- -d "jalr ra" 8290 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) -d "jalr s0" 0294 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var s0) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) -d "jalr a5" 8297 0x0 (seq (set ra (bv 64 0x2)) (jmp (& (+ (var a5) (bv 64 0x0)) (bv 64 0xfffffffffffffffe)))) +d "jalr ra" 8290 0x0 (seq (set jalr_target (& (+ (var ra) (bv 64 0x0)) (bv 64 0xfffffffffffffffe))) (set ra (bv 64 0x2)) (jmp (var jalr_target))) +d "jalr s0" 0294 0x0 (seq (set jalr_target (& (+ (var s0) (bv 64 0x0)) (bv 64 0xfffffffffffffffe))) (set ra (bv 64 0x2)) (jmp (var jalr_target))) +d "jalr a5" 8297 0x0 (seq (set jalr_target (& (+ (var a5) (bv 64 0x0)) (bv 64 0xfffffffffffffffe))) (set ra (bv 64 0x2)) (jmp (var jalr_target))) # ----------------------------- C_EBREAK ----------------------------- d "ebreak" 0290 0x0 (goto ebreak) d "ebreak" 0290 0x0 (goto ebreak) From 36a85d7e5ff23be4badb4de4460802ff2ae248cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Mon, 20 Jul 2026 00:51:51 +0300 Subject: [PATCH 10/10] fix details regression --- librz/arch/p/analysis/analysis_riscv_cs.c | 256 +++++--- librz/arch/p/analysis/analysis_riscv_utils.h | 130 ---- test/db/analysis/riscv | 634 +++++++++---------- 3 files changed, 485 insertions(+), 535 deletions(-) diff --git a/librz/arch/p/analysis/analysis_riscv_cs.c b/librz/arch/p/analysis/analysis_riscv_cs.c index 545378548b4..ebac4054083 100644 --- a/librz/arch/p/analysis/analysis_riscv_cs.c +++ b/librz/arch/p/analysis/analysis_riscv_cs.c @@ -16,51 +16,8 @@ #include -#define OPERAND(x) insn->detail->riscv.operands[x] -#define REGID(x) insn->detail->riscv.operands[x].reg -#define REG(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].reg) -#define IMM(x) insn->detail->riscv.operands[x].imm -#define MEMBASE(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].mem.base) -#define MEMINDEX(x) insn->detail->riscv.operands[x].mem.index -#define MEMDISP(x) insn->detail->riscv.operands[x].mem.disp -#define OPCOUNT() insn->detail->riscv.op_count -// TODO scale and disp - #define NEXT_ADDRESS(op) (op->addr + op->size) -#define CREATE_SRC_DST_3(op) \ - (op)->src[0] = rz_analysis_value_new(); \ - (op)->src[1] = rz_analysis_value_new(); \ - (op)->dst = rz_analysis_value_new(); - -#define CREATE_SRC_DST_2(op) \ - (op)->src[0] = rz_analysis_value_new(); \ - (op)->dst = rz_analysis_value_new(); - -#define SET_SRC_DST_3_REGS(op) \ - CREATE_SRC_DST_3(op); \ - (op)->dst->reg = riscv_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \ - (op)->src[0]->reg = riscv_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \ - (op)->src[1]->reg = riscv_reg_get(analysis->reg, REG(2), RZ_REG_TYPE_GPR); - -#define SET_SRC_DST_3_IMM(op) \ - CREATE_SRC_DST_3(op); \ - (op)->dst->reg = riscv_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \ - (op)->src[0]->reg = riscv_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \ - (op)->src[1]->imm = IMM(2); - -#define SET_SRC_DST_2_REGS(op) \ - CREATE_SRC_DST_2(op); \ - (op)->dst->reg = riscv_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \ - (op)->src[0]->reg = riscv_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); - -#define SET_SRC_DST_3_REG_OR_IMM(op) \ - if (OPERAND(2).type == RISCV_OP_IMM) { \ - SET_SRC_DST_3_IMM(op); \ - } else if (OPERAND(2).type == RISCV_OP_REG) { \ - SET_SRC_DST_3_REGS(op); \ - } - static void set_stack_effect(RzAnalysisOp *op, cs_insn *insn); static RzRegItem *riscv_reg_get(const RzReg *reg, const char *name, int type) { @@ -71,6 +28,134 @@ static RzRegItem *riscv_reg_get(const RzReg *reg, const char *name, int type) { return rz_reg_get(reg, name, type); } +static cs_riscv_op *riscv_operand(cs_insn *insn, ut8 n) { + rz_return_val_if_fail(insn && insn->detail && n < insn->detail->riscv.op_count, NULL); + return &insn->detail->riscv.operands[n]; +} + +static bool riscv_operand_is(cs_insn *insn, ut8 n, riscv_op_type type) { + return insn && insn->detail && n < insn->detail->riscv.op_count && insn->detail->riscv.operands[n].type == type; +} + +static const char *riscv_reg_name(csh handle, cs_insn *insn, ut8 n) { + rz_return_val_if_fail(riscv_operand_is(insn, n, RISCV_OP_REG), NULL); + return cs_reg_name(handle, riscv_operand(insn, n)->reg); +} + +static ut32 riscv_reg_id(cs_insn *insn, ut8 n) { + rz_return_val_if_fail(riscv_operand_is(insn, n, RISCV_OP_REG), RISCV_REG_INVALID); + return riscv_operand(insn, n)->reg; +} + +static st64 riscv_imm(cs_insn *insn, ut8 n) { + rz_return_val_if_fail(riscv_operand_is(insn, n, RISCV_OP_IMM), INT64_MAX); + return riscv_operand(insn, n)->imm; +} + +static cs_riscv_op *riscv_memory_operand(cs_insn *insn, ut8 n) { + rz_return_val_if_fail(riscv_operand_is(insn, n, RISCV_OP_MEM), NULL); + return riscv_operand(insn, n); +} + +static bool riscv_memory_operand_is_based_on(cs_insn *insn, ut8 n, ut32 reg) { + return riscv_operand_is(insn, n, RISCV_OP_MEM) && riscv_memory_operand(insn, n)->mem.base == reg; +} + +static cs_riscv_op *find_memory_reference(cs_insn *insn) { + for (int i = 0; i < insn->detail->riscv.op_count; i++) { + cs_riscv_op *op = riscv_operand(insn, i); + if (op && op->type == RISCV_OP_MEM) { + return op; + } + } + return NULL; +} + +static bool riscv_destination_is_sp(cs_insn *insn) { + return riscv_operand_is(insn, 0, RISCV_OP_REG) && riscv_reg_id(insn, 0) == RISCV_REG_X2; +} + +static ut64 find_jump_target(cs_insn *insn) { + switch (insn->id) { + case RISCV_INS_C_BEQZ: + case RISCV_INS_C_BNEZ: + case RISCV_INS_BEQ: + case RISCV_INS_BNE: + case RISCV_INS_BLT: + case RISCV_INS_BGE: + case RISCV_INS_BLTU: + case RISCV_INS_BGEU: + return riscv_imm(insn, 2); + case RISCV_INS_C_J: + case RISCV_INS_C_JAL: + case RISCV_INS_JAL: + return riscv_imm(insn, 1); + case RISCV_INS_JALR: + return riscv_imm(insn, 2); + default: + return INT64_MAX; + } +} + +static bool jalr_base_is_zero(cs_insn *insn) { + return riscv_reg_id(insn, 1) == RISCV_REG_X0; +} + +static st64 find_hint_immediate(cs_insn *insn) { + switch (insn->id) { + case RISCV_INS_LUI: + case RISCV_INS_C_LUI: + case RISCV_INS_LI: + case RISCV_INS_AUIPC: + case RISCV_INS_C_LI: + return riscv_operand_is(insn, 1, RISCV_OP_IMM) ? riscv_imm(insn, 1) : INT64_MAX; + default: + return riscv_operand_is(insn, 2, RISCV_OP_IMM) ? riscv_imm(insn, 2) : INT64_MAX; + } +} + +static void create_src_dst_3(RzAnalysisOp *op) { + op->src[0] = rz_analysis_value_new(); + op->src[1] = rz_analysis_value_new(); + op->dst = rz_analysis_value_new(); +} + +static void create_src_dst_2(RzAnalysisOp *op) { + op->src[0] = rz_analysis_value_new(); + op->dst = rz_analysis_value_new(); +} + +static void set_src_dst_3_regs(RzAnalysis *analysis, RzAnalysisOp *op, csh handle, cs_insn *insn) { + create_src_dst_3(op); + op->dst->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 0), RZ_REG_TYPE_GPR); + op->src[0]->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 1), RZ_REG_TYPE_GPR); + op->src[1]->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 2), RZ_REG_TYPE_GPR); +} + +static void set_src_dst_3_imm(RzAnalysis *analysis, RzAnalysisOp *op, csh handle, cs_insn *insn) { + create_src_dst_3(op); + op->dst->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 0), RZ_REG_TYPE_GPR); + op->src[0]->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 1), RZ_REG_TYPE_GPR); + op->src[1]->imm = riscv_imm(insn, 2); +} + +static void set_src_dst_2_regs(RzAnalysis *analysis, RzAnalysisOp *op, csh handle, cs_insn *insn) { + create_src_dst_2(op); + op->dst->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 0), RZ_REG_TYPE_GPR); + op->src[0]->reg = riscv_reg_get(analysis->reg, riscv_reg_name(handle, insn, 1), RZ_REG_TYPE_GPR); +} + +static void set_src_dst_3_reg_or_imm(RzAnalysis *analysis, RzAnalysisOp *op, csh handle, cs_insn *insn) { + if (!riscv_operand_is(insn, 0, RISCV_OP_REG) || !riscv_operand_is(insn, 1, RISCV_OP_REG)) { + return; + } + if (riscv_operand_is(insn, 2, RISCV_OP_IMM)) { + set_src_dst_3_imm(analysis, op, handle, insn); + } else if (riscv_operand_is(insn, 2, RISCV_OP_REG)) { + set_src_dst_3_regs(analysis, op, handle, insn); + } +} + static RzStructuredData *riscv_opex(csh handle, cs_insn *insn) { if (!insn->detail) { return NULL; @@ -121,13 +206,14 @@ static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num if (!reg) { return -1; } - switch (OPERAND(reg_num).type) { + cs_riscv_op *op = riscv_operand(insn, reg_num); + switch (op->type) { case RISCV_OP_REG: - reg->name = (char *)cs_reg_name(handle, OPERAND(reg_num).reg); + reg->name = (char *)cs_reg_name(handle, op->reg); break; case RISCV_OP_MEM: - if (OPERAND(reg_num).mem.base != RISCV_REG_INVALID) { - reg->name = (char *)cs_reg_name(handle, OPERAND(reg_num).mem.base); + if (op->mem.base != RISCV_REG_INVALID) { + reg->name = (char *)cs_reg_name(handle, op->mem.base); } default: break; @@ -156,31 +242,33 @@ static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_i RiscvContext *ctx = (RiscvContext *)analysis->plugin_data; switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) { case RZ_ANALYSIS_OP_TYPE_LOAD: - if (OPERAND(1).type == RISCV_OP_MEM) { + if (riscv_operand_is(insn, 1, RISCV_OP_MEM)) { + cs_riscv_op *mem = riscv_memory_operand(insn, 1); ZERO_FILL(ctx->reg); op->dst = rz_analysis_value_new(); op->dst->type = RZ_ANALYSIS_VAL_REG; - op->dst->reg = riscv_reg_get(analysis->reg, cs_reg_name(*handle, FIRST_WRITTEN_REGID(insn)), RZ_REG_TYPE_GPR); + op->dst->reg = riscv_reg_get(analysis->reg, riscv_reg_name(*handle, insn, 0), RZ_REG_TYPE_GPR); op->src[0] = rz_analysis_value_new(); op->src[0]->type = RZ_ANALYSIS_VAL_MEM; op->src[0]->reg = &ctx->reg; parse_reg_name(op->src[0]->reg, *handle, insn, 1); - op->src[0]->delta = OPERAND(1).mem.disp; + op->src[0]->delta = mem->mem.disp; op->src[0]->memref = op->refptr; } break; case RZ_ANALYSIS_OP_TYPE_STORE: - if (OPERAND(1).type == RISCV_OP_MEM) { + if (riscv_operand_is(insn, 1, RISCV_OP_MEM)) { + cs_riscv_op *mem = riscv_memory_operand(insn, 1); ZERO_FILL(ctx->reg); op->dst = rz_analysis_value_new(); op->dst->type = RZ_ANALYSIS_VAL_MEM; op->dst->reg = &ctx->reg; parse_reg_name(op->dst->reg, *handle, insn, 1); - op->dst->delta = OPERAND(1).mem.disp; + op->dst->delta = mem->mem.disp; op->dst->memref = op->refptr; op->src[0] = rz_analysis_value_new(); op->src[0]->type = RZ_ANALYSIS_VAL_REG; - op->src[0]->reg = riscv_reg_get(analysis->reg, cs_reg_name(*handle, FIRST_READ_REGID(insn)), RZ_REG_TYPE_GPR); + op->src[0]->reg = riscv_reg_get(analysis->reg, riscv_reg_name(*handle, insn, 0), RZ_REG_TYPE_GPR); } break; case RZ_ANALYSIS_OP_TYPE_SHL: @@ -191,23 +279,23 @@ static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_i case RZ_ANALYSIS_OP_TYPE_AND: case RZ_ANALYSIS_OP_TYPE_ADD: case RZ_ANALYSIS_OP_TYPE_OR: - SET_SRC_DST_3_REG_OR_IMM(op); + set_src_dst_3_reg_or_imm(analysis, op, *handle, insn); break; case RZ_ANALYSIS_OP_TYPE_MOV: - SET_SRC_DST_3_REG_OR_IMM(op); + set_src_dst_3_reg_or_imm(analysis, op, *handle, insn); break; case RZ_ANALYSIS_OP_TYPE_DIV: // UDIV - if (OPERAND(0).type == RISCV_OP_REG && OPERAND(1).type == RISCV_OP_REG && OPERAND(2).type == RISCV_OP_REG) { - SET_SRC_DST_3_REGS(op); - } else if (OPERAND(0).type == RISCV_OP_REG && OPERAND(1).type == RISCV_OP_REG) { - SET_SRC_DST_2_REGS(op); + if (riscv_operand_is(insn, 0, RISCV_OP_REG) && riscv_operand_is(insn, 1, RISCV_OP_REG) && riscv_operand_is(insn, 2, RISCV_OP_REG)) { + set_src_dst_3_regs(analysis, op, *handle, insn); + } else if (riscv_operand_is(insn, 0, RISCV_OP_REG) && riscv_operand_is(insn, 1, RISCV_OP_REG)) { + set_src_dst_2_regs(analysis, op, *handle, insn); } else { RZ_LOG_ERROR("riscv: unknown div opcode at 0x%08" PFMT64x "\n", op->addr); } break; } if (insn && (insn->id == RISCV_INS_SLTI || insn->id == RISCV_INS_SLTIU)) { - SET_SRC_DST_3_IMM(op); + set_src_dst_3_imm(analysis, op, *handle, insn); } } @@ -468,7 +556,7 @@ static void set_op_val(RzAnalysisOp *op, cs_insn *insn) { return; } - st64 imm = FIRST_IMM(insn); + st64 imm = find_hint_immediate(insn); if (imm != INT64_MAX) { switch (insn->id) { case RISCV_INS_LUI: @@ -744,17 +832,15 @@ static void set_op_extra_metadata(RzAnalysis *analysis, RzAnalysisOp *op, csh ha return; } // Set destination register name - if (insn->detail->riscv.op_count > 0 && insn->detail->riscv.operands[0].type == RISCV_OP_REG && (insn->detail->riscv.operands[0].access & CS_AC_WRITE)) { - op->reg = cs_reg_name(handle, insn->detail->riscv.operands[0].reg); + if (riscv_operand_is(insn, 0, RISCV_OP_REG)) { + op->reg = riscv_reg_name(handle, insn, 0); } // Set indirect register name (base for loads/stores) - for (int i = 0; i < insn->detail->riscv.op_count; i++) { - if (insn->detail->riscv.operands[i].type == RISCV_OP_MEM) { - op->ireg = cs_reg_name(handle, insn->detail->riscv.operands[i].mem.base); - op->disp = insn->detail->riscv.operands[i].mem.disp; - break; - } + cs_riscv_op *mem = find_memory_reference(insn); + if (mem) { + op->ireg = cs_reg_name(handle, mem->mem.base); + op->disp = mem->mem.disp; } // Set datatype @@ -844,7 +930,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf case RISCV_INS_C_JAL: { bool is_call = insn->id == RISCV_INS_C_JAL; op->type = is_call ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = SINGLE_IMM(insn); + op->jump = find_jump_target(insn); op->fail = UINT64_MAX; break; } @@ -857,7 +943,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf // no fallthrough op->fail = UINT64_MAX; // special case: known base register, namely the always-0 register - bool is_known_base = FIRST_READ_REGID(insn) == RISCV_REG_X0; + bool is_known_base = jalr_base_is_zero(insn); if (group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_CALL)) { op->type = is_known_base ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_RCALL; @@ -865,7 +951,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf op->type = is_known_base ? RZ_ANALYSIS_OP_TYPE_JMP : RZ_ANALYSIS_OP_TYPE_RJMP; } if (is_known_base) { - op->jump = SINGLE_IMM(insn); + op->jump = find_jump_target(insn); } break; @@ -873,7 +959,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf bool is_call = group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_CALL); op->type = is_call ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = SINGLE_IMM(insn); + op->jump = find_jump_target(insn); op->fail = UINT64_MAX; break; } @@ -1288,11 +1374,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf case RISCV_INS_C_BEQZ: case RISCV_INS_C_BNEZ: op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - if (insn->id == RISCV_INS_C_BEQZ || insn->id == RISCV_INS_C_BNEZ) { - op->jump = IMM(1); - } else { - op->jump = IMM(2); - } + op->jump = find_jump_target(insn); op->fail = NEXT_ADDRESS(op); break; @@ -2224,7 +2306,7 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { static void set_stack_effect(RzAnalysisOp *op, cs_insn *insn) { op->stackop = RZ_ANALYSIS_STACK_NOP; - if (!IS_REG_WRITTEN(insn, RISCV_REG_X2)) { + if (!riscv_destination_is_sp(insn)) { return; } @@ -2233,24 +2315,28 @@ static void set_stack_effect(RzAnalysisOp *op, cs_insn *insn) { // incremented or decremented ? switch (op->type) { case RZ_ANALYSIS_OP_TYPE_ADD: - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = -MAYBE_IMM(insn); + if (riscv_operand_is(insn, 2, RISCV_OP_IMM)) { + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = -riscv_imm(insn, 2); + } return; case RZ_ANALYSIS_OP_TYPE_SUB: - op->stackop = RZ_ANALYSIS_STACK_DEC; - op->stackptr = MAYBE_IMM(insn); + if (riscv_operand_is(insn, 2, RISCV_OP_IMM)) { + op->stackop = RZ_ANALYSIS_STACK_DEC; + op->stackptr = riscv_imm(insn, 2); + } return; case RZ_ANALYSIS_OP_TYPE_LOAD: - if (MEM_BASE(insn, RISCV_REG_X2)) { + if (riscv_memory_operand_is_based_on(insn, 1, RISCV_REG_X2)) { op->stackop = RZ_ANALYSIS_STACK_GET; op->stackptr = op->refptr; } return; case RZ_ANALYSIS_OP_TYPE_STORE: - if (MEM_BASE(insn, RISCV_REG_X2)) { + if (riscv_memory_operand_is_based_on(insn, 1, RISCV_REG_X2)) { op->stackop = RZ_ANALYSIS_STACK_SET; op->stackptr = op->refptr; } diff --git a/librz/arch/p/analysis/analysis_riscv_utils.h b/librz/arch/p/analysis/analysis_riscv_utils.h index 753190849a4..cac7e3e87f1 100644 --- a/librz/arch/p/analysis/analysis_riscv_utils.h +++ b/librz/arch/p/analysis/analysis_riscv_utils.h @@ -4,134 +4,4 @@ #ifndef ANALYSIS_RISCV_UTILS_H #define ANALYSIS_RISCV_UTILS_H -#include - -#include -#include -#include - -// A more high-level alternative to direct indexing that can get immediates and operands without exact indices -// While also enforcing high-level constraints such as "exactly one immediate operand is present" or "at most -// one operand is present" or "get the single register that is read/written" - -static inline ut32 find_at_most_one_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type, const char *type_str) { - ut32 first = UT32_MAX; - for (ut32 i = 0; i < op_count; i++) { - if (operands[i].type == type) { - if (first == UT32_MAX) { - first = i; - } else { - RZ_LOG_DEBUG("Expected exactly one %s operand, two elements matched (the %ith and %ith elements)", type_str, first, i); - } - } - } - return first; -} - -static inline ut32 find_at_most_one_imm(cs_riscv_op *operands, uint8_t op_count) { - return find_at_most_one_op(operands, op_count, RISCV_OP_IMM, "immediate"); -} - -static inline ut32 find_exactly_one_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type, const char *type_str) { - return find_at_most_one_op(operands, op_count, type, type_str); -} - -static inline ut32 find_exactly_one_imm(cs_riscv_op *operands, uint8_t op_count) { - return find_exactly_one_op(operands, op_count, RISCV_OP_IMM, "immediate"); -} - -static inline int64_t get_exactly_one_immediate(cs_riscv_op *operands, uint8_t op_count) { - ut32 idx = find_exactly_one_imm(operands, op_count); - if (idx < op_count) { - return operands[idx].imm; - } - return INT64_MAX; -} - -static inline int64_t get_at_most_one_immediate(cs_riscv_op *operands, uint8_t op_count) { - ut32 idx = find_at_most_one_imm(operands, op_count); - if (idx < op_count) { - return operands[idx].imm; - } - return INT64_MAX; -} - -#define SINGLE_IMM(insn) get_exactly_one_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); -#define MAYBE_IMM(insn) get_at_most_one_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); - -static inline ut32 find_first_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type) { - for (ut32 i = 0; i < op_count; i++) { - if (operands[i].type == type) { - return i; - } - } - return UT32_MAX; -} - -static inline ut32 find_first_imm(cs_riscv_op *operands, uint8_t op_count) { - return find_first_op(operands, op_count, RISCV_OP_IMM); -} - -static inline int64_t get_first_immediate(cs_riscv_op *operands, uint8_t op_count) { - ut32 idx = find_first_imm(operands, op_count); - if (idx < op_count) { - return operands[idx].imm; - } - return INT64_MAX; -} - -#define FIRST_IMM(insn) get_first_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); - -static inline ut32 get_any_reg_accessed_as(cs_riscv_op *operands, uint8_t op_count, cs_ac_type access) { - for (ut32 i = 0; i < op_count; i++) { - if (operands[i].type == RISCV_OP_REG && (operands[i].access & access)) { - return operands[i].reg; - } - } - RZ_LOG_DEBUG("Expected at least one register with %s access, found none", access == CS_AC_READ ? "read" : "write"); - return 0; // dummy for type checking, never reached -} - -static inline ut32 first_read_register(cs_riscv_op *operands, uint8_t op_count) { - return get_any_reg_accessed_as(operands, op_count, CS_AC_READ); -} - -static inline ut32 first_written_register(cs_riscv_op *operands, uint8_t op_count) { - return get_any_reg_accessed_as(operands, op_count, CS_AC_WRITE); -} - -#define FIRST_READ_REGID(insn) first_read_register(insn->detail->riscv.operands, insn->detail->riscv.op_count) -#define FIRST_WRITTEN_REGID(insn) first_written_register(insn->detail->riscv.operands, insn->detail->riscv.op_count) - -// check if a certain reg is ever accessed as read/write register -static inline bool is_any_reg_accessed_as(cs_riscv_op *operands, uint8_t op_count, ut32 reg, cs_ac_type access) { - for (int i = 0; i < op_count; i++) { - if (operands[i].type == RISCV_OP_REG && operands[i].reg == reg && (operands[i].access & access)) { - return true; - } - } - return false; -} - -static inline bool is_reg_written(cs_riscv_op *operands, uint8_t op_count, ut32 reg) { - return is_any_reg_accessed_as(operands, op_count, reg, CS_AC_WRITE); -} -static inline bool is_reg_read(cs_riscv_op *operands, uint8_t op_count, ut32 reg) { - return is_any_reg_accessed_as(operands, op_count, reg, CS_AC_READ); -} - -#define IS_REG_WRITTEN(insn, reg) is_reg_written(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) -#define IS_REG_READ(insn, reg) is_reg_read(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) - -static inline bool is_any_reg_memory_base(cs_riscv_op *operands, uint8_t op_count, unsigned int reg) { - for (ut32 i = 0; i < op_count; i++) { - if (operands[i].type == RISCV_OP_MEM && operands[i].mem.base == reg) { - return true; - } - } - return false; -} - -#define MEM_BASE(insn, reg) is_any_reg_memory_base(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) - #endif /* ANALYSIS_RISCV_UTILS_H */ diff --git a/test/db/analysis/riscv b/test/db/analysis/riscv index 84495914c17..efde88e33fa 100644 --- a/test/db/analysis/riscv +++ b/test/db/analysis/riscv @@ -835,13 +835,13 @@ nth paddr vaddr bind type size lib name 8 0x00000570 0x00010570 GLOBAL FUNC 0 imp.__libc_start_main --- vector reductions : ; CALL XREF from main @ 0x10938 -/ sym.test_reductions(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg_7fffffffffffffcfh, int64_t arg_7fffffffffffffd7h, int64_t arg_7fffffffffffffe7h, int64_t arg_7fffffffffffffefh, int64_t arg_7ffffffffffffff7h); +/ sym.test_reductions(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg8, int64_t arg_7fffffffffffffcfh, int64_t arg_7fffffffffffffd7h, int64_t arg_7fffffffffffffe7h, int64_t arg_7fffffffffffffefh, int64_t arg_7ffffffffffffff7h); | : ; arg int64_t arg1 @ a0 | : ; arg int64_t arg2 @ a1 | : ; arg int64_t arg3 @ a2 | : ; arg int64_t arg4 @ a3 | : ; arg int64_t arg5 @ a4 -| : ; arg int64_t arg6 @ a5 +| : ; arg int64_t arg8 @ a7 | : ; var int64_t var_c0h @ stack - 0xc0 | : ; arg int64_t arg_7fffffffffffffcfh @ stack + 0x7fffffffffffffcf | : ; arg int64_t arg_7fffffffffffffd7h @ stack + 0x7fffffffffffffd7 @@ -861,12 +861,12 @@ nth paddr vaddr bind type size lib name | : 0x00010c76 26f5 sd s1, 0xa8(sp) | : 0x00010c78 22ad fsd fs0, 0x98(sp) | : 0x00010c7a 26a9 fsd fs1, 0x90(sp) -| : 0x00010c7c 2a83 mv t1, a0 +| : 0x00010c7c 2a83 mv t1, a0 ; arg1 | : 0x00010c7e 33015140 sub sp, sp, t0 | : 0x00010c82 aa9e add t4, t4, a0 ; arg1 -| : 0x00010c84 aa87 mv a5, a0 -| .--> 0x00010c86 07e10702 vle32.v v2, (a5) ; arg6 -| :: 0x00010c8a c107 addi a5, a5, 0x10 ; arg6 +| : 0x00010c84 aa87 mv a5, a0 ; arg1 +| .--> 0x00010c86 07e10702 vle32.v v2, (a5) +| :: 0x00010c8a c107 addi a5, a5, 0x10 | :: 0x00010c8c d7001102 vadd.vv v1, v1, v2 | `==< 0x00010c90 e39bd7ff bne a5, t4, 0x10c86 | : 0x00010c94 f32620c2 csrr a3, vlenb @@ -875,29 +875,29 @@ nth paddr vaddr bind type size lib name | : 0x00010c9e 5774000d vsetvli s0, zero, e0x20, m1, ta, ma | : 0x00010ca2 d730005e vmv.v.i v1, 0 | : 0x00010ca6 1147 li a4, 4 -| .--> 0x00010ca8 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| .--> 0x00010ca8 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg5 | :: 0x00010cac 07e10602 vle32.v v2, (a3) ; arg4 -| :: 0x00010cb0 13982700 slli a6, a5, 2 ; arg6 -| :: 0x00010cb4 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010cb0 13982700 slli a6, a5, 2 +| :: 0x00010cb4 1d8f sub a4, a4, a5 ; arg5 | :: 0x00010cb6 c296 add a3, a3, a6 ; arg4 | :: 0x00010cb8 d7802002 vadd.vv v1, v2, v1 | `==< 0x00010cbc 75f7 bnez a4, 0x10ca8 -| : 0x00010cbe d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| : 0x00010cbe d777000d vsetvli a5, zero, e0x20, m1, ta, ma | : 0x00010cc2 57610042 vmv.s.x v2, zero | : 0x00010cc6 f32720c2 csrr a5, vlenb | : 0x00010cca d7201102 vredsum.vs v1, v1, v2 -| : 0x00010cce c107 addi a5, a5, 0x10 ; arg6 +| : 0x00010cce c107 addi a5, a5, 0x10 | : 0x00010cd0 37070080 lui a4, 0x80000 -| : 0x00010cd4 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010cd4 3308f100 add a6, sp, a5 | : 0x00010cd8 5741075e vmv.v.x v2, a4 | : 0x00010cdc c286 mv a3, a6 | : 0x00010cde 1147 li a4, 4 | : 0x00010ce0 d7281042 vmv.x.s a7, v1 -| .--> 0x00010ce4 d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 -| :: 0x00010ce8 27e10602 vse32.v v2, (a3) ; arg4 -| :: 0x00010cec 1d8f sub a4, a4, a5 ; arg6 +| .--> 0x00010ce4 d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg5 +| :: 0x00010ce8 27e10602 vse32.v v2, (a3) +| :: 0x00010cec 1d8f sub a4, a4, a5 ; arg5 | :: 0x00010cee 8a07 slli a5, a5, 2 -| :: 0x00010cf0 be96 add a3, a3, a5 ; arg6 +| :: 0x00010cf0 be96 add a3, a3, a5 | `==< 0x00010cf2 6dfb bnez a4, 0x10ce4 | : 0x00010cf4 577002cd vsetivli zero, 4, e0x20, m1, ta, ma | : 0x00010cf8 87600802 vle32.v v1, (a6) @@ -906,35 +906,35 @@ nth paddr vaddr bind type size lib name | :: 0x00010d02 d700111e vmax.vv v1, v1, v2 | `==< 0x00010d06 e39baefe bne t4, a0, 0x10cfc | : 0x00010d0a a7600802 vse32.v v1, (a6) -| : 0x00010d0e d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| : 0x00010d0e d777000d vsetvli a5, zero, e0x20, m1, ta, ma | : 0x00010d12 d7400e5e vmv.v.x v1, t3 | : 0x00010d16 c286 mv a3, a6 | : 0x00010d18 1147 li a4, 4 | : 0x00010d1a 5731109e vmv1r.v v2, v1 -| .--> 0x00010d1e d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 -| :: 0x00010d22 07e20602 vle32.v v4, (a3) ; arg4 -| :: 0x00010d26 13952700 slli a0, a5, 2 ; arg6 -| :: 0x00010d2a 1d8f sub a4, a4, a5 ; arg6 -| :: 0x00010d2c aa96 add a3, a3, a0 ; arg4 +| .--> 0x00010d1e d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg5 +| :: 0x00010d22 07e20602 vle32.v v4, (a3) +| :: 0x00010d26 13952700 slli a0, a5, 2 +| :: 0x00010d2a 1d8f sub a4, a4, a5 ; arg5 +| :: 0x00010d2c aa96 add a3, a3, a0 | :: 0x00010d2e 5701411e vmax.vv v2, v4, v2 | `==< 0x00010d32 75f7 bnez a4, 0x10d1e | : 0x00010d34 5774000d vsetvli s0, zero, e0x20, m1, ta, ma | : 0x00010d38 b7070080 lui a5, 0x80000 | : 0x00010d3c 57e20742 vmv.s.x v4, a5 -| : 0x00010d40 fd37 addiw a5, a5, -1 ; arg6 +| : 0x00010d40 fd37 addiw a5, a5, -1 | : 0x00010d42 5721221e vredmax.vs v2, v2, v4 | : 0x00010d46 57c2075e vmv.v.x v4, a5 | : 0x00010d4a f32720c2 csrr a5, vlenb -| : 0x00010d4e 93870702 addi a5, a5, 0x20 ; arg6 -| : 0x00010d52 3305f100 add a0, sp, a5 ; arg6 +| : 0x00010d4e 93870702 addi a5, a5, 0x20 +| : 0x00010d52 3305f100 add a0, sp, a5 | : 0x00010d56 aa86 mv a3, a0 | : 0x00010d58 1147 li a4, 4 | : 0x00010d5a 572e2042 vmv.x.s t3, v2 -| .--> 0x00010d5e d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 -| :: 0x00010d62 27e20602 vse32.v v4, (a3) ; arg4 -| :: 0x00010d66 1d8f sub a4, a4, a5 ; arg6 +| .--> 0x00010d5e d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg5 +| :: 0x00010d62 27e20602 vse32.v v4, (a3) +| :: 0x00010d66 1d8f sub a4, a4, a5 ; arg5 | :: 0x00010d68 8a07 slli a5, a5, 2 -| :: 0x00010d6a be96 add a3, a3, a5 ; arg6 +| :: 0x00010d6a be96 add a3, a3, a5 | `==< 0x00010d6c 6dfb bnez a4, 0x10d5e | : 0x00010d6e 577002cd vsetivli zero, 4, e0x20, m1, ta, ma | : 0x00010d72 07610502 vle32.v v2, (a0) @@ -945,41 +945,41 @@ nth paddr vaddr bind type size lib name | : 0x00010d84 27610502 vse32.v v2, (a0) | : 0x00010d88 aa86 mv a3, a0 | : 0x00010d8a 1147 li a4, 4 -| .--> 0x00010d8c d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 -| :: 0x00010d90 07e10602 vle32.v v2, (a3) ; arg4 -| :: 0x00010d94 13952700 slli a0, a5, 2 ; arg6 -| :: 0x00010d98 1d8f sub a4, a4, a5 ; arg6 -| :: 0x00010d9a aa96 add a3, a3, a0 ; arg4 +| .--> 0x00010d8c d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg5 +| :: 0x00010d90 07e10602 vle32.v v2, (a3) +| :: 0x00010d94 13952700 slli a0, a5, 2 +| :: 0x00010d98 1d8f sub a4, a4, a5 ; arg5 +| :: 0x00010d9a aa96 add a3, a3, a0 | :: 0x00010d9c d7802016 vmin.vv v1, v2, v1 | `==< 0x00010da0 75f7 bnez a4, 0x10d8c | : 0x00010da2 b7070080 lui a5, 0x80000 | : 0x00010da6 577002cd vsetivli zero, 4, e0x20, m1, ta, ma -| : 0x00010daa fd37 addiw a5, a5, -1 ; arg6 +| : 0x00010daa fd37 addiw a5, a5, -1 | : 0x00010dac 57e20742 vmv.s.x v4, a5 | : 0x00010db0 57b10f5e vmv.v.i v2, -1 | : 0x00010db4 5774000d vsetvli s0, zero, e0x20, m1, ta, ma | : 0x00010db8 d7201216 vredmin.vs v1, v1, v4 | : 0x00010dbc 0563 lui t1, 1 | : 0x00010dbe 2e93 add t1, t1, a1 ; arg2 -| : 0x00010dc0 2e85 mv a0, a1 -| : 0x00010dc2 ae87 mv a5, a1 +| : 0x00010dc0 2e85 mv a0, a1 ; arg2 +| : 0x00010dc2 ae87 mv a5, a1 ; arg2 | : 0x00010dc4 d7261042 vmv.x.s a3, v1 | : 0x00010dc8 577002cd vsetivli zero, 4, e0x20, m1, ta, ma -| .--> 0x00010dcc 87e00702 vle32.v v1, (a5) ; arg6 -| :: 0x00010dd0 c107 addi a5, a5, 0x10 ; arg6 +| .--> 0x00010dcc 87e00702 vle32.v v1, (a5) +| :: 0x00010dd0 c107 addi a5, a5, 0x10 | :: 0x00010dd2 57812026 vand.vv v2, v2, v1 | `==< 0x00010dd6 e39b67fe bne a5, t1, 0x10dcc | : 0x00010dda f32720c2 csrr a5, vlenb -| : 0x00010dde 93870703 addi a5, a5, 0x30 ; arg6 -| : 0x00010de2 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010dde 93870703 addi a5, a5, 0x30 +| : 0x00010de2 3308f100 add a6, sp, a5 | : 0x00010de6 27610802 vse32.v v2, (a6) | : 0x00010dea 5774000d vsetvli s0, zero, e0x20, m1, ta, ma | : 0x00010dee d7b00f5e vmv.v.i v1, -1 | : 0x00010df2 1147 li a4, 4 -| .--> 0x00010df4 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| .--> 0x00010df4 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg5 | :: 0x00010df8 07610802 vle32.v v2, (a6) -| :: 0x00010dfc 939e2700 slli t4, a5, 2 ; arg6 -| :: 0x00010e00 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010dfc 939e2700 slli t4, a5, 2 +| :: 0x00010e00 1d8f sub a4, a4, a5 ; arg5 | :: 0x00010e02 7698 add a6, a6, t4 | :: 0x00010e04 d7802026 vand.vv v1, v2, v1 | `==< 0x00010e08 75f7 bnez a4, 0x10df4 @@ -995,16 +995,16 @@ nth paddr vaddr bind type size lib name | :: 0x00010e2a 5781202a vor.vv v2, v2, v1 | `==< 0x00010e2e e39b65fe bne a1, t1, 0x10e24 | : 0x00010e32 f32720c2 csrr a5, vlenb -| : 0x00010e36 93870704 addi a5, a5, 0x40 ; arg6 -| : 0x00010e3a 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010e36 93870704 addi a5, a5, 0x40 +| : 0x00010e3a 3308f100 add a6, sp, a5 | : 0x00010e3e 27610802 vse32.v v2, (a6) | : 0x00010e42 5774000d vsetvli s0, zero, e0x20, m1, ta, ma | : 0x00010e46 d730005e vmv.v.i v1, 0 | : 0x00010e4a 9145 li a1, 4 -| .--> 0x00010e4c d7f70509 vsetvli a5, a1, e0x20, m1, tu, ma ; arg6 +| .--> 0x00010e4c d7f70509 vsetvli a5, a1, e0x20, m1, tu, ma ; arg2 | :: 0x00010e50 07610802 vle32.v v2, (a6) -| :: 0x00010e54 939e2700 slli t4, a5, 2 ; arg6 -| :: 0x00010e58 9d8d sub a1, a1, a5 ; arg6 +| :: 0x00010e54 939e2700 slli t4, a5, 2 +| :: 0x00010e58 9d8d sub a1, a1, a5 ; arg2 | :: 0x00010e5a 7698 add a6, a6, t4 | :: 0x00010e5c d780202a vor.vv v1, v2, v1 | `==< 0x00010e60 f5f5 bnez a1, 0x10e4c @@ -1039,49 +1039,49 @@ nth paddr vaddr bind type size lib name | : 0x00010ec8 d7a0110e vredxor.vs v1, v1, v3 | : 0x00010ecc 856f lui t6, 1 | : 0x00010ece b29f add t6, t6, a2 ; arg3 -| : 0x00010ed0 328f mv t5, a2 -| : 0x00010ed2 b285 mv a1, a2 +| : 0x00010ed0 328f mv t5, a2 ; arg3 +| : 0x00010ed2 b285 mv a1, a2 ; arg3 | : 0x00010ed4 57281042 vmv.x.s a6, v1 | : 0x00010ed8 577002cd vsetivli zero, 4, e0x20, m1, ta, ma -| .--> 0x00010edc 87e00502 vle32.v v1, (a1) ; arg2 -| :: 0x00010ee0 c105 addi a1, a1, 0x10 ; arg2 +| .--> 0x00010edc 87e00502 vle32.v v1, (a1) +| :: 0x00010ee0 c105 addi a1, a1, 0x10 | :: 0x00010ee2 57912002 vfadd.vv v2, v2, v1 | `==< 0x00010ee6 e39bbffe bne t6, a1, 0x10edc | : 0x00010eea f32520c2 csrr a1, vlenb -| : 0x00010eee 93850506 addi a1, a1, 0x60 ; arg2 -| : 0x00010ef2 3303b100 add t1, sp, a1 ; arg2 +| : 0x00010eee 93850506 addi a1, a1, 0x60 +| : 0x00010ef2 3303b100 add t1, sp, a1 | : 0x00010ef6 27610302 vse32.v v2, (t1) | : 0x00010efa 530400f0 fmv.w.x fs0, zero | : 0x00010efe 9145 li a1, 4 -| .--> 0x00010f00 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| .--> 0x00010f00 57f5650c vsetvli a0, a1, e8, mf4, ta, ma | :: 0x00010f04 07610302 vle32.v v2, (t1) | :: 0x00010f08 57f000cd vsetivli zero, 1, e0x20, m1, ta, ma | :: 0x00010f0c d7500442 vfmv.s.f v1, fs0 | :: 0x00010f10 5770050d vsetvli zero, a0, e0x20, m1, ta, ma | :: 0x00010f14 931e2500 slli t4, a0, 2 -| :: 0x00010f18 898d sub a1, a1, a0 ; arg2 +| :: 0x00010f18 898d sub a1, a1, a0 | :: 0x00010f1a d790200e vfredosum.vs v1, v2, v1 | :: 0x00010f1e 7693 add t1, t1, t4 | :: 0x00010f20 57141042 vfmv.f.s fs0, v1 | `==< 0x00010f24 f1fd bnez a1, 0x10f00 | : 0x00010f26 cd62 lui t0, 0x13 ; 0x13000 ; "P\U00000005\U00000001" | : 0x00010f28 07a78202 flw fa4, 0x28(t0) -| : 0x00010f2c d775000d vsetvli a1, zero, e0x20, m1, ta, ma ; arg2 +| : 0x00010f2c d775000d vsetvli a1, zero, e0x20, m1, ta, ma | : 0x00010f30 732520c2 csrr a0, vlenb | : 0x00010f34 13050507 addi a0, a0, 0x70 | : 0x00010f38 d750075e vfmv.v.f v1, fa4 | : 0x00010f3c b30ea100 add t4, sp, a0 | : 0x00010f40 7683 mv t1, t4 | : 0x00010f42 9145 li a1, 4 -| .--> 0x00010f44 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| .--> 0x00010f44 57f5650c vsetvli a0, a1, e8, mf4, ta, ma | :: 0x00010f48 a7600302 vse32.v v1, (t1) -| :: 0x00010f4c 898d sub a1, a1, a0 ; arg2 +| :: 0x00010f4c 898d sub a1, a1, a0 | :: 0x00010f4e 0a05 slli a0, a0, 2 | :: 0x00010f50 2a93 add t1, t1, a0 | `==< 0x00010f52 edf9 bnez a1, 0x10f44 | : 0x00010f54 577002cd vsetivli zero, 4, e0x20, m1, ta, ma | : 0x00010f58 87e00e02 vle32.v v1, (t4) -| : 0x00010f5c 3285 mv a0, a2 +| : 0x00010f5c 3285 mv a0, a2 ; arg3 | .--> 0x00010f5e 07610502 vle32.v v2, (a0) | :: 0x00010f62 4105 addi a0, a0, 0x10 | :: 0x00010f64 5710116e vmflt.vv v0, v1, v2 @@ -1094,10 +1094,10 @@ nth paddr vaddr bind type size lib name | : 0x00010f7e 1146 li a2, 4 | : 0x00010f80 5731109e vmv1r.v v2, v1 | .--> 0x00010f84 57750609 vsetvli a0, a2, e0x20, m1, tu, ma ; arg3 -| :: 0x00010f88 87e10502 vle32.v v3, (a1) ; arg2 +| :: 0x00010f88 87e10502 vle32.v v3, (a1) | :: 0x00010f8c 13132500 slli t1, a0, 2 | :: 0x00010f90 098e sub a2, a2, a0 ; arg3 -| :: 0x00010f92 9a95 add a1, a1, t1 ; arg2 +| :: 0x00010f92 9a95 add a1, a1, t1 | :: 0x00010f94 5711311a vfmax.vv v2, v3, v2 | `==< 0x00010f98 75f6 bnez a2, 0x10f84 | : 0x00010f9a 07a78202 flw fa4, 0x28(t0) @@ -1110,12 +1110,12 @@ nth paddr vaddr bind type size lib name | : 0x00010fb4 13060608 addi a2, a2, 0x80 ; arg3 | : 0x00010fb8 d7d1075e vfmv.v.f v3, fa5 | : 0x00010fbc 0a96 add a2, a2, sp ; arg3 -| : 0x00010fbe 3283 mv t1, a2 +| : 0x00010fbe 3283 mv t1, a2 ; arg3 | : 0x00010fc0 9145 li a1, 4 | : 0x00010fc2 d7142042 vfmv.f.s fs1, v2 -| .--> 0x00010fc6 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| .--> 0x00010fc6 57f5650c vsetvli a0, a1, e8, mf4, ta, ma | :: 0x00010fca a7610302 vse32.v v3, (t1) -| :: 0x00010fce 898d sub a1, a1, a0 ; arg2 +| :: 0x00010fce 898d sub a1, a1, a0 | :: 0x00010fd0 0a05 slli a0, a0, 2 | :: 0x00010fd2 2a93 add t1, t1, a0 | `==< 0x00010fd4 edf9 bnez a1, 0x10fc6 @@ -1128,16 +1128,16 @@ nth paddr vaddr bind type size lib name | `==< 0x00010fec e319ffff bne t5, t6, 0x10fde | : 0x00010ff0 27610602 vse32.v v2, (a2) ; arg3 | : 0x00010ff4 9145 li a1, 4 -| .--> 0x00010ff6 57f50509 vsetvli a0, a1, e0x20, m1, tu, ma ; arg2 +| .--> 0x00010ff6 57f50509 vsetvli a0, a1, e0x20, m1, tu, ma | :: 0x00010ffa 07610602 vle32.v v2, (a2) ; arg3 | :: 0x00010ffe 13132500 slli t1, a0, 2 -| :: 0x00011002 898d sub a1, a1, a0 ; arg2 +| :: 0x00011002 898d sub a1, a1, a0 | :: 0x00011004 1a96 add a2, a2, t1 ; arg3 | :: 0x00011006 d7101112 vfmin.vv v1, v1, v2 | `==< 0x0001100a f5f5 bnez a1, 0x10ff6 | : 0x0001100c 4965 lui a0, 0x12 | : 0x0001100e 7286 mv a2, t3 -| : 0x00011010 c685 mv a1, a7 +| : 0x00011010 c685 mv a1, a7 ; arg8 | : 0x00011012 1305859c addi a0, a0, -0x638 | : 0x00011016 a7008102 vs1r.v v1, (sp) | : 0x0001101a eff06fd8 jal sym.imp.printf ; int printf(const char *format) @@ -1166,38 +1166,36 @@ nth paddr vaddr bind type size lib name \ `=< 0x00011066 6ff0afd3 j sym.imp.printf --- vector sign injection ; CALL XREF from main @ 0x10a04 -/ sym.test_sign_injection(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_sign_injection(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011566 b286 mv a3, a2 -| 0x00011568 aa88 mv a7, a0 +| 0x00011566 b286 mv a3, a2 ; arg3 +| 0x00011568 aa88 mv a7, a0 ; arg1 | 0x0001156a 13070040 li a4, 0x400 | .-> 0x0001156e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011572 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011572 87e00802 vle32.v v1, (a7) | : 0x00011576 07e10502 vle32.v v2, (a1) ; arg2 | : 0x0001157a 13982700 slli a6, a5, 2 ; arg6 | : 0x0001157e 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011580 c298 add a7, a7, a6 ; arg8 +| : 0x00011580 c298 add a7, a7, a6 | : 0x00011582 c295 add a1, a1, a6 ; arg2 | : 0x00011584 d7101122 vfsgnj.vv v1, v1, v2 -| : 0x00011588 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x0001158c c296 add a3, a3, a6 ; arg4 +| : 0x00011588 a7e00602 vse32.v v1, (a3) +| : 0x0001158c c296 add a3, a3, a6 | `=< 0x0001158e 65f3 bnez a4, 0x1156e -| 0x00011590 b286 mv a3, a2 -| 0x00011592 aa85 mv a1, a0 +| 0x00011590 b286 mv a3, a2 ; arg3 +| 0x00011592 aa85 mv a1, a0 ; arg1 | 0x00011594 13070040 li a4, 0x400 | .-> 0x00011598 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001159c 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x0001159c 87e00502 vle32.v v1, (a1) | : 0x000115a0 13982700 slli a6, a5, 2 ; arg6 | : 0x000115a4 1d8f sub a4, a4, a5 ; arg6 -| : 0x000115a6 c295 add a1, a1, a6 ; arg2 +| : 0x000115a6 c295 add a1, a1, a6 | : 0x000115a8 d790102a vfabs.v v1, v1 -| : 0x000115ac a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000115b0 c296 add a3, a3, a6 ; arg4 +| : 0x000115ac a7e00602 vse32.v v1, (a3) +| : 0x000115b0 c296 add a3, a3, a6 | `=< 0x000115b2 7df3 bnez a4, 0x11598 | 0x000115b4 87a7c180 flw fa5, -0x7f4(gp) | 0x000115b8 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 @@ -1215,30 +1213,29 @@ nth paddr vaddr bind type size lib name \ 0x000115e0 8280 ret --- vector saturating ; CALL XREF from main @ 0x10960 -/ sym.test_saturating(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg8); +/ sym.test_saturating(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 | ; arg int64_t arg4 @ a3 | ; arg int64_t arg5 @ a4 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 | 0x00011252 d776000d vsetvli a3, zero, e0x20, m1, ta, ma ; arg4 | 0x00011256 6178 lui a6, 0xffff8 | 0x00011258 2167 lui a4, 8 | 0x0001125a d741085e vmv.v.x v3, a6 | 0x0001125e 7d37 addiw a4, a4, -1 ; arg5 | 0x00011260 5741075e vmv.v.x v2, a4 -| 0x00011264 b286 mv a3, a2 -| 0x00011266 2e83 mv t1, a1 -| 0x00011268 aa88 mv a7, a0 +| 0x00011264 b286 mv a3, a2 ; arg3 +| 0x00011266 2e83 mv t1, a1 ; arg2 +| 0x00011268 aa88 mv a7, a0 ; arg1 | 0x0001126a 13070040 li a4, 0x400 | .-> 0x0001126e d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 | : 0x00011272 87520302 vle16.v v5, (t1) -| : 0x00011276 07d20802 vle16.v v4, (a7) ; arg8 +| : 0x00011276 07d20802 vle16.v v4, (a7) | : 0x0001127a 13981700 slli a6, a5, 1 ; arg6 | : 0x0001127e 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011280 c298 add a7, a7, a6 ; arg8 +| : 0x00011280 c298 add a7, a7, a6 | : 0x00011282 4293 add t1, t1, a6 | : 0x00011284 d72052c6 vwadd.vv v1, v5, v4 | : 0x00011288 5770000d vsetvli zero, zero, e0x20, m1, ta, ma @@ -1246,8 +1243,8 @@ nth paddr vaddr bind type size lib name | : 0x00011290 d7001116 vmin.vv v1, v1, v2 | : 0x00011294 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma | : 0x00011298 d73010b2 vnsrl.wi v1, v1, 0 -| : 0x0001129c a7d00602 vse16.v v1, (a3) ; arg4 -| : 0x000112a0 c296 add a3, a3, a6 ; arg4 +| : 0x0001129c a7d00602 vse16.v v1, (a3) +| : 0x000112a0 c296 add a3, a3, a6 | `=< 0x000112a2 71f7 bnez a4, 0x1126e | 0x000112a4 13070040 li a4, 0x400 | .-> 0x000112a8 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 @@ -1269,27 +1266,25 @@ nth paddr vaddr bind type size lib name \ 0x000112de 8280 ret --- vector unsigned operations ; CALL XREF from main @ 0x10b02 -/ sym.test_unsigned_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_unsigned_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011900 b286 mv a3, a2 -| 0x00011902 2a83 mv t1, a0 -| 0x00011904 ae88 mv a7, a1 +| 0x00011900 b286 mv a3, a2 ; arg3 +| 0x00011902 2a83 mv t1, a0 ; arg1 +| 0x00011904 ae88 mv a7, a1 ; arg2 | 0x00011906 13070040 li a4, 0x400 | .-> 0x0001190a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001190e 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x0001190e 07e10802 vle32.v v2, (a7) | : 0x00011912 87600302 vle32.v v1, (t1) | : 0x00011916 13982700 slli a6, a5, 2 ; arg6 | : 0x0001191a 1d8f sub a4, a4, a5 ; arg6 -| : 0x0001191c c298 add a7, a7, a6 ; arg8 +| : 0x0001191c c298 add a7, a7, a6 | : 0x0001191e 4293 add t1, t1, a6 | : 0x00011920 d700111a vmaxu.vv v1, v1, v2 -| : 0x00011924 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011928 c296 add a3, a3, a6 ; arg4 +| : 0x00011924 a7e00602 vse32.v v1, (a3) +| : 0x00011928 c296 add a3, a3, a6 | `=< 0x0001192a 65f3 bnez a4, 0x1190a | 0x0001192c 13070040 li a4, 0x400 | .-> 0x00011930 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 @@ -1306,27 +1301,25 @@ nth paddr vaddr bind type size lib name \ 0x00011952 8280 ret --- vector minmax ; CALL XREF from main @ 0x10af8 -/ sym.test_minmax(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_minmax(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x000118ac b286 mv a3, a2 -| 0x000118ae 2a83 mv t1, a0 -| 0x000118b0 ae88 mv a7, a1 +| 0x000118ac b286 mv a3, a2 ; arg3 +| 0x000118ae 2a83 mv t1, a0 ; arg1 +| 0x000118b0 ae88 mv a7, a1 ; arg2 | 0x000118b2 13070040 li a4, 0x400 | .-> 0x000118b6 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000118ba 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000118ba 07e10802 vle32.v v2, (a7) | : 0x000118be 87600302 vle32.v v1, (t1) | : 0x000118c2 13982700 slli a6, a5, 2 ; arg6 | : 0x000118c6 1d8f sub a4, a4, a5 ; arg6 -| : 0x000118c8 c298 add a7, a7, a6 ; arg8 +| : 0x000118c8 c298 add a7, a7, a6 | : 0x000118ca 4293 add t1, t1, a6 | : 0x000118cc d700111e vmax.vv v1, v1, v2 -| : 0x000118d0 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000118d4 c296 add a3, a3, a6 ; arg4 +| : 0x000118d0 a7e00602 vse32.v v1, (a3) +| : 0x000118d4 c296 add a3, a3, a6 | `=< 0x000118d6 65f3 bnez a4, 0x118b6 | 0x000118d8 13070040 li a4, 0x400 | .-> 0x000118dc d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 @@ -1343,17 +1336,16 @@ nth paddr vaddr bind type size lib name \ 0x000118fe 8280 ret --- vector fused multiply-add ; CALL XREF from main @ 0x109a8 -/ sym.test_fma(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_fma(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 | ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011416 b688 mv a7, a3 -| 0x00011418 b28e mv t4, a2 -| 0x0001141a 2e8e mv t3, a1 -| 0x0001141c 2a83 mv t1, a0 +| 0x00011416 b688 mv a7, a3 ; arg4 +| 0x00011418 b28e mv t4, a2 ; arg3 +| 0x0001141a 2e8e mv t3, a1 ; arg2 +| 0x0001141c 2a83 mv t1, a0 ; arg1 | 0x0001141e 13080040 li a6, 0x400 | .-> 0x00011422 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 | : 0x00011426 87600302 vle32.v v1, (t1) @@ -1365,13 +1357,13 @@ nth paddr vaddr bind type size lib name | : 0x0001143c 3a9e add t3, t3, a4 | : 0x0001143e ba9e add t4, t4, a4 | : 0x00011440 d79021a2 vfmadd.vv v1, v3, v2 -| : 0x00011444 a7e00802 vse32.v v1, (a7) ; arg8 -| : 0x00011448 ba98 add a7, a7, a4 ; arg8 +| : 0x00011444 a7e00802 vse32.v v1, (a7) +| : 0x00011448 ba98 add a7, a7, a4 | `=< 0x0001144a e31c08fc bnez a6, 0x11422 -| 0x0001144e b688 mv a7, a3 -| 0x00011450 b28e mv t4, a2 -| 0x00011452 2e8e mv t3, a1 -| 0x00011454 2a83 mv t1, a0 +| 0x0001144e b688 mv a7, a3 ; arg4 +| 0x00011450 b28e mv t4, a2 ; arg3 +| 0x00011452 2e8e mv t3, a1 ; arg2 +| 0x00011454 2a83 mv t1, a0 ; arg1 | 0x00011456 13080040 li a6, 0x400 | .-> 0x0001145a d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 | : 0x0001145e 87610302 vle32.v v3, (t1) @@ -1383,8 +1375,8 @@ nth paddr vaddr bind type size lib name | : 0x00011474 3a9e add t3, t3, a4 | : 0x00011476 ba9e add t4, t4, a4 | : 0x00011478 d79021aa vfmsub.vv v1, v3, v2 -| : 0x0001147c a7e00802 vse32.v v1, (a7) ; arg8 -| : 0x00011480 ba98 add a7, a7, a4 ; arg8 +| : 0x0001147c a7e00802 vse32.v v1, (a7) +| : 0x00011480 ba98 add a7, a7, a4 | `=< 0x00011482 e31c08fc bnez a6, 0x1145a | 0x00011486 13080040 li a6, 0x400 | .-> 0x0001148a d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 @@ -1403,56 +1395,54 @@ nth paddr vaddr bind type size lib name \ 0x000114b6 8280 ret --- vector float operations ; CALL XREF from main @ 0x1099c -/ sym.test_float_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_float_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011362 b286 mv a3, a2 -| 0x00011364 2e83 mv t1, a1 -| 0x00011366 aa88 mv a7, a0 +| 0x00011362 b286 mv a3, a2 ; arg3 +| 0x00011364 2e83 mv t1, a1 ; arg2 +| 0x00011366 aa88 mv a7, a0 ; arg1 | 0x00011368 13070040 li a4, 0x400 | .-> 0x0001136c d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011370 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011370 87e00802 vle32.v v1, (a7) | : 0x00011374 07610302 vle32.v v2, (t1) | : 0x00011378 13982700 slli a6, a5, 2 ; arg6 | : 0x0001137c 1d8f sub a4, a4, a5 ; arg6 -| : 0x0001137e c298 add a7, a7, a6 ; arg8 +| : 0x0001137e c298 add a7, a7, a6 | : 0x00011380 4293 add t1, t1, a6 | : 0x00011382 d7101102 vfadd.vv v1, v1, v2 -| : 0x00011386 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x0001138a c296 add a3, a3, a6 ; arg4 +| : 0x00011386 a7e00602 vse32.v v1, (a3) +| : 0x0001138a c296 add a3, a3, a6 | `=< 0x0001138c 65f3 bnez a4, 0x1136c -| 0x0001138e b286 mv a3, a2 -| 0x00011390 2e83 mv t1, a1 -| 0x00011392 aa88 mv a7, a0 +| 0x0001138e b286 mv a3, a2 ; arg3 +| 0x00011390 2e83 mv t1, a1 ; arg2 +| 0x00011392 aa88 mv a7, a0 ; arg1 | 0x00011394 13070040 li a4, 0x400 | .-> 0x00011398 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001139c 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x0001139c 87e00802 vle32.v v1, (a7) | : 0x000113a0 07610302 vle32.v v2, (t1) | : 0x000113a4 13982700 slli a6, a5, 2 ; arg6 | : 0x000113a8 1d8f sub a4, a4, a5 ; arg6 -| : 0x000113aa c298 add a7, a7, a6 ; arg8 +| : 0x000113aa c298 add a7, a7, a6 | : 0x000113ac 4293 add t1, t1, a6 | : 0x000113ae d710110a vfsub.vv v1, v1, v2 -| : 0x000113b2 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000113b6 c296 add a3, a3, a6 ; arg4 +| : 0x000113b2 a7e00602 vse32.v v1, (a3) +| : 0x000113b6 c296 add a3, a3, a6 | `=< 0x000113b8 65f3 bnez a4, 0x11398 -| 0x000113ba b286 mv a3, a2 -| 0x000113bc aa88 mv a7, a0 +| 0x000113ba b286 mv a3, a2 ; arg3 +| 0x000113bc aa88 mv a7, a0 ; arg1 | 0x000113be 13070040 li a4, 0x400 | .-> 0x000113c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000113c6 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113c6 87e00802 vle32.v v1, (a7) | : 0x000113ca 07e10502 vle32.v v2, (a1) ; arg2 | : 0x000113ce 13982700 slli a6, a5, 2 ; arg6 | : 0x000113d2 1d8f sub a4, a4, a5 ; arg6 -| : 0x000113d4 c298 add a7, a7, a6 ; arg8 +| : 0x000113d4 c298 add a7, a7, a6 | : 0x000113d6 c295 add a1, a1, a6 ; arg2 | : 0x000113d8 d7101182 vfdiv.vv v1, v1, v2 -| : 0x000113dc a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000113e0 c296 add a3, a3, a6 ; arg4 +| : 0x000113dc a7e00602 vse32.v v1, (a3) +| : 0x000113e0 c296 add a3, a3, a6 | `=< 0x000113e2 65f3 bnez a4, 0x113c2 | 0x000113e4 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 | 0x000113e8 5731005e vmv.v.i v2, 0 @@ -1471,56 +1461,54 @@ nth paddr vaddr bind type size lib name \ 0x00011414 8280 ret --- floating point operations ; CALL XREF from main @ 0x1099c -/ sym.test_float_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_float_ops(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011362 b286 mv a3, a2 -| 0x00011364 2e83 mv t1, a1 -| 0x00011366 aa88 mv a7, a0 +| 0x00011362 b286 mv a3, a2 ; arg3 +| 0x00011364 2e83 mv t1, a1 ; arg2 +| 0x00011366 aa88 mv a7, a0 ; arg1 | 0x00011368 13070040 li a4, 0x400 | .-> 0x0001136c d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011370 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011370 87e00802 vle32.v v1, (a7) | : 0x00011374 07610302 vle32.v v2, (t1) | : 0x00011378 13982700 slli a6, a5, 2 ; arg6 | : 0x0001137c 1d8f sub a4, a4, a5 ; arg6 -| : 0x0001137e c298 add a7, a7, a6 ; arg8 +| : 0x0001137e c298 add a7, a7, a6 | : 0x00011380 4293 add t1, t1, a6 | : 0x00011382 d7101102 vfadd.vv v1, v1, v2 -| : 0x00011386 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x0001138a c296 add a3, a3, a6 ; arg4 +| : 0x00011386 a7e00602 vse32.v v1, (a3) +| : 0x0001138a c296 add a3, a3, a6 | `=< 0x0001138c 65f3 bnez a4, 0x1136c -| 0x0001138e b286 mv a3, a2 -| 0x00011390 2e83 mv t1, a1 -| 0x00011392 aa88 mv a7, a0 +| 0x0001138e b286 mv a3, a2 ; arg3 +| 0x00011390 2e83 mv t1, a1 ; arg2 +| 0x00011392 aa88 mv a7, a0 ; arg1 | 0x00011394 13070040 li a4, 0x400 | .-> 0x00011398 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001139c 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x0001139c 87e00802 vle32.v v1, (a7) | : 0x000113a0 07610302 vle32.v v2, (t1) | : 0x000113a4 13982700 slli a6, a5, 2 ; arg6 | : 0x000113a8 1d8f sub a4, a4, a5 ; arg6 -| : 0x000113aa c298 add a7, a7, a6 ; arg8 +| : 0x000113aa c298 add a7, a7, a6 | : 0x000113ac 4293 add t1, t1, a6 | : 0x000113ae d710110a vfsub.vv v1, v1, v2 -| : 0x000113b2 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000113b6 c296 add a3, a3, a6 ; arg4 +| : 0x000113b2 a7e00602 vse32.v v1, (a3) +| : 0x000113b6 c296 add a3, a3, a6 | `=< 0x000113b8 65f3 bnez a4, 0x11398 -| 0x000113ba b286 mv a3, a2 -| 0x000113bc aa88 mv a7, a0 +| 0x000113ba b286 mv a3, a2 ; arg3 +| 0x000113bc aa88 mv a7, a0 ; arg1 | 0x000113be 13070040 li a4, 0x400 | .-> 0x000113c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000113c6 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113c6 87e00802 vle32.v v1, (a7) | : 0x000113ca 07e10502 vle32.v v2, (a1) ; arg2 | : 0x000113ce 13982700 slli a6, a5, 2 ; arg6 | : 0x000113d2 1d8f sub a4, a4, a5 ; arg6 -| : 0x000113d4 c298 add a7, a7, a6 ; arg8 +| : 0x000113d4 c298 add a7, a7, a6 | : 0x000113d6 c295 add a1, a1, a6 ; arg2 | : 0x000113d8 d7101182 vfdiv.vv v1, v1, v2 -| : 0x000113dc a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000113e0 c296 add a3, a3, a6 ; arg4 +| : 0x000113dc a7e00602 vse32.v v1, (a3) +| : 0x000113e0 c296 add a3, a3, a6 | `=< 0x000113e2 65f3 bnez a4, 0x113c2 | 0x000113e4 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 | 0x000113e8 5731005e vmv.v.i v2, 0 @@ -1539,29 +1527,26 @@ nth paddr vaddr bind type size lib name \ 0x00011414 8280 ret --- widening operations ; CALL XREF from main @ 0x1096a -/ sym.test_widening(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg7, int64_t arg8); +/ sym.test_widening(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg7 @ a6 -| ; arg int64_t arg8 @ a7 -| 0x000112e0 b286 mv a3, a2 -| 0x000112e2 ae88 mv a7, a1 -| 0x000112e4 2a88 mv a6, a0 +| 0x000112e0 b286 mv a3, a2 ; arg3 +| 0x000112e2 ae88 mv a7, a1 ; arg2 +| 0x000112e4 2a88 mv a6, a0 ; arg1 | 0x000112e6 13070040 li a4, 0x400 | .-> 0x000112ea d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 -| : 0x000112ee 87d10802 vle16.v v3, (a7) ; arg8 -| : 0x000112f2 07510802 vle16.v v2, (a6) ; arg7 +| : 0x000112ee 87d10802 vle16.v v3, (a7) +| : 0x000112f2 07510802 vle16.v v2, (a6) | : 0x000112f6 13931700 slli t1, a5, 1 ; arg6 | : 0x000112fa 139e2700 slli t3, a5, 2 ; arg6 | : 0x000112fe 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011300 1a98 add a6, a6, t1 ; arg7 -| : 0x00011302 9a98 add a7, a7, t1 ; arg8 +| : 0x00011300 1a98 add a6, a6, t1 +| : 0x00011302 9a98 add a7, a7, t1 | : 0x00011304 d72031c6 vwadd.vv v1, v3, v2 -| : 0x00011308 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x0001130c f296 add a3, a3, t3 ; arg4 +| : 0x00011308 a7e00602 vse32.v v1, (a3) +| : 0x0001130c f296 add a3, a3, t3 | `=< 0x0001130e 71ff bnez a4, 0x112ea | 0x00011310 13070040 li a4, 0x400 | .-> 0x00011314 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 @@ -1579,44 +1564,42 @@ nth paddr vaddr bind type size lib name \ 0x0001133a 8280 ret --- comparisons ; CALL XREF from main @ 0x10942 -/ sym.test_comparisons(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_comparisons(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x0001106a b286 mv a3, a2 -| 0x0001106c 2a83 mv t1, a0 -| 0x0001106e ae88 mv a7, a1 +| 0x0001106a b286 mv a3, a2 ; arg3 +| 0x0001106c 2a83 mv t1, a0 ; arg1 +| 0x0001106e ae88 mv a7, a1 ; arg2 | 0x00011070 13070040 li a4, 0x400 | .-> 0x00011074 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011078 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x00011078 07e10802 vle32.v v2, (a7) | : 0x0001107c 87600302 vle32.v v1, (t1) | : 0x00011080 13982700 slli a6, a5, 2 ; arg6 | : 0x00011084 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011086 c298 add a7, a7, a6 ; arg8 +| : 0x00011086 c298 add a7, a7, a6 | : 0x00011088 4293 add t1, t1, a6 | : 0x0001108a d7001116 vmin.vv v1, v1, v2 -| : 0x0001108e a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011092 c296 add a3, a3, a6 ; arg4 +| : 0x0001108e a7e00602 vse32.v v1, (a3) +| : 0x00011092 c296 add a3, a3, a6 | `=< 0x00011094 65f3 bnez a4, 0x11074 | 0x00011096 5773000d vsetvli t1, zero, e0x20, m1, ta, ma | 0x0001109a 5731005e vmv.v.i v2, 0 -| 0x0001109e b286 mv a3, a2 -| 0x000110a0 aa88 mv a7, a0 +| 0x0001109e b286 mv a3, a2 ; arg3 +| 0x000110a0 aa88 mv a7, a0 ; arg1 | 0x000110a2 13070040 li a4, 0x400 | .-> 0x000110a6 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000110aa 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000110aa 87e00802 vle32.v v1, (a7) | : 0x000110ae 07e00502 vle32.v v0, (a1) ; arg2 | : 0x000110b2 13982700 slli a6, a5, 2 ; arg6 | : 0x000110b6 1d8f sub a4, a4, a5 ; arg6 | : 0x000110b8 c295 add a1, a1, a6 ; arg2 -| : 0x000110ba c298 add a7, a7, a6 ; arg8 +| : 0x000110ba c298 add a7, a7, a6 | : 0x000110bc 57800062 vmseq.vv v0, v0, v1 | : 0x000110c0 d7b0205c vmerge.vim v1, v2, 1, v0 -| : 0x000110c4 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000110c8 c296 add a3, a3, a6 ; arg4 +| : 0x000110c4 a7e00602 vse32.v v1, (a3) +| : 0x000110c8 c296 add a3, a3, a6 | `=< 0x000110ca 71ff bnez a4, 0x110a6 | 0x000110cc d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 | 0x000110d0 5731005e vmv.v.i v2, 0 @@ -1745,28 +1728,26 @@ nth paddr vaddr bind type size lib name \ 0x00011776 8280 ret --- floating point comparisons ; CALL XREF from main @ 0x109b2 -/ sym.test_float_comparisons(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_float_comparisons(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x000114b8 b286 mv a3, a2 -| 0x000114ba 2e83 mv t1, a1 -| 0x000114bc aa88 mv a7, a0 +| 0x000114b8 b286 mv a3, a2 ; arg3 +| 0x000114ba 2e83 mv t1, a1 ; arg2 +| 0x000114bc aa88 mv a7, a0 ; arg1 | 0x000114be 13070040 li a4, 0x400 | .-> 0x000114c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000114c6 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000114c6 07e10802 vle32.v v2, (a7) | : 0x000114ca 87600302 vle32.v v1, (t1) | : 0x000114ce 13982700 slli a6, a5, 2 ; arg6 | : 0x000114d2 1d8f sub a4, a4, a5 ; arg6 -| : 0x000114d4 c298 add a7, a7, a6 ; arg8 +| : 0x000114d4 c298 add a7, a7, a6 | : 0x000114d6 4293 add t1, t1, a6 | : 0x000114d8 5790206e vmflt.vv v0, v2, v1 | : 0x000114dc d700115c vmerge.vvm v1, v1, v2, v0 -| : 0x000114e0 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000114e4 c296 add a3, a3, a6 ; arg4 +| : 0x000114e0 a7e00602 vse32.v v1, (a3) +| : 0x000114e4 c296 add a3, a3, a6 | `=< 0x000114e6 71ff bnez a4, 0x114c2 | 0x000114e8 577e000d vsetvli t3, zero, e0x20, m1, ta, ma | 0x000114ec d731005e vmv.v.i v3, 0 @@ -1807,38 +1788,36 @@ nth paddr vaddr bind type size lib name \ 0x0001179e 8280 ret --- shifts ; CALL XREF from main @ 0x1094c -/ sym.test_shifts(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg7); +/ sym.test_shifts(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg7 @ a6 -| 0x00011102 b286 mv a3, a2 -| 0x00011104 2a88 mv a6, a0 +| 0x00011102 b286 mv a3, a2 ; arg3 +| 0x00011104 2a88 mv a6, a0 ; arg1 | 0x00011106 13070040 li a4, 0x400 | .-> 0x0001110a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001110e 87600802 vle32.v v1, (a6) ; arg7 +| : 0x0001110e 87600802 vle32.v v1, (a6) | : 0x00011112 93982700 slli a7, a5, 2 ; arg6 | : 0x00011116 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011118 4698 add a6, a6, a7 ; arg7 +| : 0x00011118 4698 add a6, a6, a7 | : 0x0001111a d7b01196 vsll.vi v1, v1, 3 -| : 0x0001111e a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011122 c696 add a3, a3, a7 ; arg4 +| : 0x0001111e a7e00602 vse32.v v1, (a3) +| : 0x00011122 c696 add a3, a3, a7 | `=< 0x00011124 7df3 bnez a4, 0x1110a -| 0x00011126 b286 mv a3, a2 -| 0x00011128 2a88 mv a6, a0 +| 0x00011126 b286 mv a3, a2 ; arg3 +| 0x00011128 2a88 mv a6, a0 ; arg1 | 0x0001112a 13070040 li a4, 0x400 | .-> 0x0001112e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011132 87600802 vle32.v v1, (a6) ; arg7 +| : 0x00011132 87600802 vle32.v v1, (a6) | : 0x00011136 93982700 slli a7, a5, 2 ; arg6 | : 0x0001113a 1d8f sub a4, a4, a5 ; arg6 -| : 0x0001113c 4698 add a6, a6, a7 ; arg7 +| : 0x0001113c 4698 add a6, a6, a7 | : 0x0001113e d73011a2 vsrl.vi v1, v1, 2 -| : 0x00011142 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011146 c696 add a3, a3, a7 ; arg4 +| : 0x00011142 a7e00602 vse32.v v1, (a3) +| : 0x00011146 c696 add a3, a3, a7 | `=< 0x00011148 7df3 bnez a4, 0x1112e -| 0x0001114a b286 mv a3, a2 +| 0x0001114a b286 mv a3, a2 ; arg3 | 0x0001114c 13070040 li a4, 0x400 | .-> 0x00011150 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 | : 0x00011154 87e00502 vle32.v v1, (a1) ; arg2 @@ -1846,8 +1825,8 @@ nth paddr vaddr bind type size lib name | : 0x0001115c 1d8f sub a4, a4, a5 ; arg6 | : 0x0001115e c295 add a1, a1, a6 ; arg2 | : 0x00011160 d73012a6 vsra.vi v1, v1, 4 -| : 0x00011164 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011168 c296 add a3, a3, a6 ; arg4 +| : 0x00011164 a7e00602 vse32.v v1, (a3) +| : 0x00011168 c296 add a3, a3, a6 | `=< 0x0001116a 7df3 bnez a4, 0x11150 | 0x0001116c d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 | 0x00011170 57a10852 vid.v v2 @@ -1870,29 +1849,27 @@ nth paddr vaddr bind type size lib name \ 0x000111ac 8280 ret --- strided access ; CALL XREF from main @ 0x10a0c -/ sym.test_strided_access(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6); +/ sym.test_strided_access(int64_t arg1, int64_t arg2, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 -| ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| 0x000115e2 ae86 mv a3, a1 -| 0x000115e4 2a86 mv a2, a0 +| 0x000115e2 ae86 mv a3, a1 ; arg2 +| 0x000115e4 2a86 mv a2, a0 ; arg1 | 0x000115e6 1307f01f li a4, 0x1ff | .-> 0x000115ea d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 -| : 0x000115ee 07610622 vlseg2e32.v v2, (a2) ; arg3 +| : 0x000115ee 07610622 vlseg2e32.v v2, (a2) | : 0x000115f2 93983700 slli a7, a5, 3 ; arg6 | : 0x000115f6 13982700 slli a6, a5, 2 ; arg6 | : 0x000115fa 1d8f sub a4, a4, a5 ; arg6 -| : 0x000115fc 4696 add a2, a2, a7 ; arg3 -| : 0x000115fe 27e10602 vse32.v v2, (a3) ; arg4 -| : 0x00011602 c296 add a3, a3, a6 ; arg4 +| : 0x000115fc 4696 add a2, a2, a7 +| : 0x000115fe 27e10602 vse32.v v2, (a3) +| : 0x00011602 c296 add a3, a3, a6 | `=< 0x00011604 7df3 bnez a4, 0x115ea | 0x00011606 0567 lui a4, 1 | 0x00011608 b307e500 add a5, a0, a4 ; arg1 | 0x0001160c 87a787ff flw fa5, -8(a5) | 0x00011610 732620c2 csrr a2, vlenb -| 0x00011614 93582600 srli a7, a2, 2 ; arg3 +| 0x00011614 93582600 srli a7, a2, 2 | 0x00011618 9387f8ff addi a5, a7, -1 | 0x0001161c 27aef57e fsw fa5, 0x7fc(a1) ; arg2 | 0x00011620 1b880700 sext.w a6, a5 @@ -1900,19 +1877,19 @@ nth paddr vaddr bind type size lib name | ,=< 0x00011628 63e80611 bltu a3, a6, 0x11738 | | 0x0001162c 5773000d vsetvli t1, zero, e0x20, m1, ta, ma | | 0x00011630 d7a10852 vid.v v3 -| | 0x00011634 118f sub a4, a4, a2 ; arg3 +| | 0x00011634 118f sub a4, a4, a2 | | 0x00011636 33081041 neg a6, a7 | | 0x0001163a d7c1370e vrsub.vx v3, v3, a5 | | 0x0001163e 2e97 add a4, a4, a1 ; arg2 | | 0x00011640 1b080840 addiw a6, a6, 0x400 -| | 0x00011644 aa86 mv a3, a0 +| | 0x00011644 aa86 mv a3, a0 ; arg1 | | 0x00011646 8147 li a5, 0 | .--> 0x00011648 07e18602 vl1re32.v v2, (a3) | :| 0x0001164c bb871701 addw a5, a5, a7 -| :| 0x00011650 b296 add a3, a3, a2 ; arg3 +| :| 0x00011650 b296 add a3, a3, a2 | :| 0x00011652 d7802132 vrgather.vv v1, v2, v3 | :| 0x00011656 a7008702 vs1r.v v1, (a4) -| :| 0x0001165a 118f sub a4, a4, a2 ; arg3 +| :| 0x0001165a 118f sub a4, a4, a2 | `==< 0x0001165c e376f8fe bgeu a6, a5, 0x11648 | | 0x00011660 93060040 li a3, 0x400 | ,==< 0x00011664 6389d70c beq a5, a3, 0x11736 @@ -1981,24 +1958,22 @@ nth paddr vaddr bind type size lib name \ `===< 0x00011740 3db7 j 0x1166e --- absolute value and negation ; CALL XREF from main @ 0x10aee -/ sym.test_abs_neg(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6); +/ sym.test_abs_neg(int64_t arg1, int64_t arg2, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 -| ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| 0x00011862 ae86 mv a3, a1 -| 0x00011864 2a86 mv a2, a0 +| 0x00011862 ae86 mv a3, a1 ; arg2 +| 0x00011864 2a86 mv a2, a0 ; arg1 | 0x00011866 13070040 li a4, 0x400 | .-> 0x0001186a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x0001186e 87600602 vle32.v v1, (a2) ; arg3 +| : 0x0001186e 87600602 vle32.v v1, (a2) | : 0x00011872 13982700 slli a6, a5, 2 ; arg6 | : 0x00011876 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011878 4296 add a2, a2, a6 ; arg3 +| : 0x00011878 4296 add a2, a2, a6 | : 0x0001187a 5731100e vrsub.vi v2, v1, 0 | : 0x0001187e d700111e vmax.vv v1, v1, v2 -| : 0x00011882 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011886 c296 add a3, a3, a6 ; arg4 +| : 0x00011882 a7e00602 vse32.v v1, (a3) +| : 0x00011886 c296 add a3, a3, a6 | `=< 0x00011888 6df3 bnez a4, 0x1186a | 0x0001188a 13070040 li a4, 0x400 | .-> 0x0001188e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 @@ -2571,17 +2546,16 @@ nth paddr vaddr bind type size lib name \ 0x00010ba6 8280 ret --- madd ; CALL XREF from main @ 0x10b0e -/ sym.test_madd(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_madd(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 | ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x00011954 b688 mv a7, a3 -| 0x00011956 b28e mv t4, a2 -| 0x00011958 2e8e mv t3, a1 -| 0x0001195a 2a83 mv t1, a0 +| 0x00011954 b688 mv a7, a3 ; arg4 +| 0x00011956 b28e mv t4, a2 ; arg3 +| 0x00011958 2e8e mv t3, a1 ; arg2 +| 0x0001195a 2a83 mv t1, a0 ; arg1 | 0x0001195c 13080040 li a6, 0x400 | .-> 0x00011960 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 | : 0x00011964 87610302 vle32.v v3, (t1) @@ -2593,8 +2567,8 @@ nth paddr vaddr bind type size lib name | : 0x0001197a 3a9e add t3, t3, a4 | : 0x0001197c ba9e add t4, t4, a4 | : 0x0001197e d7a021a6 vmadd.vv v1, v3, v2 -| : 0x00011982 a7e00802 vse32.v v1, (a7) ; arg8 -| : 0x00011986 ba98 add a7, a7, a4 ; arg8 +| : 0x00011982 a7e00802 vse32.v v1, (a7) +| : 0x00011986 ba98 add a7, a7, a4 | `=< 0x00011988 e31c08fc bnez a6, 0x11960 | 0x0001198c 13080040 li a6, 0x400 | .-> 0x00011990 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 @@ -2613,56 +2587,54 @@ nth paddr vaddr bind type size lib name \ 0x000119bc 8280 ret --- bitwise ; CALL XREF from main @ 0x10956 -/ sym.test_bitwise(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg6, int64_t arg8); +/ sym.test_bitwise(int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg6); | ; arg int64_t arg1 @ a0 | ; arg int64_t arg2 @ a1 | ; arg int64_t arg3 @ a2 -| ; arg int64_t arg4 @ a3 | ; arg int64_t arg6 @ a5 -| ; arg int64_t arg8 @ a7 -| 0x000111ae b286 mv a3, a2 -| 0x000111b0 2e83 mv t1, a1 -| 0x000111b2 aa88 mv a7, a0 +| 0x000111ae b286 mv a3, a2 ; arg3 +| 0x000111b0 2e83 mv t1, a1 ; arg2 +| 0x000111b2 aa88 mv a7, a0 ; arg1 | 0x000111b4 13070040 li a4, 0x400 | .-> 0x000111b8 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000111bc 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000111bc 07e10802 vle32.v v2, (a7) | : 0x000111c0 87600302 vle32.v v1, (t1) | : 0x000111c4 13982700 slli a6, a5, 2 ; arg6 | : 0x000111c8 1d8f sub a4, a4, a5 ; arg6 -| : 0x000111ca c298 add a7, a7, a6 ; arg8 +| : 0x000111ca c298 add a7, a7, a6 | : 0x000111cc 4293 add t1, t1, a6 | : 0x000111ce d7001126 vand.vv v1, v1, v2 -| : 0x000111d2 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x000111d6 c296 add a3, a3, a6 ; arg4 +| : 0x000111d2 a7e00602 vse32.v v1, (a3) +| : 0x000111d6 c296 add a3, a3, a6 | `=< 0x000111d8 65f3 bnez a4, 0x111b8 -| 0x000111da b286 mv a3, a2 -| 0x000111dc 2e83 mv t1, a1 -| 0x000111de aa88 mv a7, a0 +| 0x000111da b286 mv a3, a2 ; arg3 +| 0x000111dc 2e83 mv t1, a1 ; arg2 +| 0x000111de aa88 mv a7, a0 ; arg1 | 0x000111e0 13070040 li a4, 0x400 | .-> 0x000111e4 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x000111e8 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000111e8 07e10802 vle32.v v2, (a7) | : 0x000111ec 87600302 vle32.v v1, (t1) | : 0x000111f0 13982700 slli a6, a5, 2 ; arg6 | : 0x000111f4 1d8f sub a4, a4, a5 ; arg6 -| : 0x000111f6 c298 add a7, a7, a6 ; arg8 +| : 0x000111f6 c298 add a7, a7, a6 | : 0x000111f8 4293 add t1, t1, a6 | : 0x000111fa d700112a vor.vv v1, v1, v2 -| : 0x000111fe a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x00011202 c296 add a3, a3, a6 ; arg4 +| : 0x000111fe a7e00602 vse32.v v1, (a3) +| : 0x00011202 c296 add a3, a3, a6 | `=< 0x00011204 65f3 bnez a4, 0x111e4 -| 0x00011206 b286 mv a3, a2 -| 0x00011208 aa88 mv a7, a0 +| 0x00011206 b286 mv a3, a2 ; arg3 +| 0x00011208 aa88 mv a7, a0 ; arg1 | 0x0001120a 13070040 li a4, 0x400 | .-> 0x0001120e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 -| : 0x00011212 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x00011212 07e10802 vle32.v v2, (a7) | : 0x00011216 87e00502 vle32.v v1, (a1) ; arg2 | : 0x0001121a 13982700 slli a6, a5, 2 ; arg6 | : 0x0001121e 1d8f sub a4, a4, a5 ; arg6 -| : 0x00011220 c298 add a7, a7, a6 ; arg8 +| : 0x00011220 c298 add a7, a7, a6 | : 0x00011222 c295 add a1, a1, a6 ; arg2 | : 0x00011224 d700112e vxor.vv v1, v1, v2 -| : 0x00011228 a7e00602 vse32.v v1, (a3) ; arg4 -| : 0x0001122c c296 add a3, a3, a6 ; arg4 +| : 0x00011228 a7e00602 vse32.v v1, (a3) +| : 0x0001122c c296 add a3, a3, a6 | `=< 0x0001122e 65f3 bnez a4, 0x1120e | 0x00011230 13070040 li a4, 0x400 | .-> 0x00011234 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 @@ -3204,13 +3176,15 @@ EXPECT=<