aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/riscv-tdep.c40
2 files changed, 43 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ee66a06..0d55fd4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2018-08-30 Andrew Burgess <andrew.burgess@embecosm.com>
+ * riscv-tdep.c (riscv_insn::decode): Decode c.addi4spn, c.sd,
+ c.sw, c.swsp, and c.sdsp.
+
+2018-08-30 Andrew Burgess <andrew.burgess@embecosm.com>
+
* riscv-tdep.c (struct riscv_inferior_data): Delete.
(riscv_read_misa_reg): Don't cache value read into inferior data.
(riscv_new_inferior_data): Delete.
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 2f619c3..96431f2 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -972,6 +972,31 @@ private:
m_imm.s = EXTRACT_STYPE_IMM (ival);
}
+ /* Helper for DECODE, decode 16-bit CS-type instruction. The immediate
+ encoding is different for each CS format instruction, so extracting
+ the immediate is left up to the caller, who should pass the extracted
+ immediate value through in IMM. */
+ void decode_cs_type_insn (enum opcode opcode, ULONGEST ival, int imm)
+ {
+ m_opcode = opcode;
+ m_imm.s = imm;
+ m_rs1 = decode_register_index_short (ival, OP_SH_CRS1S);
+ m_rs2 = decode_register_index_short (ival, OP_SH_CRS2S);
+ }
+
+ /* Helper for DECODE, decode 16-bit CSS-type instruction. The immediate
+ encoding is different for each CSS format instruction, so extracting
+ the immediate is left up to the caller, who should pass the extracted
+ immediate value through in IMM. */
+ void decode_css_type_insn (enum opcode opcode, ULONGEST ival, int imm)
+ {
+ m_opcode = opcode;
+ m_imm.s = imm;
+ m_rs1 = RISCV_SP_REGNUM;
+ /* Not a compressed register number in this case. */
+ m_rs2 = decode_register_index (ival, OP_SH_CRS2);
+ }
+
/* Helper for DECODE, decode 32-bit U-type instruction. */
void decode_u_type_insn (enum opcode opcode, ULONGEST ival)
{
@@ -1165,14 +1190,25 @@ riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
m_rd = m_rs1 = decode_register_index (ival, OP_SH_RD);
m_imm.s = EXTRACT_RVC_ADDI16SP_IMM (ival);
}
+ else if (is_c_addi4spn_insn (ival))
+ {
+ m_opcode = ADDI;
+ m_rd = decode_register_index_short (ival, OP_SH_CRS2S);
+ m_rs1 = RISCV_SP_REGNUM;
+ m_imm.s = EXTRACT_RVC_ADDI4SPN_IMM (ival);
+ }
else if (is_c_lui_insn (ival))
m_opcode = OTHER;
/* C_SD and C_FSW have the same opcode. C_SD is RV64 and RV128 only,
and C_FSW is RV32 only. */
else if (xlen != 4 && is_c_sd_insn (ival))
- m_opcode = OTHER;
+ decode_cs_type_insn (SD, ival, EXTRACT_RVC_LD_IMM (ival));
else if (is_c_sw_insn (ival))
- m_opcode = OTHER;
+ decode_cs_type_insn (SW, ival, EXTRACT_RVC_LW_IMM (ival));
+ else if (is_c_swsp_insn (ival))
+ decode_css_type_insn (SW, ival, EXTRACT_RVC_SWSP_IMM (ival));
+ else if (xlen != 4 && is_c_sdsp_insn (ival))
+ decode_css_type_insn (SW, ival, EXTRACT_RVC_SDSP_IMM (ival));
/* C_JR and C_MV have the same opcode. If RS2 is 0, then this is a C_JR.
So must try to match C_JR first as it ahs more bits in mask. */
else if (is_c_jr_insn (ival))