diff --git a/src/interpret.cpp b/src/interpret.cpp index 8bdddc62..a44e32da 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -546,6 +546,12 @@ static inline void set_rtc_interrupt(STATE_ACCESS &a, uint64_t mcycle) { } } +/// \brief Checks if a instruction is uncompressed. +/// \param insn Instruction. +static FORCE_INLINE bool insn_is_uncompressed(uint32_t insn) { + return (insn & 3) == 3; +} + /// \brief Obtains the id fields an instruction. /// \param insn Instruction. static FORCE_INLINE uint32_t insn_get_id(uint32_t insn) { @@ -4717,7 +4723,7 @@ static FORCE_INLINE execute_status execute_C_FS(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.ADDI4SPN instruction. template static FORCE_INLINE execute_status execute_C_ADDI4SPN(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.addi4spn"); + dump_insn(a, pc, static_cast(insn), "c.addi4spn"); // rd cannot be zero (guaranteed by RISC-V spec design) const uint32_t rd = insn_get_CIW_CL_rd_CS_CA_rs2(insn); // imm cannot be zero (guaranteed by the jump table) @@ -4732,11 +4738,11 @@ static FORCE_INLINE execute_status execute_C_ADDI4SPN(STATE_ACCESS &a, uint64_t /// \brief Implementation of the C.FLD instruction. template static FORCE_INLINE execute_status execute_C_FLD(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.fld"); + dump_insn(a, pc, static_cast(insn), "c.fld"); // If FS is OFF, attempts to read or write the float state will cause an illegal instruction // exception. if (unlikely((a.read_mstatus() & MSTATUS_FS_MASK) == MSTATUS_FS_OFF)) { - return raise_illegal_insn_exception(a, pc, insn); + return raise_illegal_insn_exception(a, pc, static_cast(insn)); } const uint32_t rd = insn_get_CIW_CL_rd_CS_CA_rs2(insn); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); @@ -4747,7 +4753,7 @@ static FORCE_INLINE execute_status execute_C_FLD(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.LW instruction. template static FORCE_INLINE execute_status execute_C_LW(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.lw"); + dump_insn(a, pc, static_cast(insn), "c.lw"); const uint32_t rd = insn_get_CIW_CL_rd_CS_CA_rs2(insn); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const int32_t imm = insn_get_C_LW_C_SW_imm(insn); @@ -4757,7 +4763,7 @@ static FORCE_INLINE execute_status execute_C_LW(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.LD instruction. template static FORCE_INLINE execute_status execute_C_LD(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.ld"); + dump_insn(a, pc, static_cast(insn), "c.ld"); const uint32_t rd = insn_get_CIW_CL_rd_CS_CA_rs2(insn); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const int32_t imm = insn_get_CL_CS_imm(insn); @@ -4767,11 +4773,11 @@ static FORCE_INLINE execute_status execute_C_LD(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.FSD instruction. template static FORCE_INLINE execute_status execute_C_FSD(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.fsd"); + dump_insn(a, pc, static_cast(insn), "c.fsd"); // If FS is OFF, attempts to read or write the float state will cause an illegal instruction // exception. if (unlikely((a.read_mstatus() & MSTATUS_FS_MASK) == MSTATUS_FS_OFF)) { - return raise_illegal_insn_exception(a, pc, insn); + return raise_illegal_insn_exception(a, pc, static_cast(insn)); } const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const uint32_t rs2 = insn_get_CIW_CL_rd_CS_CA_rs2(insn); @@ -4782,7 +4788,7 @@ static FORCE_INLINE execute_status execute_C_FSD(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SW instruction. template static FORCE_INLINE execute_status execute_C_SW(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.sw"); + dump_insn(a, pc, static_cast(insn), "c.sw"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const uint32_t rs2 = insn_get_CIW_CL_rd_CS_CA_rs2(insn); const int32_t imm = insn_get_C_LW_C_SW_imm(insn); @@ -4792,7 +4798,7 @@ static FORCE_INLINE execute_status execute_C_SW(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.SD instruction. template static FORCE_INLINE execute_status execute_C_SD(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.sd"); + dump_insn(a, pc, static_cast(insn), "c.sd"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const uint32_t rs2 = insn_get_CIW_CL_rd_CS_CA_rs2(insn); const int32_t imm = insn_get_CL_CS_imm(insn); @@ -4802,7 +4808,7 @@ static FORCE_INLINE execute_status execute_C_SD(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.NOP instruction. template static FORCE_INLINE execute_status execute_C_NOP(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.nop"); + dump_insn(a, pc, static_cast(insn), "c.nop"); // Really do nothing return advance_to_next_insn<2>(a, pc); } @@ -4810,7 +4816,7 @@ static FORCE_INLINE execute_status execute_C_NOP(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.ADDI instruction. template static FORCE_INLINE execute_status execute_C_ADDI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.addi"); + dump_insn(a, pc, static_cast(insn), "c.addi"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); const int32_t imm = insn_get_CI_CB_imm_se(insn); @@ -4825,7 +4831,7 @@ static FORCE_INLINE execute_status execute_C_ADDI(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.addiw instruction. template static FORCE_INLINE execute_status execute_C_ADDIW(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.addiw"); + dump_insn(a, pc, static_cast(insn), "c.addiw"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); const uint64_t rd_value = a.read_x(rd); @@ -4839,7 +4845,7 @@ static FORCE_INLINE execute_status execute_C_ADDIW(STATE_ACCESS &a, uint64_t &pc /// \brief Implementation of the C.LI instruction. template static FORCE_INLINE execute_status execute_C_LI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.li"); + dump_insn(a, pc, static_cast(insn), "c.li"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); const int32_t imm = insn_get_CI_CB_imm_se(insn); @@ -4850,7 +4856,7 @@ static FORCE_INLINE execute_status execute_C_LI(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.ADDI16SP instruction. template static FORCE_INLINE execute_status execute_C_ADDI16SP(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.addi16sp"); + dump_insn(a, pc, static_cast(insn), "c.addi16sp"); // imm cannot be zero (guaranteed by the jump table) const int32_t imm = insn_get_C_ADDI16SP_imm(insn); const uint64_t rs1_value = a.read_x(2); @@ -4863,7 +4869,7 @@ static FORCE_INLINE execute_status execute_C_ADDI16SP(STATE_ACCESS &a, uint64_t /// \brief Implementation of the C.LUI instruction. template static FORCE_INLINE execute_status execute_C_LUI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.lui"); + dump_insn(a, pc, static_cast(insn), "c.lui"); // imm cannot be zero (guaranteed by the jump table) const int32_t imm = insn_get_C_LUI_imm(insn); // rd cannot be zero (guaranteed by the jump table) @@ -4875,7 +4881,7 @@ static FORCE_INLINE execute_status execute_C_LUI(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SRLI instruction. template static FORCE_INLINE execute_status execute_C_SRLI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.srli"); + dump_insn(a, pc, static_cast(insn), "c.srli"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); // imm cannot be zero (guaranteed by the jump table) const uint32_t imm = insn_get_CI_CB_imm(insn); @@ -4887,7 +4893,7 @@ static FORCE_INLINE execute_status execute_C_SRLI(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SRAI instruction. template static FORCE_INLINE execute_status execute_C_SRAI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.srai"); + dump_insn(a, pc, static_cast(insn), "c.srai"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); // imm cannot be zero (guaranteed by the jump table) const uint32_t imm = insn_get_CI_CB_imm(insn); @@ -4899,7 +4905,7 @@ static FORCE_INLINE execute_status execute_C_SRAI(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.ANDI instruction. template static FORCE_INLINE execute_status execute_C_ANDI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.andi"); + dump_insn(a, pc, static_cast(insn), "c.andi"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); const int32_t imm = insn_get_CI_CB_imm_se(insn); const uint64_t rs1_value = a.read_x(rs1); @@ -4922,7 +4928,7 @@ static FORCE_INLINE execute_status execute_C_arithmetic(STATE_ACCESS &a, uint64_ /// \brief Implementation of the C.SUB instruction. template static FORCE_INLINE execute_status execute_C_SUB(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.sub"); + dump_insn(a, pc, static_cast(insn), "c.sub"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { uint64_t val = 0; __builtin_sub_overflow(rs1_value, rs2_value, &val); @@ -4933,7 +4939,7 @@ static FORCE_INLINE execute_status execute_C_SUB(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.XOR instruction. template static FORCE_INLINE execute_status execute_C_XOR(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.xor"); + dump_insn(a, pc, static_cast(insn), "c.xor"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { return rs1_value ^ rs2_value; }); } @@ -4941,7 +4947,7 @@ static FORCE_INLINE execute_status execute_C_XOR(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.OR instruction. template static FORCE_INLINE execute_status execute_C_OR(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.or"); + dump_insn(a, pc, static_cast(insn), "c.or"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { return rs1_value | rs2_value; }); } @@ -4949,7 +4955,7 @@ static FORCE_INLINE execute_status execute_C_OR(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.AND instruction. template static FORCE_INLINE execute_status execute_C_AND(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.and"); + dump_insn(a, pc, static_cast(insn), "c.and"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { return rs1_value & rs2_value; }); } @@ -4957,7 +4963,7 @@ static FORCE_INLINE execute_status execute_C_AND(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SUBW instruction. template static FORCE_INLINE execute_status execute_C_SUBW(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.subw"); + dump_insn(a, pc, static_cast(insn), "c.subw"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { // Convert 64-bit to 32-bit auto rs1w = static_cast(rs1_value); @@ -4971,7 +4977,7 @@ static FORCE_INLINE execute_status execute_C_SUBW(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.ADDW instruction. template static FORCE_INLINE execute_status execute_C_ADDW(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.addw"); + dump_insn(a, pc, static_cast(insn), "c.addw"); return execute_C_arithmetic(a, pc, insn, [](uint64_t rs1_value, uint64_t rs2_value) -> uint64_t { // Discard upper 32 bits auto rs1w = static_cast(rs1_value); @@ -4985,7 +4991,7 @@ static FORCE_INLINE execute_status execute_C_ADDW(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C_J instruction. template static FORCE_INLINE execute_status execute_C_J(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.j"); + dump_insn(a, pc, static_cast(insn), "c.j"); const uint64_t new_pc = pc + static_cast(insn_get_C_J_imm(insn)); return execute_jump(a, pc, new_pc); } @@ -4993,7 +4999,7 @@ static FORCE_INLINE execute_status execute_C_J(STATE_ACCESS &a, uint64_t &pc, ui /// \brief Implementation of the C.BEQZ instruction. template static FORCE_INLINE execute_status execute_C_BEQZ(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.beqz"); + dump_insn(a, pc, static_cast(insn), "c.beqz"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); if (a.read_x(rs1) == 0) { const int32_t imm = insn_get_C_BEQZ_BNEZ_imm(insn); @@ -5006,7 +5012,7 @@ static FORCE_INLINE execute_status execute_C_BEQZ(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.BNEZ instruction. template static FORCE_INLINE execute_status execute_C_BNEZ(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.bnez"); + dump_insn(a, pc, static_cast(insn), "c.bnez"); const uint32_t rs1 = insn_get_CL_CS_CA_CB_rs1(insn); if (a.read_x(rs1) != 0) { const int32_t imm = insn_get_C_BEQZ_BNEZ_imm(insn); @@ -5019,7 +5025,7 @@ static FORCE_INLINE execute_status execute_C_BNEZ(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SLLI instruction. template static FORCE_INLINE execute_status execute_C_SLLI(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.slli"); + dump_insn(a, pc, static_cast(insn), "c.slli"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); // imm cannot be zero (guaranteed by jump table) @@ -5032,11 +5038,11 @@ static FORCE_INLINE execute_status execute_C_SLLI(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.FLDSP instruction. template static FORCE_INLINE execute_status execute_C_FLDSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.fldsp"); + dump_insn(a, pc, static_cast(insn), "c.fldsp"); // If FS is OFF, attempts to read or write the float state will cause an illegal instruction // exception. if (unlikely((a.read_mstatus() & MSTATUS_FS_MASK) == MSTATUS_FS_OFF)) { - return raise_illegal_insn_exception(a, pc, insn); + return raise_illegal_insn_exception(a, pc, static_cast(insn)); } const uint32_t rd = insn_get_rd(insn); const int32_t imm = insn_get_C_FLDSP_LDSP_imm(insn); @@ -5046,7 +5052,7 @@ static FORCE_INLINE execute_status execute_C_FLDSP(STATE_ACCESS &a, uint64_t &pc /// \brief Implementation of the C.LWSP instruction. template static FORCE_INLINE execute_status execute_C_LWSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.lwsp"); + dump_insn(a, pc, static_cast(insn), "c.lwsp"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); const int32_t imm = insn_get_C_LWSP_imm(insn); @@ -5056,7 +5062,7 @@ static FORCE_INLINE execute_status execute_C_LWSP(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.LDSP instruction. template static FORCE_INLINE execute_status execute_C_LDSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.ldsp"); + dump_insn(a, pc, static_cast(insn), "c.ldsp"); // rd cannot be zero (guaranteed by jump table) const uint32_t rd = insn_get_rd(insn); const int32_t imm = insn_get_C_FLDSP_LDSP_imm(insn); @@ -5066,7 +5072,7 @@ static FORCE_INLINE execute_status execute_C_LDSP(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.JR instruction. template static FORCE_INLINE execute_status execute_C_JR(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.jr"); + dump_insn(a, pc, static_cast(insn), "c.jr"); // rs1 cannot be zero (guaranteed by the jump table) const uint32_t rs1 = insn_get_rd(insn); const uint64_t new_pc = a.read_x(rs1) & ~static_cast(1); @@ -5076,7 +5082,7 @@ static FORCE_INLINE execute_status execute_C_JR(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.MV instruction. template static FORCE_INLINE execute_status execute_C_MV(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.mv"); + dump_insn(a, pc, static_cast(insn), "c.mv"); // rd cannot be zero (guaranteed by the jump table) const uint32_t rd = insn_get_rd(insn); const uint32_t rs2 = insn_get_CR_CSS_rs2(insn); @@ -5088,7 +5094,7 @@ static FORCE_INLINE execute_status execute_C_MV(STATE_ACCESS &a, uint64_t &pc, u /// \brief Implementation of the C.EBREAK instruction. template static FORCE_INLINE execute_status execute_C_EBREAK(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.ebreak"); + dump_insn(a, pc, static_cast(insn), "c.ebreak"); pc = raise_exception(a, pc, MCAUSE_BREAKPOINT, pc); return advance_to_raised_exception(a, pc); } @@ -5096,7 +5102,7 @@ static FORCE_INLINE execute_status execute_C_EBREAK(STATE_ACCESS &a, uint64_t &p /// \brief Implementation of the C.JALR instruction. template static FORCE_INLINE execute_status execute_C_JALR(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.jalr"); + dump_insn(a, pc, static_cast(insn), "c.jalr"); const uint32_t rs1 = insn_get_rd(insn); const uint64_t new_pc = a.read_x(rs1) & ~static_cast(1); const uint64_t val = pc + 2; @@ -5107,7 +5113,7 @@ static FORCE_INLINE execute_status execute_C_JALR(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.ADD instruction. template static FORCE_INLINE execute_status execute_C_ADD(STATE_ACCESS &a, uint64_t &pc, uint32_t insn) { - dump_insn(a, pc, insn, "c.add"); + dump_insn(a, pc, static_cast(insn), "c.add"); // rd cannot be zero (guaranteed by the jump table) const uint32_t rd = insn_get_rd(insn); const uint32_t rs2 = insn_get_CR_CSS_rs2(insn); @@ -5122,11 +5128,11 @@ static FORCE_INLINE execute_status execute_C_ADD(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.FSDSP instruction. template static FORCE_INLINE execute_status execute_C_FSDSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.fsdsp"); + dump_insn(a, pc, static_cast(insn), "c.fsdsp"); // If FS is OFF, attempts to read or write the float state will cause an illegal instruction // exception. if (unlikely((a.read_mstatus() & MSTATUS_FS_MASK) == MSTATUS_FS_OFF)) { - return raise_illegal_insn_exception(a, pc, insn); + return raise_illegal_insn_exception(a, pc, static_cast(insn)); } const uint32_t rs2 = insn_get_CR_CSS_rs2(insn); const int32_t imm = insn_get_C_FSDSP_SDSP_imm(insn); @@ -5136,7 +5142,7 @@ static FORCE_INLINE execute_status execute_C_FSDSP(STATE_ACCESS &a, uint64_t &pc /// \brief Implementation of the C.SWSP instruction. template static FORCE_INLINE execute_status execute_C_SWSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.swsp"); + dump_insn(a, pc, static_cast(insn), "c.swsp"); const uint32_t rs2 = insn_get_CR_CSS_rs2(insn); const int32_t imm = insn_get_C_SWSP_imm(insn); return execute_C_S(a, pc, mcycle, rs2, 0x2, imm); @@ -5145,7 +5151,7 @@ static FORCE_INLINE execute_status execute_C_SWSP(STATE_ACCESS &a, uint64_t &pc, /// \brief Implementation of the C.SDSP instruction. template static FORCE_INLINE execute_status execute_C_SDSP(STATE_ACCESS &a, uint64_t &pc, uint64_t mcycle, uint32_t insn) { - dump_insn(a, pc, insn, "c.sdsp"); + dump_insn(a, pc, static_cast(insn), "c.sdsp"); const uint32_t rs2 = insn_get_CR_CSS_rs2(insn); const int32_t imm = insn_get_C_FSDSP_SDSP_imm(insn); return execute_C_S(a, pc, mcycle, rs2, 0x2, imm); @@ -5253,7 +5259,7 @@ static FORCE_INLINE fetch_status fetch_insn(STATE_ACCESS &a, uint64_t &pc, uint3 // Here we are crossing page boundary, this is unlikely (1 in 2048 possible cases) insn = aliased_aligned_read(hptr); // If not a compressed instruction, we must read 2 additional bytes from the next page. - if (unlikely((insn & 3) == 3)) { + if (unlikely(insn_is_uncompressed(insn))) { // We have to perform a new address translation to read the next 2 bytes since we changed pages. const uint64_t vaddr = pc + 2; if (unlikely(fetch_translate_pc(a, pc, vaddr, &hptr) == fetch_status::exception)) { @@ -5503,115 +5509,115 @@ static NO_INLINE execute_status interpret_loop(STATE_ACCESS &a, uint64_t mcycle_ // C extension INSN_CASE(C_HINT): INSN_CASE(C_NOP): - status = execute_C_NOP(a, pc, static_cast(insn)); + status = execute_C_NOP(a, pc, insn); INSN_BREAK(); INSN_CASE(C_LUI): - status = execute_C_LUI(a, pc, static_cast(insn)); + status = execute_C_LUI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_LI): - status = execute_C_LI(a, pc, static_cast(insn)); + status = execute_C_LI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_J): - status = execute_C_J(a, pc, static_cast(insn)); + status = execute_C_J(a, pc, insn); INSN_BREAK(); INSN_CASE(C_JR): - status = execute_C_JR(a, pc, static_cast(insn)); + status = execute_C_JR(a, pc, insn); INSN_BREAK(); INSN_CASE(C_JALR): - status = execute_C_JALR(a, pc, static_cast(insn)); + status = execute_C_JALR(a, pc, insn); INSN_BREAK(); INSN_CASE(C_MV): - status = execute_C_MV(a, pc, static_cast(insn)); + status = execute_C_MV(a, pc, insn); INSN_BREAK(); INSN_CASE(C_BEQZ): - status = execute_C_BEQZ(a, pc, static_cast(insn)); + status = execute_C_BEQZ(a, pc, insn); INSN_BREAK(); INSN_CASE(C_BNEZ): - status = execute_C_BNEZ(a, pc, static_cast(insn)); + status = execute_C_BNEZ(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADDI): - status = execute_C_ADDI(a, pc, static_cast(insn)); + status = execute_C_ADDI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADDIW): - status = execute_C_ADDIW(a, pc, static_cast(insn)); + status = execute_C_ADDIW(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADDI4SPN): - status = execute_C_ADDI4SPN(a, pc, static_cast(insn)); + status = execute_C_ADDI4SPN(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADDI16SP): - status = execute_C_ADDI16SP(a, pc, static_cast(insn)); + status = execute_C_ADDI16SP(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ANDI): - status = execute_C_ANDI(a, pc, static_cast(insn)); + status = execute_C_ANDI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_SLLI): - status = execute_C_SLLI(a, pc, static_cast(insn)); + status = execute_C_SLLI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_SRAI): - status = execute_C_SRAI(a, pc, static_cast(insn)); + status = execute_C_SRAI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_SRLI): - status = execute_C_SRLI(a, pc, static_cast(insn)); + status = execute_C_SRLI(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADD): - status = execute_C_ADD(a, pc, static_cast(insn)); + status = execute_C_ADD(a, pc, insn); INSN_BREAK(); INSN_CASE(C_SUB): - status = execute_C_SUB(a, pc, static_cast(insn)); + status = execute_C_SUB(a, pc, insn); INSN_BREAK(); INSN_CASE(C_XOR): - status = execute_C_XOR(a, pc, static_cast(insn)); + status = execute_C_XOR(a, pc, insn); INSN_BREAK(); INSN_CASE(C_OR): - status = execute_C_OR(a, pc, static_cast(insn)); + status = execute_C_OR(a, pc, insn); INSN_BREAK(); INSN_CASE(C_AND): - status = execute_C_AND(a, pc, static_cast(insn)); + status = execute_C_AND(a, pc, insn); INSN_BREAK(); INSN_CASE(C_ADDW): - status = execute_C_ADDW(a, pc, static_cast(insn)); + status = execute_C_ADDW(a, pc, insn); INSN_BREAK(); INSN_CASE(C_SUBW): - status = execute_C_SUBW(a, pc, static_cast(insn)); + status = execute_C_SUBW(a, pc, insn); INSN_BREAK(); INSN_CASE(C_LD): - status = execute_C_LD(a, pc, mcycle, static_cast(insn)); + status = execute_C_LD(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_LW): - status = execute_C_LW(a, pc, mcycle, static_cast(insn)); + status = execute_C_LW(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_LDSP): - status = execute_C_LDSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_LDSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_LWSP): - status = execute_C_LWSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_LWSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_SD): - status = execute_C_SD(a, pc, mcycle, static_cast(insn)); + status = execute_C_SD(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_SW): - status = execute_C_SW(a, pc, mcycle, static_cast(insn)); + status = execute_C_SW(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_SDSP): - status = execute_C_SDSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_SDSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_SWSP): - status = execute_C_SWSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_SWSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_FLD): - status = execute_C_FLD(a, pc, mcycle, static_cast(insn)); + status = execute_C_FLD(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_FLDSP): - status = execute_C_FLDSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_FLDSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_FSD): - status = execute_C_FSD(a, pc, mcycle, static_cast(insn)); + status = execute_C_FSD(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_FSDSP): - status = execute_C_FSDSP(a, pc, mcycle, static_cast(insn)); + status = execute_C_FSDSP(a, pc, mcycle, insn); INSN_BREAK(); INSN_CASE(C_EBREAK): - status = execute_C_EBREAK(a, pc, static_cast(insn)); + status = execute_C_EBREAK(a, pc, insn); INSN_BREAK(); // FD extensions INSN_CASE(FD): @@ -5761,7 +5767,7 @@ static NO_INLINE execute_status interpret_loop(STATE_ACCESS &a, uint64_t mcycle_ INSN_BREAK(); // Illegal instructions INSN_CASE(ILLEGAL): - status = raise_illegal_insn_exception(a, pc, ((insn & 3) != 3) ? static_cast(insn) : insn); + status = raise_illegal_insn_exception(a, pc, insn_is_uncompressed(insn) ? insn : static_cast(insn)); INSN_BREAK(); } INSN_SWITCH_OUT(); diff --git a/src/soft-float.h b/src/soft-float.h index fbdaa3fc..16671c42 100644 --- a/src/soft-float.h +++ b/src/soft-float.h @@ -326,7 +326,7 @@ struct i_sfloat { } /// \brief Addition operation. - static F_UINT add(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT add(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { // swap so that abs(a) >= abs(b) if ((a & ~SIGN_MASK) < (b & ~SIGN_MASK)) { const F_UINT tmp = a; @@ -379,7 +379,7 @@ struct i_sfloat { } /// \brief Multiply operation. - static F_UINT mul(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT mul(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { const uint32_t a_sign = a >> (F_SIZE - 1); const uint32_t b_sign = b >> (F_SIZE - 1); const uint32_t r_sign = a_sign ^ b_sign; @@ -425,7 +425,7 @@ struct i_sfloat { } /// \brief Fused multiply and add operation. - static F_UINT fma(F_UINT a, F_UINT b, F_UINT c, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT fma(F_UINT a, F_UINT b, F_UINT c, FRM_modes rm, uint32_t *pfflags) { const uint32_t a_sign = a >> (F_SIZE - 1); const uint32_t b_sign = b >> (F_SIZE - 1); uint32_t c_sign = c >> (F_SIZE - 1); @@ -551,7 +551,7 @@ struct i_sfloat { } /// \brief Division operation. - static F_UINT div(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT div(F_UINT a, F_UINT b, FRM_modes rm, uint32_t *pfflags) { const uint32_t a_sign = a >> (F_SIZE - 1); const uint32_t b_sign = b >> (F_SIZE - 1); const uint32_t r_sign = a_sign ^ b_sign; @@ -612,7 +612,7 @@ struct i_sfloat { } /// \brief Square root operation. - static F_UINT sqrt(F_UINT a, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT sqrt(F_UINT a, FRM_modes rm, uint32_t *pfflags) { const uint32_t a_sign = a >> (F_SIZE - 1); int32_t a_exp = (a >> MANT_SIZE) & EXP_MASK; F_UINT a_mant = a & MANT_MASK; @@ -762,7 +762,7 @@ struct i_sfloat { /// \brief Conversion from float to integer. template - static ICVT_INT cvt_f_i(F_UINT a, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE ICVT_INT cvt_f_i(F_UINT a, FRM_modes rm, uint32_t *pfflags) { using ICVT_UINT = std::make_unsigned_t; constexpr bool IS_UNSIGNED = std::is_unsigned_v; constexpr int ICVT_SIZE = sizeof(ICVT_UINT) * 8; @@ -841,7 +841,7 @@ struct i_sfloat { /// \brief Conversion from integer to float. template - static F_UINT cvt_i_f(ICVT_INT a, FRM_modes rm, uint32_t *pfflags) { + static NO_INLINE F_UINT cvt_i_f(ICVT_INT a, FRM_modes rm, uint32_t *pfflags) { using ICVT_UINT = std::make_unsigned_t; constexpr bool IS_UNSIGNED = std::is_unsigned_v; constexpr int ICVT_SIZE = sizeof(ICVT_UINT) * 8; @@ -870,7 +870,7 @@ using i_sfloat32 = i_sfloat; // Interface for single-precision using i_sfloat64 = i_sfloat; // Interface for double-precision floating-point /// \brief Conversion from float32 to float64. -static uint64_t sfloat_cvt_f32_f64(uint32_t a, uint32_t *pfflags) { +static NO_INLINE uint64_t sfloat_cvt_f32_f64(uint32_t a, uint32_t *pfflags) { uint32_t a_sign = 0; int32_t a_exp = 0; i_sfloat64::F_UINT a_mant = i_sfloat32::unpack(&a_sign, &a_exp, a); @@ -899,7 +899,7 @@ static uint64_t sfloat_cvt_f32_f64(uint32_t a, uint32_t *pfflags) { } /// \brief Conversion from float64 to float32. -static uint32_t sfloat_cvt_f64_f32(uint64_t a, FRM_modes rm, uint32_t *pfflags) { +static NO_INLINE uint32_t sfloat_cvt_f64_f32(uint64_t a, FRM_modes rm, uint32_t *pfflags) { uint32_t a_sign = 0; int32_t a_exp = 0; i_sfloat64::F_UINT a_mant = i_sfloat64::unpack(&a_sign, &a_exp, a);