xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrFormats.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric//===-- RISCVInstrFormats.td - RISC-V Instruction Formats --*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//  These instruction format definitions are structured to match the
120b57cec5SDimitry Andric//  description in the RISC-V User-Level ISA specification as closely as
130b57cec5SDimitry Andric//  possible. For instance, the specification describes instructions with the
140b57cec5SDimitry Andric//  MSB (31st bit) on the left and the LSB (0th bit) on the right. This is
150b57cec5SDimitry Andric//  reflected in the order of parameters to each instruction class.
160b57cec5SDimitry Andric//
170b57cec5SDimitry Andric//  One area of divergence is in the description of immediates. The
180b57cec5SDimitry Andric//  specification describes immediate encoding in terms of bit-slicing
190b57cec5SDimitry Andric//  operations on the logical value represented. The immediate argument to
200b57cec5SDimitry Andric//  these instruction formats instead represents the bit sequence that will be
210b57cec5SDimitry Andric//  inserted into the instruction. e.g. although JAL's immediate is logically
220b57cec5SDimitry Andric//  a 21-bit value (where the LSB is always zero), we describe it as an imm20
230b57cec5SDimitry Andric//  to match how it is encoded.
240b57cec5SDimitry Andric//
250b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric// Format specifies the encoding used by the instruction. This is used by
280b57cec5SDimitry Andric// RISCVMCCodeEmitter to determine which form of fixup to use. These
290b57cec5SDimitry Andric// definitions must be kept in-sync with RISCVBaseInfo.h.
300b57cec5SDimitry Andricclass InstFormat<bits<5> val> {
310b57cec5SDimitry Andric  bits<5> Value = val;
320b57cec5SDimitry Andric}
330b57cec5SDimitry Andricdef InstFormatPseudo : InstFormat<0>;
340b57cec5SDimitry Andricdef InstFormatR      : InstFormat<1>;
350b57cec5SDimitry Andricdef InstFormatR4     : InstFormat<2>;
360b57cec5SDimitry Andricdef InstFormatI      : InstFormat<3>;
370b57cec5SDimitry Andricdef InstFormatS      : InstFormat<4>;
380b57cec5SDimitry Andricdef InstFormatB      : InstFormat<5>;
390b57cec5SDimitry Andricdef InstFormatU      : InstFormat<6>;
400b57cec5SDimitry Andricdef InstFormatJ      : InstFormat<7>;
410b57cec5SDimitry Andricdef InstFormatCR     : InstFormat<8>;
420b57cec5SDimitry Andricdef InstFormatCI     : InstFormat<9>;
430b57cec5SDimitry Andricdef InstFormatCSS    : InstFormat<10>;
440b57cec5SDimitry Andricdef InstFormatCIW    : InstFormat<11>;
450b57cec5SDimitry Andricdef InstFormatCL     : InstFormat<12>;
460b57cec5SDimitry Andricdef InstFormatCS     : InstFormat<13>;
470b57cec5SDimitry Andricdef InstFormatCA     : InstFormat<14>;
480b57cec5SDimitry Andricdef InstFormatCB     : InstFormat<15>;
490b57cec5SDimitry Andricdef InstFormatCJ     : InstFormat<16>;
5006c3fb27SDimitry Andricdef InstFormatCU     : InstFormat<17>;
5106c3fb27SDimitry Andricdef InstFormatCLB    : InstFormat<18>;
5206c3fb27SDimitry Andricdef InstFormatCLH    : InstFormat<19>;
5306c3fb27SDimitry Andricdef InstFormatCSB    : InstFormat<20>;
5406c3fb27SDimitry Andricdef InstFormatCSH    : InstFormat<21>;
5506c3fb27SDimitry Andricdef InstFormatOther  : InstFormat<22>;
560b57cec5SDimitry Andric
57e8d8bef9SDimitry Andricclass RISCVVConstraint<bits<3> val> {
58e8d8bef9SDimitry Andric  bits<3> Value = val;
595ffd83dbSDimitry Andric}
60e8d8bef9SDimitry Andricdef NoConstraint  : RISCVVConstraint<0b000>;
61e8d8bef9SDimitry Andricdef VS2Constraint : RISCVVConstraint<0b001>;
62e8d8bef9SDimitry Andricdef VS1Constraint : RISCVVConstraint<0b010>;
63e8d8bef9SDimitry Andricdef VMConstraint  : RISCVVConstraint<0b100>;
64e8d8bef9SDimitry Andric
65e8d8bef9SDimitry Andric// Illegal instructions:
66e8d8bef9SDimitry Andric//
67e8d8bef9SDimitry Andric// * The destination vector register group for a masked vector instruction
68e8d8bef9SDimitry Andric// cannot overlap the source mask register (v0), unless the destination vector
69e8d8bef9SDimitry Andric// register is being written with a mask value (e.g., comparisons) or the
70e8d8bef9SDimitry Andric// scalar result of a reduction.
71e8d8bef9SDimitry Andric//
72e8d8bef9SDimitry Andric// * Widening: The destination EEW is greater than the source EEW, the source
73e8d8bef9SDimitry Andric// EMUL is at least 1. The destination vector register group cannot overlap
74e8d8bef9SDimitry Andric// with the source vector register groups besides the highest-numbered part of
75e8d8bef9SDimitry Andric// the destination register group.
76e8d8bef9SDimitry Andric//
77e8d8bef9SDimitry Andric// * Narrowing: The destination EEW is smaller than the source EEW. The
78e8d8bef9SDimitry Andric// destination vector register group cannot overlap with the source vector
79e8d8bef9SDimitry Andric// register groups besides the lowest-numbered part of the source register
80e8d8bef9SDimitry Andric// group.
81e8d8bef9SDimitry Andric//
82e8d8bef9SDimitry Andric// * vmsbf.m/vmsif.m/vmsof.m: The destination register cannot overlap the
83e8d8bef9SDimitry Andric// source register and, if masked, cannot overlap the mask register ('v0').
84e8d8bef9SDimitry Andric//
85e8d8bef9SDimitry Andric// * viota: The destination register cannot overlap the source register and,
86e8d8bef9SDimitry Andric// if masked, cannot overlap the mask register ('v0').
87e8d8bef9SDimitry Andric//
88e8d8bef9SDimitry Andric// * v[f]slide[1]up: The destination vector register group for vslideup cannot
89e8d8bef9SDimitry Andric// overlap the source vector register group.
90e8d8bef9SDimitry Andric//
91e8d8bef9SDimitry Andric// * vrgather: The destination vector register group cannot overlap with the
92e8d8bef9SDimitry Andric// source vector register groups.
93e8d8bef9SDimitry Andric//
94e8d8bef9SDimitry Andric// * vcompress: The destination vector register group cannot overlap the
95e8d8bef9SDimitry Andric// source vector register group or the source mask register
96e8d8bef9SDimitry Andricdef WidenV       : RISCVVConstraint<!or(VS2Constraint.Value,
97e8d8bef9SDimitry Andric                                        VS1Constraint.Value,
98e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
99e8d8bef9SDimitry Andricdef WidenW       : RISCVVConstraint<!or(VS1Constraint.Value,
100e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
101e8d8bef9SDimitry Andricdef WidenCvt     : RISCVVConstraint<!or(VS2Constraint.Value,
102e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
103e8d8bef9SDimitry Andricdef Iota         : RISCVVConstraint<!or(VS2Constraint.Value,
104e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
105e8d8bef9SDimitry Andricdef SlideUp      : RISCVVConstraint<!or(VS2Constraint.Value,
106e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
107e8d8bef9SDimitry Andricdef Vrgather     : RISCVVConstraint<!or(VS2Constraint.Value,
108e8d8bef9SDimitry Andric                                        VS1Constraint.Value,
109e8d8bef9SDimitry Andric                                        VMConstraint.Value)>;
110e8d8bef9SDimitry Andricdef Vcompress    : RISCVVConstraint<!or(VS2Constraint.Value,
111e8d8bef9SDimitry Andric                                        VS1Constraint.Value)>;
112*0fca6ea1SDimitry Andricdef Sha2Constraint : RISCVVConstraint<!or(VS2Constraint.Value,
113*0fca6ea1SDimitry Andric                                          VS1Constraint.Value)>;
1145ffd83dbSDimitry Andric
1150b57cec5SDimitry Andric// The following opcode names match those given in Table 19.1 in the
1160b57cec5SDimitry Andric// RISC-V User-level ISA specification ("RISC-V base opcode map").
1170eae32dcSDimitry Andricclass RISCVOpcode<string name, bits<7> val> {
1180eae32dcSDimitry Andric  string Name = name;
1190b57cec5SDimitry Andric  bits<7> Value = val;
1200b57cec5SDimitry Andric}
1210eae32dcSDimitry Andricdef RISCVOpcodesList : GenericTable {
1220eae32dcSDimitry Andric  let FilterClass = "RISCVOpcode";
1230eae32dcSDimitry Andric  let Fields = [
1240eae32dcSDimitry Andric    "Name", "Value"
1250eae32dcSDimitry Andric  ];
1260eae32dcSDimitry Andric  let PrimaryKey = [ "Value" ];
1270eae32dcSDimitry Andric  let PrimaryKeyName = "lookupRISCVOpcodeByValue";
1280eae32dcSDimitry Andric}
1290eae32dcSDimitry Andricdef lookupRISCVOpcodeByName : SearchIndex {
1300eae32dcSDimitry Andric  let Table = RISCVOpcodesList;
1310eae32dcSDimitry Andric  let Key = [ "Name" ];
1320eae32dcSDimitry Andric}
1330eae32dcSDimitry Andricdef OPC_LOAD      : RISCVOpcode<"LOAD",      0b0000011>;
1340eae32dcSDimitry Andricdef OPC_LOAD_FP   : RISCVOpcode<"LOAD_FP",   0b0000111>;
135bdd1243dSDimitry Andricdef OPC_CUSTOM_0  : RISCVOpcode<"CUSTOM_0",  0b0001011>;
1360eae32dcSDimitry Andricdef OPC_MISC_MEM  : RISCVOpcode<"MISC_MEM",  0b0001111>;
1370eae32dcSDimitry Andricdef OPC_OP_IMM    : RISCVOpcode<"OP_IMM",    0b0010011>;
1380eae32dcSDimitry Andricdef OPC_AUIPC     : RISCVOpcode<"AUIPC",     0b0010111>;
1390eae32dcSDimitry Andricdef OPC_OP_IMM_32 : RISCVOpcode<"OP_IMM_32", 0b0011011>;
1400eae32dcSDimitry Andricdef OPC_STORE     : RISCVOpcode<"STORE",     0b0100011>;
1410eae32dcSDimitry Andricdef OPC_STORE_FP  : RISCVOpcode<"STORE_FP",  0b0100111>;
142bdd1243dSDimitry Andricdef OPC_CUSTOM_1  : RISCVOpcode<"CUSTOM_1",  0b0101011>;
1430eae32dcSDimitry Andricdef OPC_AMO       : RISCVOpcode<"AMO",       0b0101111>;
1440eae32dcSDimitry Andricdef OPC_OP        : RISCVOpcode<"OP",        0b0110011>;
1450eae32dcSDimitry Andricdef OPC_LUI       : RISCVOpcode<"LUI",       0b0110111>;
1460eae32dcSDimitry Andricdef OPC_OP_32     : RISCVOpcode<"OP_32",     0b0111011>;
1470eae32dcSDimitry Andricdef OPC_MADD      : RISCVOpcode<"MADD",      0b1000011>;
1480eae32dcSDimitry Andricdef OPC_MSUB      : RISCVOpcode<"MSUB",      0b1000111>;
1490eae32dcSDimitry Andricdef OPC_NMSUB     : RISCVOpcode<"NMSUB",     0b1001011>;
1500eae32dcSDimitry Andricdef OPC_NMADD     : RISCVOpcode<"NMADD",     0b1001111>;
1510eae32dcSDimitry Andricdef OPC_OP_FP     : RISCVOpcode<"OP_FP",     0b1010011>;
1520eae32dcSDimitry Andricdef OPC_OP_V      : RISCVOpcode<"OP_V",      0b1010111>;
153bdd1243dSDimitry Andricdef OPC_CUSTOM_2  : RISCVOpcode<"CUSTOM_2",  0b1011011>;
1540eae32dcSDimitry Andricdef OPC_BRANCH    : RISCVOpcode<"BRANCH",    0b1100011>;
1550eae32dcSDimitry Andricdef OPC_JALR      : RISCVOpcode<"JALR",      0b1100111>;
1560eae32dcSDimitry Andricdef OPC_JAL       : RISCVOpcode<"JAL",       0b1101111>;
1570eae32dcSDimitry Andricdef OPC_SYSTEM    : RISCVOpcode<"SYSTEM",    0b1110011>;
158*0fca6ea1SDimitry Andricdef OPC_OP_VE     : RISCVOpcode<"OP_VE",     0b1110111>;
159bdd1243dSDimitry Andricdef OPC_CUSTOM_3  : RISCVOpcode<"CUSTOM_3",  0b1111011>;
1600b57cec5SDimitry Andric
16106c3fb27SDimitry Andricclass RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
16206c3fb27SDimitry Andric                   list<dag> pattern, InstFormat format> : Instruction {
1630b57cec5SDimitry Andric  let Namespace = "RISCV";
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric  dag OutOperandList = outs;
1660b57cec5SDimitry Andric  dag InOperandList = ins;
16706c3fb27SDimitry Andric  let AsmString = opcodestr # !if(!empty(argstr), "", "\t" # argstr);
1680b57cec5SDimitry Andric  let Pattern = pattern;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric  let TSFlags{4-0} = format.Value;
1715ffd83dbSDimitry Andric
1725ffd83dbSDimitry Andric  // Defaults
1735ffd83dbSDimitry Andric  RISCVVConstraint RVVConstraint = NoConstraint;
174e8d8bef9SDimitry Andric  let TSFlags{7-5} = RVVConstraint.Value;
175e8d8bef9SDimitry Andric
176e8d8bef9SDimitry Andric  bits<3> VLMul = 0;
177e8d8bef9SDimitry Andric  let TSFlags{10-8} = VLMul;
178e8d8bef9SDimitry Andric
179fe6060f1SDimitry Andric  bit ForceTailAgnostic = false;
18006c3fb27SDimitry Andric  let TSFlags{11} = ForceTailAgnostic;
181e8d8bef9SDimitry Andric
18206c3fb27SDimitry Andric  bit IsTiedPseudo = 0;
18306c3fb27SDimitry Andric  let TSFlags{12} = IsTiedPseudo;
184e8d8bef9SDimitry Andric
185e8d8bef9SDimitry Andric  bit HasSEWOp = 0;
18606c3fb27SDimitry Andric  let TSFlags{13} = HasSEWOp;
187e8d8bef9SDimitry Andric
188e8d8bef9SDimitry Andric  bit HasVLOp = 0;
18906c3fb27SDimitry Andric  let TSFlags{14} = HasVLOp;
190349cc55cSDimitry Andric
191349cc55cSDimitry Andric  bit HasVecPolicyOp = 0;
19206c3fb27SDimitry Andric  let TSFlags{15} = HasVecPolicyOp;
193349cc55cSDimitry Andric
194349cc55cSDimitry Andric  bit IsRVVWideningReduction = 0;
19506c3fb27SDimitry Andric  let TSFlags{16} = IsRVVWideningReduction;
19681ad6265SDimitry Andric
19781ad6265SDimitry Andric  bit UsesMaskPolicy = 0;
19806c3fb27SDimitry Andric  let TSFlags{17} = UsesMaskPolicy;
199bdd1243dSDimitry Andric
200bdd1243dSDimitry Andric  // Indicates that the result can be considered sign extended from bit 31. Some
201bdd1243dSDimitry Andric  // instructions with this flag aren't W instructions, but are either sign
202bdd1243dSDimitry Andric  // extended from a smaller size, always outputs a small integer, or put zeros
203bdd1243dSDimitry Andric  // in bits 63:31. Used by the SExtWRemoval pass.
204bdd1243dSDimitry Andric  bit IsSignExtendingOpW = 0;
20506c3fb27SDimitry Andric  let TSFlags{18} = IsSignExtendingOpW;
20606c3fb27SDimitry Andric
20706c3fb27SDimitry Andric  bit HasRoundModeOp = 0;
20806c3fb27SDimitry Andric  let TSFlags{19} =  HasRoundModeOp;
20906c3fb27SDimitry Andric
21006c3fb27SDimitry Andric  // This is only valid when HasRoundModeOp is set to 1. HasRoundModeOp is set
21106c3fb27SDimitry Andric  // to 1 for vector fixed-point or floating-point intrinsics. This bit is
21206c3fb27SDimitry Andric  // processed under pass 'RISCVInsertReadWriteCSR' pass to distinguish between
21306c3fb27SDimitry Andric  // fixed-point / floating-point instructions and emit appropriate read/write
21406c3fb27SDimitry Andric  // to the correct CSR.
21506c3fb27SDimitry Andric  bit UsesVXRM = 0;
21606c3fb27SDimitry Andric  let TSFlags{20} =  UsesVXRM;
217cb14a3feSDimitry Andric
218cb14a3feSDimitry Andric  // Indicates whther these instructions can partially overlap between source
219cb14a3feSDimitry Andric  // registers and destination registers according to the vector spec.
220cb14a3feSDimitry Andric  // 0 -> not a vector pseudo
221cb14a3feSDimitry Andric  // 1 -> default value for vector pseudos. not widening or narrowing.
222cb14a3feSDimitry Andric  // 2 -> narrowing case
223cb14a3feSDimitry Andric  // 3 -> widening case
224cb14a3feSDimitry Andric  bits<2> TargetOverlapConstraintType = 0;
225cb14a3feSDimitry Andric  let TSFlags{22-21} = TargetOverlapConstraintType;
22606c3fb27SDimitry Andric}
22706c3fb27SDimitry Andric
22806c3fb27SDimitry Andricclass RVInst<dag outs, dag ins, string opcodestr, string argstr,
22906c3fb27SDimitry Andric             list<dag> pattern, InstFormat format>
23006c3fb27SDimitry Andric    : RVInstCommon<outs, ins, opcodestr, argstr, pattern, format> {
23106c3fb27SDimitry Andric  field bits<32> Inst;
23206c3fb27SDimitry Andric  // SoftFail is a field the disassembler can use to provide a way for
23306c3fb27SDimitry Andric  // instructions to not match without killing the whole decode process. It is
23406c3fb27SDimitry Andric  // mainly used for ARM, but Tablegen expects this field to exist or it fails
23506c3fb27SDimitry Andric  // to build the decode table.
23606c3fb27SDimitry Andric  field bits<32> SoftFail = 0;
23706c3fb27SDimitry Andric  let Size = 4;
2380b57cec5SDimitry Andric}
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric// Pseudo instructions
2410b57cec5SDimitry Andricclass Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = "">
2420eae32dcSDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo> {
2430b57cec5SDimitry Andric  let isPseudo = 1;
2440b57cec5SDimitry Andric  let isCodeGenOnly = 1;
2450b57cec5SDimitry Andric}
2460b57cec5SDimitry Andric
24706c3fb27SDimitry Andricclass PseudoQuietFCMP<DAGOperand Ty>
24804eeddc0SDimitry Andric    : Pseudo<(outs GPR:$rd), (ins Ty:$rs1, Ty:$rs2), []> {
24904eeddc0SDimitry Andric  let hasSideEffects = 1;
25004eeddc0SDimitry Andric  let mayLoad = 0;
25104eeddc0SDimitry Andric  let mayStore = 0;
25204eeddc0SDimitry Andric}
25304eeddc0SDimitry Andric
2540b57cec5SDimitry Andric// Pseudo load instructions.
2555f757f3fSDimitry Andricclass PseudoLoad<string opcodestr>
2565f757f3fSDimitry Andric    : Pseudo<(outs GPR:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> {
2570b57cec5SDimitry Andric  let hasSideEffects = 0;
2580b57cec5SDimitry Andric  let mayLoad = 1;
2590b57cec5SDimitry Andric  let mayStore = 0;
2600b57cec5SDimitry Andric  let isCodeGenOnly = 0;
2610b57cec5SDimitry Andric  let isAsmParserOnly = 1;
2620b57cec5SDimitry Andric}
2630b57cec5SDimitry Andric
2645f757f3fSDimitry Andricclass PseudoFloatLoad<string opcodestr, RegisterClass rdty>
265349cc55cSDimitry Andric    : Pseudo<(outs GPR:$tmp, rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> {
2660b57cec5SDimitry Andric  let hasSideEffects = 0;
2670b57cec5SDimitry Andric  let mayLoad = 1;
2680b57cec5SDimitry Andric  let mayStore = 0;
2690b57cec5SDimitry Andric  let isCodeGenOnly = 0;
2700b57cec5SDimitry Andric  let isAsmParserOnly = 1;
2710b57cec5SDimitry Andric}
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric// Pseudo store instructions.
2740b57cec5SDimitry Andricclass PseudoStore<string opcodestr, RegisterClass rsty = GPR>
275349cc55cSDimitry Andric    : Pseudo<(outs GPR:$tmp), (ins rsty:$rs, bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> {
2760b57cec5SDimitry Andric  let hasSideEffects = 0;
2770b57cec5SDimitry Andric  let mayLoad = 0;
2780b57cec5SDimitry Andric  let mayStore = 1;
2790b57cec5SDimitry Andric  let isCodeGenOnly = 0;
2800b57cec5SDimitry Andric  let isAsmParserOnly = 1;
2810b57cec5SDimitry Andric}
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric// Instruction formats are listed in the order they appear in the RISC-V
2845f757f3fSDimitry Andric// instruction set manual (R, R4, I, S, B, U, J).
2850b57cec5SDimitry Andric
2865f757f3fSDimitry Andric// Common base class for R format instructions. Bits {31-25} should be set by
2875f757f3fSDimitry Andric// the subclasses.
2885f757f3fSDimitry Andricclass RVInstRBase<bits<3> funct3, RISCVOpcode opcode, dag outs,
2890b57cec5SDimitry Andric                  dag ins, string opcodestr, string argstr>
2900b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
2910b57cec5SDimitry Andric  bits<5> rs2;
2920b57cec5SDimitry Andric  bits<5> rs1;
2930b57cec5SDimitry Andric  bits<5> rd;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric  let Inst{24-20} = rs2;
2960b57cec5SDimitry Andric  let Inst{19-15} = rs1;
2970b57cec5SDimitry Andric  let Inst{14-12} = funct3;
2980b57cec5SDimitry Andric  let Inst{11-7} = rd;
29906c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
3000b57cec5SDimitry Andric}
3010b57cec5SDimitry Andric
3025f757f3fSDimitry Andricclass RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs,
3035f757f3fSDimitry Andric              dag ins, string opcodestr, string argstr>
3045f757f3fSDimitry Andric    : RVInstRBase<funct3, opcode, outs, ins, opcodestr, argstr> {
3055f757f3fSDimitry Andric  let Inst{31-25} = funct7;
3065f757f3fSDimitry Andric}
3075f757f3fSDimitry Andric
3085f757f3fSDimitry Andricclass RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3,
3095f757f3fSDimitry Andric                    RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
3105f757f3fSDimitry Andric                    string argstr>
3115f757f3fSDimitry Andric    : RVInstRBase<funct3, opcode, outs, ins, opcodestr, argstr> {
3125f757f3fSDimitry Andric  let Inst{31-27} = funct5;
3135f757f3fSDimitry Andric  let Inst{26} = aq;
3145f757f3fSDimitry Andric  let Inst{25} = rl;
3155f757f3fSDimitry Andric}
3165f757f3fSDimitry Andric
3175f757f3fSDimitry Andricclass RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins,
3185f757f3fSDimitry Andric                 string opcodestr, string argstr>
3195f757f3fSDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
3205f757f3fSDimitry Andric  bits<5> rs2;
3215f757f3fSDimitry Andric  bits<5> rs1;
3225f757f3fSDimitry Andric  bits<3> frm;
3235f757f3fSDimitry Andric  bits<5> rd;
3245f757f3fSDimitry Andric
3255f757f3fSDimitry Andric  let Inst{31-25} = funct7;
3265f757f3fSDimitry Andric  let Inst{24-20} = rs2;
3275f757f3fSDimitry Andric  let Inst{19-15} = rs1;
3285f757f3fSDimitry Andric  let Inst{14-12} = frm;
3295f757f3fSDimitry Andric  let Inst{11-7} = rd;
3305f757f3fSDimitry Andric  let Inst{6-0} = opcode.Value;
3315f757f3fSDimitry Andric}
3325f757f3fSDimitry Andric
333fe6060f1SDimitry Andricclass RVInstR4<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode, dag outs,
334fe6060f1SDimitry Andric               dag ins, string opcodestr, string argstr>
335fe6060f1SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> {
336fe6060f1SDimitry Andric  bits<5> rs3;
337fe6060f1SDimitry Andric  bits<5> rs2;
338fe6060f1SDimitry Andric  bits<5> rs1;
339fe6060f1SDimitry Andric  bits<5> rd;
340fe6060f1SDimitry Andric
341fe6060f1SDimitry Andric  let Inst{31-27} = rs3;
342fe6060f1SDimitry Andric  let Inst{26-25} = funct2;
343fe6060f1SDimitry Andric  let Inst{24-20} = rs2;
344fe6060f1SDimitry Andric  let Inst{19-15} = rs1;
345fe6060f1SDimitry Andric  let Inst{14-12} = funct3;
346fe6060f1SDimitry Andric  let Inst{11-7} = rd;
34706c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
348fe6060f1SDimitry Andric}
349fe6060f1SDimitry Andric
350fe6060f1SDimitry Andricclass RVInstR4Frm<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins,
3510b57cec5SDimitry Andric                  string opcodestr, string argstr>
3520b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> {
3530b57cec5SDimitry Andric  bits<5> rs3;
3540b57cec5SDimitry Andric  bits<5> rs2;
3550b57cec5SDimitry Andric  bits<5> rs1;
3560eae32dcSDimitry Andric  bits<3> frm;
3570b57cec5SDimitry Andric  bits<5> rd;
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric  let Inst{31-27} = rs3;
3600b57cec5SDimitry Andric  let Inst{26-25} = funct2;
3610b57cec5SDimitry Andric  let Inst{24-20} = rs2;
3620b57cec5SDimitry Andric  let Inst{19-15} = rs1;
3630eae32dcSDimitry Andric  let Inst{14-12} = frm;
3640b57cec5SDimitry Andric  let Inst{11-7} = rd;
36506c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
3660b57cec5SDimitry Andric}
3670b57cec5SDimitry Andric
3685f757f3fSDimitry Andric// Common base class for I format instructions. Bits {31-20} should be set by
3695f757f3fSDimitry Andric// the subclasses.
3705f757f3fSDimitry Andricclass RVInstIBase<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
3715f757f3fSDimitry Andric                  string opcodestr, string argstr>
3725f757f3fSDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
3730b57cec5SDimitry Andric  bits<5> rs1;
3740b57cec5SDimitry Andric  bits<5> rd;
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andric  let Inst{19-15} = rs1;
3770b57cec5SDimitry Andric  let Inst{14-12} = funct3;
3780b57cec5SDimitry Andric  let Inst{11-7} = rd;
37906c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
3800b57cec5SDimitry Andric}
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andricclass RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
3830b57cec5SDimitry Andric              string opcodestr, string argstr>
3845f757f3fSDimitry Andric    : RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> {
3850b57cec5SDimitry Andric  bits<12> imm12;
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric  let Inst{31-20} = imm12;
3880b57cec5SDimitry Andric}
3890b57cec5SDimitry Andric
390fe6060f1SDimitry Andricclass RVInstIShift<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
3910b57cec5SDimitry Andric                   dag outs, dag ins, string opcodestr, string argstr>
3925f757f3fSDimitry Andric    : RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> {
3930b57cec5SDimitry Andric  bits<6> shamt;
3940b57cec5SDimitry Andric
395fe6060f1SDimitry Andric  let Inst{31-27} = imm11_7;
396fe6060f1SDimitry Andric  let Inst{26} = 0;
3970b57cec5SDimitry Andric  let Inst{25-20} = shamt;
3980b57cec5SDimitry Andric}
3990b57cec5SDimitry Andric
400fe6060f1SDimitry Andricclass RVInstIShiftW<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
4010b57cec5SDimitry Andric                    dag outs, dag ins, string opcodestr, string argstr>
4025f757f3fSDimitry Andric    : RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> {
4030b57cec5SDimitry Andric  bits<5> shamt;
4040b57cec5SDimitry Andric
405fe6060f1SDimitry Andric  let Inst{31-25} = imm11_5;
4060b57cec5SDimitry Andric  let Inst{24-20} = shamt;
4075f757f3fSDimitry Andric}
4085f757f3fSDimitry Andric
4095f757f3fSDimitry Andricclass RVInstIUnary<bits<12> imm12, bits<3> funct3, RISCVOpcode opcode,
4105f757f3fSDimitry Andric                   dag outs, dag ins, string opcodestr, string argstr>
4115f757f3fSDimitry Andric    : RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> {
4125f757f3fSDimitry Andric  let Inst{31-20} = imm12;
4130b57cec5SDimitry Andric}
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andricclass RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
4160b57cec5SDimitry Andric              string opcodestr, string argstr>
4170b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> {
4180b57cec5SDimitry Andric  bits<12> imm12;
4190b57cec5SDimitry Andric  bits<5> rs2;
4200b57cec5SDimitry Andric  bits<5> rs1;
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andric  let Inst{31-25} = imm12{11-5};
4230b57cec5SDimitry Andric  let Inst{24-20} = rs2;
4240b57cec5SDimitry Andric  let Inst{19-15} = rs1;
4250b57cec5SDimitry Andric  let Inst{14-12} = funct3;
4260b57cec5SDimitry Andric  let Inst{11-7} = imm12{4-0};
42706c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
4280b57cec5SDimitry Andric}
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andricclass RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
4310b57cec5SDimitry Andric              string opcodestr, string argstr>
4320b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> {
4330b57cec5SDimitry Andric  bits<12> imm12;
4340b57cec5SDimitry Andric  bits<5> rs2;
4350b57cec5SDimitry Andric  bits<5> rs1;
4360b57cec5SDimitry Andric
4370b57cec5SDimitry Andric  let Inst{31} = imm12{11};
4380b57cec5SDimitry Andric  let Inst{30-25} = imm12{9-4};
4390b57cec5SDimitry Andric  let Inst{24-20} = rs2;
4400b57cec5SDimitry Andric  let Inst{19-15} = rs1;
4410b57cec5SDimitry Andric  let Inst{14-12} = funct3;
4420b57cec5SDimitry Andric  let Inst{11-8} = imm12{3-0};
4430b57cec5SDimitry Andric  let Inst{7} = imm12{10};
44406c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
4450b57cec5SDimitry Andric}
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andricclass RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
4480b57cec5SDimitry Andric              string argstr>
4490b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> {
4500b57cec5SDimitry Andric  bits<20> imm20;
4510b57cec5SDimitry Andric  bits<5> rd;
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric  let Inst{31-12} = imm20;
4540b57cec5SDimitry Andric  let Inst{11-7} = rd;
45506c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
4560b57cec5SDimitry Andric}
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andricclass RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
4590b57cec5SDimitry Andric              string argstr>
4600b57cec5SDimitry Andric    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> {
4610b57cec5SDimitry Andric  bits<20> imm20;
4620b57cec5SDimitry Andric  bits<5> rd;
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andric  let Inst{31} = imm20{19};
4650b57cec5SDimitry Andric  let Inst{30-21} = imm20{9-0};
4660b57cec5SDimitry Andric  let Inst{20} = imm20{10};
4670b57cec5SDimitry Andric  let Inst{19-12} = imm20{18-11};
4680b57cec5SDimitry Andric  let Inst{11-7} = rd;
46906c3fb27SDimitry Andric  let Inst{6-0} = opcode.Value;
4700b57cec5SDimitry Andric}
471349cc55cSDimitry Andric
472349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
473349cc55cSDimitry Andric// Instruction classes for .insn directives
474349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
475349cc55cSDimitry Andric
476349cc55cSDimitry Andricclass DirectiveInsnR<dag outs, dag ins, string argstr>
477349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatR> {
478349cc55cSDimitry Andric  bits<7> opcode;
479349cc55cSDimitry Andric  bits<7> funct7;
480349cc55cSDimitry Andric  bits<3> funct3;
481349cc55cSDimitry Andric
482349cc55cSDimitry Andric  bits<5> rs2;
483349cc55cSDimitry Andric  bits<5> rs1;
484349cc55cSDimitry Andric  bits<5> rd;
485349cc55cSDimitry Andric
486349cc55cSDimitry Andric  let Inst{31-25} = funct7;
487349cc55cSDimitry Andric  let Inst{24-20} = rs2;
488349cc55cSDimitry Andric  let Inst{19-15} = rs1;
489349cc55cSDimitry Andric  let Inst{14-12} = funct3;
490349cc55cSDimitry Andric  let Inst{11-7} = rd;
49106c3fb27SDimitry Andric  let Inst{6-0} = opcode;
492349cc55cSDimitry Andric
493349cc55cSDimitry Andric  let AsmString = ".insn r " # argstr;
494349cc55cSDimitry Andric}
495349cc55cSDimitry Andric
496349cc55cSDimitry Andricclass DirectiveInsnR4<dag outs, dag ins, string argstr>
497349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatR4> {
498349cc55cSDimitry Andric  bits<7> opcode;
499349cc55cSDimitry Andric  bits<2> funct2;
500349cc55cSDimitry Andric  bits<3> funct3;
501349cc55cSDimitry Andric
502349cc55cSDimitry Andric  bits<5> rs3;
503349cc55cSDimitry Andric  bits<5> rs2;
504349cc55cSDimitry Andric  bits<5> rs1;
505349cc55cSDimitry Andric  bits<5> rd;
506349cc55cSDimitry Andric
507349cc55cSDimitry Andric  let Inst{31-27} = rs3;
508349cc55cSDimitry Andric  let Inst{26-25} = funct2;
509349cc55cSDimitry Andric  let Inst{24-20} = rs2;
510349cc55cSDimitry Andric  let Inst{19-15} = rs1;
511349cc55cSDimitry Andric  let Inst{14-12} = funct3;
512349cc55cSDimitry Andric  let Inst{11-7} = rd;
51306c3fb27SDimitry Andric  let Inst{6-0} = opcode;
514349cc55cSDimitry Andric
515349cc55cSDimitry Andric  let AsmString = ".insn r4 " # argstr;
516349cc55cSDimitry Andric}
517349cc55cSDimitry Andric
518349cc55cSDimitry Andricclass DirectiveInsnI<dag outs, dag ins, string argstr>
519349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatI> {
520349cc55cSDimitry Andric  bits<7> opcode;
521349cc55cSDimitry Andric  bits<3> funct3;
522349cc55cSDimitry Andric
523349cc55cSDimitry Andric  bits<12> imm12;
524349cc55cSDimitry Andric  bits<5> rs1;
525349cc55cSDimitry Andric  bits<5> rd;
526349cc55cSDimitry Andric
527349cc55cSDimitry Andric  let Inst{31-20} = imm12;
528349cc55cSDimitry Andric  let Inst{19-15} = rs1;
529349cc55cSDimitry Andric  let Inst{14-12} = funct3;
530349cc55cSDimitry Andric  let Inst{11-7} = rd;
53106c3fb27SDimitry Andric  let Inst{6-0} = opcode;
532349cc55cSDimitry Andric
533349cc55cSDimitry Andric  let AsmString = ".insn i " # argstr;
534349cc55cSDimitry Andric}
535349cc55cSDimitry Andric
536349cc55cSDimitry Andricclass DirectiveInsnS<dag outs, dag ins, string argstr>
537349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatS> {
538349cc55cSDimitry Andric  bits<7> opcode;
539349cc55cSDimitry Andric  bits<3> funct3;
540349cc55cSDimitry Andric
541349cc55cSDimitry Andric  bits<12> imm12;
542349cc55cSDimitry Andric  bits<5> rs2;
543349cc55cSDimitry Andric  bits<5> rs1;
544349cc55cSDimitry Andric
545349cc55cSDimitry Andric  let Inst{31-25} = imm12{11-5};
546349cc55cSDimitry Andric  let Inst{24-20} = rs2;
547349cc55cSDimitry Andric  let Inst{19-15} = rs1;
548349cc55cSDimitry Andric  let Inst{14-12} = funct3;
549349cc55cSDimitry Andric  let Inst{11-7} = imm12{4-0};
55006c3fb27SDimitry Andric  let Inst{6-0} = opcode;
551349cc55cSDimitry Andric
552349cc55cSDimitry Andric  let AsmString = ".insn s " # argstr;
553349cc55cSDimitry Andric}
554349cc55cSDimitry Andric
555349cc55cSDimitry Andricclass DirectiveInsnB<dag outs, dag ins, string argstr>
556349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatB> {
557349cc55cSDimitry Andric  bits<7> opcode;
558349cc55cSDimitry Andric  bits<3> funct3;
559349cc55cSDimitry Andric
560349cc55cSDimitry Andric  bits<12> imm12;
561349cc55cSDimitry Andric  bits<5> rs2;
562349cc55cSDimitry Andric  bits<5> rs1;
563349cc55cSDimitry Andric
564349cc55cSDimitry Andric  let Inst{31} = imm12{11};
565349cc55cSDimitry Andric  let Inst{30-25} = imm12{9-4};
566349cc55cSDimitry Andric  let Inst{24-20} = rs2;
567349cc55cSDimitry Andric  let Inst{19-15} = rs1;
568349cc55cSDimitry Andric  let Inst{14-12} = funct3;
569349cc55cSDimitry Andric  let Inst{11-8} = imm12{3-0};
570349cc55cSDimitry Andric  let Inst{7} = imm12{10};
57106c3fb27SDimitry Andric  let Inst{6-0} = opcode;
572349cc55cSDimitry Andric
573349cc55cSDimitry Andric  let AsmString = ".insn b " # argstr;
574349cc55cSDimitry Andric}
575349cc55cSDimitry Andric
576349cc55cSDimitry Andricclass DirectiveInsnU<dag outs, dag ins, string argstr>
577349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatU> {
578349cc55cSDimitry Andric  bits<7> opcode;
579349cc55cSDimitry Andric
580349cc55cSDimitry Andric  bits<20> imm20;
581349cc55cSDimitry Andric  bits<5> rd;
582349cc55cSDimitry Andric
583349cc55cSDimitry Andric  let Inst{31-12} = imm20;
584349cc55cSDimitry Andric  let Inst{11-7} = rd;
58506c3fb27SDimitry Andric  let Inst{6-0} = opcode;
586349cc55cSDimitry Andric
587349cc55cSDimitry Andric  let AsmString = ".insn u " # argstr;
588349cc55cSDimitry Andric}
589349cc55cSDimitry Andric
590349cc55cSDimitry Andricclass DirectiveInsnJ<dag outs, dag ins, string argstr>
591349cc55cSDimitry Andric  : RVInst<outs, ins, "", "", [], InstFormatJ> {
592349cc55cSDimitry Andric  bits<7> opcode;
593349cc55cSDimitry Andric
594349cc55cSDimitry Andric  bits<20> imm20;
595349cc55cSDimitry Andric  bits<5> rd;
596349cc55cSDimitry Andric
597349cc55cSDimitry Andric  let Inst{31-12} = imm20;
598349cc55cSDimitry Andric  let Inst{11-7} = rd;
59906c3fb27SDimitry Andric  let Inst{6-0} = opcode;
600349cc55cSDimitry Andric
601349cc55cSDimitry Andric  let AsmString = ".insn j " # argstr;
602349cc55cSDimitry Andric}
603