-/* Target-dependent header for the RISC-V architecture, for GDB, the GNU Debugger.
+/* Target-dependent header for the RISC-V architecture, for GDB, the
+ GNU Debugger.
- Copyright (C) 2018 Free Software Foundation, Inc.
-
- Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
- and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
- and by Todd Snyder <todd@bluespec.com>
- and by Mike Frysinger <vapier@gentoo.org>.
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
This file is part of GDB.
#ifndef RISCV_TDEP_H
#define RISCV_TDEP_H
+#include "arch/riscv.h"
+#include "gdbarch.h"
+
/* RiscV register numbers. */
enum
{
RISCV_FP_REGNUM = 8, /* Frame Pointer. */
RISCV_A0_REGNUM = 10, /* First argument. */
RISCV_A1_REGNUM = 11, /* Second argument. */
+ RISCV_A7_REGNUM = 17, /* Seventh argument. */
RISCV_PC_REGNUM = 32, /* Program Counter. */
+ RISCV_NUM_INTEGER_REGS = 32,
+
RISCV_FIRST_FP_REGNUM = 33, /* First Floating Point Register */
RISCV_FA0_REGNUM = 43,
RISCV_FA1_REGNUM = RISCV_FA0_REGNUM + 1,
RISCV_LAST_FP_REGNUM = 64, /* Last Floating Point Register */
RISCV_FIRST_CSR_REGNUM = 65, /* First CSR */
-#define DECLARE_CSR(name, num) RISCV_ ## num ## _REGNUM = RISCV_LAST_FP_REGNUM + 1 + num,
+#define DECLARE_CSR(name, num, class, define_version, abort_version) \
+ RISCV_ ## num ## _REGNUM = RISCV_FIRST_CSR_REGNUM + num,
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
RISCV_LAST_CSR_REGNUM = 4160,
- RISCV_CSR_LEGACY_MISA_REGNUM = 0xf10,
+ RISCV_CSR_LEGACY_MISA_REGNUM = 0xf10 + RISCV_FIRST_CSR_REGNUM,
RISCV_PRIV_REGNUM = 4161,
- RISCV_LAST_REGNUM = RISCV_PRIV_REGNUM
+ RISCV_V0_REGNUM,
+
+ RISCV_V31_REGNUM = RISCV_V0_REGNUM + 31,
+
+ RISCV_LAST_REGNUM = RISCV_V31_REGNUM
+};
+
+/* RiscV DWARF register numbers. */
+enum
+{
+ RISCV_DWARF_REGNUM_X0 = 0,
+ RISCV_DWARF_REGNUM_X31 = 31,
+ RISCV_DWARF_REGNUM_F0 = 32,
+ RISCV_DWARF_REGNUM_F31 = 63,
+ RISCV_DWARF_REGNUM_V0 = 96,
+ RISCV_DWARF_REGNUM_V31 = 127,
+ RISCV_DWARF_FIRST_CSR = 4096,
+ RISCV_DWARF_LAST_CSR = 8191,
};
/* RISC-V specific per-architecture information. */
-struct gdbarch_tdep
+struct riscv_gdbarch_tdep : gdbarch_tdep
{
- union
- {
- /* Provide access to the whole ABI in one value. */
- unsigned value;
-
- struct
- {
- /* Encode the base machine length following the same rules as in the
- MISA register. */
- unsigned base_len : 2;
-
- /* Encode which floating point ABI is in use following the same rules
- as the ELF e_flags field. */
- unsigned float_abi : 2;
- } fields;
- } abi;
-
- /* Only the least significant 26 bits are (possibly) valid, and indicate
- features that are supported on the target. These could be cached from
- the target, or read from the executable when available. */
- unsigned core_features;
+ /* Features about the target hardware that impact how the gdbarch is
+ configured. Two gdbarch instances are compatible only if this field
+ matches. */
+ struct riscv_gdbarch_features isa_features;
+
+ /* Features about the abi that impact how the gdbarch is configured. Two
+ gdbarch instances are compatible only if this field matches. */
+ struct riscv_gdbarch_features abi_features;
+
+ /* ISA-specific data types. */
+ struct type *riscv_fpreg_d_type = nullptr;
+
+ /* Use for tracking unknown CSRs in the target description.
+ UNKNOWN_CSRS_FIRST_REGNUM is the number assigned to the first unknown
+ CSR. All other unknown CSRs will be assigned sequential numbers after
+ this, with UNKNOWN_CSRS_COUNT being the total number of unknown CSRs. */
+ int unknown_csrs_first_regnum = -1;
+ int unknown_csrs_count = 0;
+
+ /* Some targets (QEMU) are reporting three registers twice in the target
+ description they send. These three register numbers, when not set to
+ -1, are for the duplicate copies of these registers. */
+ int duplicate_fflags_regnum = -1;
+ int duplicate_frm_regnum = -1;
+ int duplicate_fcsr_regnum = -1;
+
+ /* Return the expected next PC assuming FRAME is stopped at a syscall
+ instruction. */
+ CORE_ADDR (*syscall_next_pc) (struct frame_info *frame) = nullptr;
};
+
+/* Return the width in bytes of the general purpose registers for GDBARCH.
+ Possible return values are 4, 8, or 16 for RiscV variants RV32, RV64, or
+ RV128. */
+extern int riscv_isa_xlen (struct gdbarch *gdbarch);
+
+/* Return the width in bytes of the hardware floating point registers for
+ GDBARCH. If this architecture has no floating point registers, then
+ return 0. Possible values are 4, 8, or 16 for depending on which of
+ single, double or quad floating point support is available. */
+extern int riscv_isa_flen (struct gdbarch *gdbarch);
+
+/* Return the width in bytes of the general purpose register abi for
+ GDBARCH. This can be equal to, or less than RISCV_ISA_XLEN and reflects
+ how the binary was compiled rather than the hardware that is available.
+ It is possible that a binary compiled for RV32 is being run on an RV64
+ target, in which case the isa xlen is 8-bytes, and the abi xlen is
+ 4-bytes. This will impact how inferior functions are called. */
+extern int riscv_abi_xlen (struct gdbarch *gdbarch);
+
+/* Return the width in bytes of the floating point register abi for
+ GDBARCH. This reflects how the binary was compiled rather than the
+ hardware that is available. It is possible that a binary is compiled
+ for single precision floating point, and then run on a target with
+ double precision floating point. A return value of 0 indicates that no
+ floating point abi is in use (floating point arguments will be passed
+ in integer registers) other possible return value are 4, 8, or 16 as
+ with RISCV_ISA_FLEN. */
+extern int riscv_abi_flen (struct gdbarch *gdbarch);
+
+/* Return true if GDBARCH is using the embedded x-regs abi, that is the
+ target only has 16 x-registers, which includes a reduced number of
+ argument registers. */
+extern bool riscv_abi_embedded (struct gdbarch *gdbarch);
+
+/* Single step based on where the current instruction will take us. */
+extern std::vector<CORE_ADDR> riscv_software_single_step
+ (struct regcache *regcache);
+
+/* Supply register REGNUM from the buffer REGS (length LEN) into
+ REGCACHE. REGSET describes the layout of the buffer. If REGNUM is -1
+ then all registers described by REGSET are supplied.
+
+ The register RISCV_ZERO_REGNUM should not be described by REGSET,
+ however, this register (which always has the value 0) will be supplied
+ by this function if requested.
+
+ The registers RISCV_CSR_FFLAGS_REGNUM and RISCV_CSR_FRM_REGNUM should
+ not be described by REGSET, however, these register will be provided if
+ requested assuming either:
+ (a) REGCACHE already contains the value of RISCV_CSR_FCSR_REGNUM, or
+ (b) REGSET describes the location of RISCV_CSR_FCSR_REGNUM in the REGS
+ buffer.
+
+ This function can be used as the supply function for either x-regs or
+ f-regs when loading corefiles, and doesn't care which abi is currently
+ in use. */
+
+extern void riscv_supply_regset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len);
+
+/* The names of the RISC-V target description features. */
+extern const char *riscv_feature_name_csr;
+
#endif /* RISCV_TDEP_H */