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