diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/riscv-tdep.c | 40 |
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)) |