m_imm.s = EXTRACT_ITYPE_IMM (ival);
}
- /* Helper for DECODE, decode 16-bit compressed I-type instruction. */
- void decode_ci_type_insn (enum opcode opcode, ULONGEST ival)
+ /* Helper for DECODE, decode 16-bit compressed I-type instruction. Some
+ of the CI instruction have a hard-coded rs1 register, while others
+ just use rd for both the source and destination. RS1_REGNUM, if
+ passed, is the value to place in rs1, otherwise rd is duplicated into
+ rs1. */
+ void decode_ci_type_insn (enum opcode opcode, ULONGEST ival,
+ gdb::optional<int> rs1_regnum = {})
{
m_opcode = opcode;
- m_rd = m_rs1 = decode_register_index (ival, OP_SH_CRS1S);
+ m_rd = decode_register_index (ival, OP_SH_CRS1S);
+ if (rs1_regnum.has_value ())
+ m_rs1 = *rs1_regnum;
+ else
+ m_rs1 = m_rd;
m_imm.s = EXTRACT_CITYPE_IMM (ival);
}
decode_cl_type_insn (LD, ival);
else if (is_c_lw_insn (ival))
decode_cl_type_insn (LW, ival);
+ else if (is_c_ldsp_insn (ival))
+ decode_ci_type_insn (LD, ival, RISCV_SP_REGNUM);
+ else if (is_c_lwsp_insn (ival))
+ decode_ci_type_insn (LW, ival, RISCV_SP_REGNUM);
else
/* None of the other fields of INSN are valid in this case. */
m_opcode = OTHER;