diff --git a/librz/arch/il/analysis_il.c b/librz/arch/il/analysis_il.c index baf6224db62..e9dc8bf6e3a 100644 --- a/librz/arch/il/analysis_il.c +++ b/librz/arch/il/analysis_il.c @@ -193,6 +193,7 @@ static bool setup_regs(RzAnalysis *a, RzAnalysisILVM *vm, RzAnalysisILConfig *cf 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..5a43a4352d6 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il.c @@ -0,0 +1,150 @@ +// SPDX-FileCopyrightText: 2026 Mostafa Mahmoud +// SPDX-License-Identifier: BSD-3-Clause + +#include "riscv_il.h" +#include "riscv_il_integer.h" +#include "riscv_il_m.h" +#include "riscv_il_compressed.h" + +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(andi, 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), + // 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(ld, LD), + 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(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_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(c_sw, C_SW), + USE_LIFTER(c_swsp, C_SWSP), + USE_LIFTER(c_sd, C_SD), + 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, size_t 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); + + 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 new file mode 100644 index 00000000000..03c42770f59 --- /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, 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, size_t size); + +RZ_IPI RzAnalysisILConfig *rz_riscv_il_config(RZ_NONNULL RzAnalysis *analysis); + +#endif \ 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 new file mode 100644 index 00000000000..5c31ce4ce80 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_base.h @@ -0,0 +1,226 @@ +// 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 + +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_il_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_il_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 +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 (!riscv_il_require_op(insn, current_addr, idx, t, #t)) { \ + return NULL; \ + } + +#define REQUIRE_64_BIT(analysis) \ + 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 { \ + } while (0) +#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_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_IMM); \ + uint32_t rd = insn->detail->riscv.operands[0].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_3OPS(RISCV_OP_REG, RISCV_OP_REG, RISCV_OP_REG); \ + uint32_t rd = insn->detail->riscv.operands[0].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_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_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_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_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_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_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_2OPS(RISCV_OP_REG, RISCV_OP_MEM); \ + uint32_t rd = insn->detail->riscv.operands[0].reg; \ + 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_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_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_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_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_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); + +#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..96f77d45961 --- /dev/null +++ b/librz/arch/isa/riscv/riscv_il_m.h @@ -0,0 +1,32 @@ +// 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) + +// 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 + +#endif // RISCV_IL_M_H diff --git a/librz/arch/meson.build b/librz/arch/meson.build index 5366e3b45b3..d5c0be1ab8f 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..87831e4ba54 100644 --- a/test/db/asm/riscv_32 +++ b/test/db/asm/riscv_32 @@ -1,185 +1,201 @@ -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 -d "addi sp, sp, 0x90" 4961 0x40 -d "ret" 8280 0x40 -d "lw a5, 0x18(sp)" e247 0x40 -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 "srai a5, s0, 0x1f" 9357f441 0x40 -d "lw a2, 0x20(sp)" 0256 0x40 -d "andi a5, a5, 0xf" bd8b 0x40 -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 "mul a4, a0, a2" 3307c502 0x140 -d "mulhu t1, a2, a2" 3333c602 0x140 -d "slli a4, a4, 1" 0607 0x140 -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 "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 "blt s1, a7, 0x2c6" 63cc1415 0x16e -d "beq a7, s1, 0x2c2" 63889814 0x172 -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 "slli t1, a3, 8" 13938600 0x180 -d "addi a1, a1, 1" 8505 0x180 -d "mul a4, a0, a6" 33070503 0x180 -d "srai a0, a3, 0x18" 13d58641 0x180 -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 "or a2, t1, a2" 3366c300 0x180 -d "slli a7, a6, 1" 93181800 0x180 -d "srli a3, a6, 0x1f" 9356f801 0x180 -d "add a5, a7, t2" b3877800 0x1c0 -d "or a4, a4, a3" 558f 0x1c0 -d "srli a6, a5, 0x18" 13d88701 0x1c0 -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 "or a6, a5, a6" 33e80701 0x1c0 -d "srai a5, a4, 0x18" 93578741 0x1c0 -d "bne a1, s6, 0x140" e39065f7 0x1e0 -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 "mv t2, a4" ba83 0x1c0 -d "add t6, t6, a3" b69f 0x1c0 +# ----------------------------- 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 (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 (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 (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 (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))) +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 (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))) +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 (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))) +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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 "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)))