summaryrefslogtreecommitdiff
path: root/lib/Target/RISCV/RISCVInstrFormats.td
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/RISCV/RISCVInstrFormats.td')
-rw-r--r--lib/Target/RISCV/RISCVInstrFormats.td196
1 files changed, 164 insertions, 32 deletions
diff --git a/lib/Target/RISCV/RISCVInstrFormats.td b/lib/Target/RISCV/RISCVInstrFormats.td
index 3fab7122f6f1..7479ffbc9532 100644
--- a/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/lib/Target/RISCV/RISCVInstrFormats.td
@@ -25,9 +25,66 @@
//
//===----------------------------------------------------------------------===//
-class RISCVInst<dag outs, dag ins, string asmstr, list<dag> pattern>
+// Format specifies the encoding used by the instruction. This is used by
+// RISCVMCCodeEmitter to determine which form of fixup to use. These
+// definitions must be kept in-sync with RISCVBaseInfo.h.
+class InstFormat<bits<5> val> {
+ bits<5> Value = val;
+}
+def InstFormatPseudo : InstFormat<0>;
+def InstFormatR : InstFormat<1>;
+def InstFormatR4 : InstFormat<2>;
+def InstFormatI : InstFormat<3>;
+def InstFormatS : InstFormat<4>;
+def InstFormatB : InstFormat<5>;
+def InstFormatU : InstFormat<6>;
+def InstFormatJ : InstFormat<7>;
+def InstFormatCR : InstFormat<8>;
+def InstFormatCI : InstFormat<9>;
+def InstFormatCSS : InstFormat<10>;
+def InstFormatCIW : InstFormat<11>;
+def InstFormatCL : InstFormat<12>;
+def InstFormatCS : InstFormat<13>;
+def InstFormatCB : InstFormat<14>;
+def InstFormatCJ : InstFormat<15>;
+def InstFormatOther : InstFormat<16>;
+
+// The following opcode names and match those given in Table 19.1 in the
+// RISC-V User-level ISA specification ("RISC-V base opcode map").
+class RISCVOpcode<bits<7> val> {
+ bits<7> Value = val;
+}
+def OPC_LOAD : RISCVOpcode<0b0000011>;
+def OPC_LOAD_FP : RISCVOpcode<0b0000111>;
+def OPC_MISC_MEM : RISCVOpcode<0b0001111>;
+def OPC_OP_IMM : RISCVOpcode<0b0010011>;
+def OPC_AUIPC : RISCVOpcode<0b0010111>;
+def OPC_OP_IMM_32 : RISCVOpcode<0b0011011>;
+def OPC_STORE : RISCVOpcode<0b0100011>;
+def OPC_STORE_FP : RISCVOpcode<0b0100111>;
+def OPC_AMO : RISCVOpcode<0b0101111>;
+def OPC_OP : RISCVOpcode<0b0110011>;
+def OPC_LUI : RISCVOpcode<0b0110111>;
+def OPC_OP_32 : RISCVOpcode<0b0111011>;
+def OPC_MADD : RISCVOpcode<0b1000011>;
+def OPC_MSUB : RISCVOpcode<0b1000111>;
+def OPC_NMSUB : RISCVOpcode<0b1001011>;
+def OPC_NMADD : RISCVOpcode<0b1001111>;
+def OPC_OP_FP : RISCVOpcode<0b1010011>;
+def OPC_BRANCH : RISCVOpcode<0b1100011>;
+def OPC_JALR : RISCVOpcode<0b1100111>;
+def OPC_JAL : RISCVOpcode<0b1101111>;
+def OPC_SYSTEM : RISCVOpcode<0b1110011>;
+
+class RVInst<dag outs, dag ins, string opcodestr, string argstr,
+ list<dag> pattern, InstFormat format>
: Instruction {
field bits<32> Inst;
+ // SoftFail is a field the disassembler can use to provide a way for
+ // instructions to not match without killing the whole decode process. It is
+ // mainly used for ARM, but Tablegen expects this field to exist or it fails
+ // to build the decode table.
+ field bits<32> SoftFail = 0;
let Size = 4;
bits<7> Opcode = 0;
@@ -38,20 +95,26 @@ class RISCVInst<dag outs, dag ins, string asmstr, list<dag> pattern>
dag OutOperandList = outs;
dag InOperandList = ins;
- let AsmString = asmstr;
+ let AsmString = opcodestr # "\t" # argstr;
let Pattern = pattern;
+
+ let TSFlags{4-0} = format.Value;
}
// Pseudo instructions
-class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, "", pattern> {
+class Pseudo<dag outs, dag ins, list<dag> pattern>
+ : RVInst<outs, ins, "", "", pattern, InstFormatPseudo> {
let isPseudo = 1;
let isCodeGenOnly = 1;
}
-class FR<bits<7> funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins,
- string asmstr, list<dag> pattern> : RISCVInst<outs, ins, asmstr, pattern>
-{
+// Instruction formats are listed in the order they appear in the RISC-V
+// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4,
+// RVInstRAtomic) sorted alphabetically.
+
+class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs,
+ dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
bits<5> rs2;
bits<5> rs1;
bits<5> rd;
@@ -61,12 +124,64 @@ class FR<bits<7> funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins,
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = rd;
- let Opcode = opcode;
+ let Opcode = opcode.Value;
+}
+
+class RVInstR4<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> {
+ bits<5> rs3;
+ bits<5> rs2;
+ bits<5> rs1;
+ bits<3> funct3;
+ bits<5> rd;
+
+ let Inst{31-27} = rs3;
+ let Inst{26-25} = funct2;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Opcode = opcode.Value;
}
-class FI<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3,
+ RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
+ string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+ bits<5> rs2;
+ bits<5> rs1;
+ bits<5> rd;
+
+ let Inst{31-27} = funct5;
+ let Inst{26} = aq;
+ let Inst{25} = rl;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Opcode = opcode.Value;
+}
+
+class RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+ bits<5> rs2;
+ bits<5> rs1;
+ bits<3> funct3;
+ bits<5> rd;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Opcode = opcode.Value;
+}
+
+class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<12> imm12;
bits<5> rs1;
bits<5> rd;
@@ -75,12 +190,29 @@ class FI<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = rd;
- let Opcode = opcode;
+ let Opcode = opcode.Value;
+}
+
+class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode,
+ dag outs, dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
+ bits<6> shamt;
+ bits<5> rs1;
+ bits<5> rd;
+
+ let Inst{31} = 0;
+ let Inst{30} = arithshift;
+ let Inst{29-26} = 0;
+ let Inst{25-20} = shamt;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Opcode = opcode.Value;
}
-class FI32Shift<bit arithshift, bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstIShiftW<bit arithshift, bits<3> funct3, RISCVOpcode opcode,
+ dag outs, dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<5> shamt;
bits<5> rs1;
bits<5> rd;
@@ -92,12 +224,12 @@ class FI32Shift<bit arithshift, bits<3> funct3, bits<7> opcode, dag outs, dag in
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = rd;
- let Opcode = opcode;
+ let Opcode = opcode.Value;
}
-class FS<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> {
bits<12> imm12;
bits<5> rs2;
bits<5> rs1;
@@ -107,12 +239,12 @@ class FS<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = imm12{4-0};
- let Opcode = opcode;
+ let Opcode = opcode.Value;
}
-class FSB<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> {
bits<12> imm12;
bits<5> rs2;
bits<5> rs1;
@@ -124,23 +256,23 @@ class FSB<bits<3> funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list
let Inst{14-12} = funct3;
let Inst{11-8} = imm12{3-0};
let Inst{7} = imm12{10};
- let Opcode = opcode;
+ let Opcode = opcode.Value;
}
-class FU<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
+ string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> {
bits<20> imm20;
bits<5> rd;
let Inst{31-12} = imm20;
let Inst{11-7} = rd;
- let Opcode = opcode;
+ let Opcode = opcode.Value;
}
-class FUJ<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
- : RISCVInst<outs, ins, asmstr, pattern>
-{
+class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
+ string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> {
bits<20> imm20;
bits<5> rd;
@@ -149,5 +281,5 @@ class FUJ<bits<7> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{20} = imm20{10};
let Inst{19-12} = imm20{18-11};
let Inst{11-7} = rd;
- let Opcode = opcode;
+ let Opcode = opcode.Value;
}