/* riscv.h. RISC-V opcode list for GDB, the GNU debugger.
- Copyright (C) 2011-2018 Free Software Foundation, Inc.
+ Copyright (C) 2011-2020 Free Software Foundation, Inc.
Contributed by Andrew Waterman
This file is part of GDB, GAS, and the GNU binutils.
(EXTRACT_RVC_IMM (x) << RISCV_IMM_BITS)
#define EXTRACT_RVC_SIMM3(x) \
(RV_X(x, 10, 2) | (-RV_X(x, 12, 1) << 2))
+#define EXTRACT_RVC_UIMM8(x) \
+ (RV_X(x, 5, 8))
#define EXTRACT_RVC_ADDI4SPN_IMM(x) \
((RV_X(x, 6, 1) << 2) | (RV_X(x, 5, 1) << 3) | (RV_X(x, 11, 2) << 4) | (RV_X(x, 7, 4) << 6))
#define EXTRACT_RVC_ADDI16SP_IMM(x) \
ENCODE_RVC_IMM ((x) >> RISCV_IMM_BITS)
#define ENCODE_RVC_SIMM3(x) \
(RV_X(x, 0, 3) << 10)
+#define ENCODE_RVC_UIMM8(x) \
+ (RV_X(x, 0, 8) << 5)
#define ENCODE_RVC_ADDI4SPN_IMM(x) \
((RV_X(x, 2, 1) << 6) | (RV_X(x, 3, 1) << 5) | (RV_X(x, 4, 2) << 11) | (RV_X(x, 6, 4) << 7))
#define ENCODE_RVC_ADDI16SP_IMM(x) \
#define VALID_RVC_IMM(x) (EXTRACT_RVC_IMM(ENCODE_RVC_IMM(x)) == (x))
#define VALID_RVC_LUI_IMM(x) (ENCODE_RVC_LUI_IMM(x) != 0 && EXTRACT_RVC_LUI_IMM(ENCODE_RVC_LUI_IMM(x)) == (x))
#define VALID_RVC_SIMM3(x) (EXTRACT_RVC_SIMM3(ENCODE_RVC_SIMM3(x)) == (x))
+#define VALID_RVC_UIMM8(x) (EXTRACT_RVC_UIMM8(ENCODE_RVC_UIMM8(x)) == (x))
#define VALID_RVC_ADDI4SPN_IMM(x) (EXTRACT_RVC_ADDI4SPN_IMM(ENCODE_RVC_ADDI4SPN_IMM(x)) == (x))
#define VALID_RVC_ADDI16SP_IMM(x) (EXTRACT_RVC_ADDI16SP_IMM(ENCODE_RVC_ADDI16SP_IMM(x)) == (x))
#define VALID_RVC_LW_IMM(x) (EXTRACT_RVC_LW_IMM(ENCODE_RVC_LW_IMM(x)) == (x))
#define OP_MASK_CSR 0xfff
#define OP_SH_CSR 20
+#define OP_MASK_FUNCT3 0x7
+#define OP_SH_FUNCT3 12
+#define OP_MASK_FUNCT7 0x7f
+#define OP_SH_FUNCT7 25
+#define OP_MASK_FUNCT2 0x3
+#define OP_SH_FUNCT2 25
+
/* RVC fields. */
+#define OP_MASK_OP2 0x3
+#define OP_SH_OP2 0
+
#define OP_MASK_CRS2 0x1f
#define OP_SH_CRS2 2
#define OP_MASK_CRS1S 0x7
#define OP_MASK_CRS2S 0x7
#define OP_SH_CRS2S 2
+#define OP_MASK_CFUNCT6 0x3f
+#define OP_SH_CFUNCT6 10
+#define OP_MASK_CFUNCT4 0xf
+#define OP_SH_CFUNCT4 12
+#define OP_MASK_CFUNCT3 0x7
+#define OP_SH_CFUNCT3 13
+#define OP_MASK_CFUNCT2 0x3
+#define OP_SH_CFUNCT2 5
+
/* ABI names for selected x-registers. */
#define X_RA 1
#define NGPR 32
#define NFPR 32
+/* These fake label defines are use by both the assembler, and
+ libopcodes. The assembler uses this when it needs to generate a fake
+ label, and libopcodes uses it to hide the fake labels in its output. */
+#define RISCV_FAKE_LABEL_NAME ".L0 "
+#define RISCV_FAKE_LABEL_CHAR ' '
+
/* Replace bits MASK << SHIFT of STRUCT with the equivalent bits in
VALUE << SHIFT. VALUE is evaluated exactly once. */
#define INSERT_BITS(STRUCT, VALUE, MASK, SHIFT) \
#define EXTRACT_OPERAND(FIELD, INSN) \
EXTRACT_BITS ((INSN), OP_MASK_##FIELD, OP_SH_##FIELD)
+/* The maximal number of subset can be required. */
+#define MAX_SUBSET_NUM 4
+
+/* All RISC-V instructions belong to at least one of these classes. */
+
+enum riscv_insn_class
+ {
+ INSN_CLASS_NONE,
+
+ INSN_CLASS_I,
+ INSN_CLASS_C,
+ INSN_CLASS_A,
+ INSN_CLASS_M,
+ INSN_CLASS_F,
+ INSN_CLASS_D,
+ INSN_CLASS_D_AND_C,
+ INSN_CLASS_F_AND_C,
+ INSN_CLASS_Q,
+ };
+
/* This structure holds information for a particular instruction. */
struct riscv_opcode
{
/* The name of the instruction. */
const char *name;
- /* The ISA subset name (I, M, A, F, D, Xextension). */
- const char *subset;
+ /* The requirement of xlen for the instruction, 0 if no requirement. */
+ unsigned xlen_requirement;
+ /* Class to which this instruction belongs. Used to decide whether or
+ not this instruction is legal in the current -march context. */
+ enum riscv_insn_class insn_class;
/* A string describing the arguments for this instruction. */
const char *args;
/* The basic opcode for the instruction. When assembling, this
unsigned long pinfo;
};
+/* The current supported ISA spec versions. */
+
+enum riscv_isa_spec_class
+{
+ ISA_SPEC_CLASS_NONE,
+
+ ISA_SPEC_CLASS_2P2,
+ ISA_SPEC_CLASS_20190608,
+ ISA_SPEC_CLASS_20191213
+};
+
+/* This structure holds version information for specific ISA. */
+
+struct riscv_ext_version
+{
+ const char *name;
+ enum riscv_isa_spec_class isa_spec_class;
+ unsigned int major_version;
+ unsigned int minor_version;
+};
+
+/* All RISC-V CSR belong to one of these classes. */
+
+enum riscv_csr_class
+{
+ CSR_CLASS_NONE,
+
+ CSR_CLASS_I,
+ CSR_CLASS_I_32, /* rv32 only */
+ CSR_CLASS_F, /* f-ext only */
+};
+
+/* The current supported privilege spec versions. */
+
+enum riscv_priv_spec_class
+{
+ PRIV_SPEC_CLASS_NONE,
+
+ PRIV_SPEC_CLASS_1P9,
+ PRIV_SPEC_CLASS_1P9P1,
+ PRIV_SPEC_CLASS_1P10,
+ PRIV_SPEC_CLASS_1P11,
+ PRIV_SPEC_CLASS_DRAFT
+};
+
+/* This structure holds all restricted conditions for a CSR. */
+
+struct riscv_csr_extra
+{
+ /* Class to which this CSR belongs. Used to decide whether or
+ not this CSR is legal in the current -march context. */
+ enum riscv_csr_class csr_class;
+
+ /* CSR may have differnet numbers in the previous priv spec. */
+ unsigned address;
+
+ /* Record the CSR is defined/valid in which versions. */
+ enum riscv_priv_spec_class define_version;
+
+ /* Record the CSR is aborted/invalid from which versions. If it isn't
+ aborted in the current version, then it should be CSR_CLASS_VDRAFT. */
+ enum riscv_priv_spec_class abort_version;
+
+ /* The CSR may have more than one setting. */
+ struct riscv_csr_extra *next;
+};
+
/* Instruction is a simple alias (e.g. "mv" for "addi"). */
#define INSN_ALIAS 0x00000001
+
+/* These are for setting insn_info fields.
+
+ Nonbranch is the default. Noninsn is used only if there is no match.
+ There are no condjsr or dref2 instructions. So that leaves condbranch,
+ branch, jsr, and dref that we need to handle here, encoded in 3 bits. */
+#define INSN_TYPE 0x0000000e
+
+/* Instruction is an unconditional branch. */
+#define INSN_BRANCH 0x00000002
+/* Instruction is a conditional branch. */
+#define INSN_CONDBRANCH 0x00000004
+/* Instruction is a jump to subroutine. */
+#define INSN_JSR 0x00000006
+/* Instruction is a data reference. */
+#define INSN_DREF 0x00000008
+
+/* We have 5 data reference sizes, which we can encode in 3 bits. */
+#define INSN_DATA_SIZE 0x00000070
+#define INSN_DATA_SIZE_SHIFT 4
+#define INSN_1_BYTE 0x00000010
+#define INSN_2_BYTE 0x00000020
+#define INSN_4_BYTE 0x00000030
+#define INSN_8_BYTE 0x00000040
+#define INSN_16_BYTE 0x00000050
+
/* Instruction is actually a macro. It should be ignored by the
disassembler, and requires special treatment by the assembler. */
#define INSN_MACRO 0xffffffff
extern const char * const riscv_fpr_names_abi[NFPR];
extern const struct riscv_opcode riscv_opcodes[];
+extern const struct riscv_opcode riscv_insn_types[];
+extern const struct riscv_ext_version riscv_ext_version_table[];
+
+extern int
+riscv_get_isa_spec_class (const char *, enum riscv_isa_spec_class *);
+extern int
+riscv_get_priv_spec_class (const char *, enum riscv_priv_spec_class *);
+extern const char *
+riscv_get_priv_spec_name (enum riscv_priv_spec_class);
#endif /* _RISCV_H_ */