1//===-- RISCVInstrFormats.td - RISCV Instruction Formats ---*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// 11// These instruction format definitions are structured to match the 12// description in the RISC-V User-Level ISA specification as closely as 13// possible. For instance, the specification describes instructions with the 14// MSB (31st bit) on the left and the LSB (0th bit) on the right. This is 15// reflected in the order of parameters to each instruction class. 16// 17// One area of divergence is in the description of immediates. The 18// specification describes immediate encoding in terms of bit-slicing 19// operations on the logical value represented. The immediate argument to 20// these instruction formats instead represents the bit sequence that will be 21// inserted into the instruction. e.g. although JAL's immediate is logically 22// a 21-bit value (where the LSB is always zero), we describe it as an imm20 23// to match how it is encoded. 24// 25//===----------------------------------------------------------------------===// 26 27// Format specifies the encoding used by the instruction. This is used by 28// RISCVMCCodeEmitter to determine which form of fixup to use. These 29// definitions must be kept in-sync with RISCVBaseInfo.h. 30class InstFormat<bits<5> val> { 31 bits<5> Value = val; 32} 33def InstFormatPseudo : InstFormat<0>; 34def InstFormatR : InstFormat<1>; 35def InstFormatR4 : InstFormat<2>; 36def InstFormatI : InstFormat<3>; 37def InstFormatS : InstFormat<4>; 38def InstFormatB : InstFormat<5>; 39def InstFormatU : InstFormat<6>; 40def InstFormatJ : InstFormat<7>; 41def InstFormatCR : InstFormat<8>; 42def InstFormatCI : InstFormat<9>; 43def InstFormatCSS : InstFormat<10>; 44def InstFormatCIW : InstFormat<11>; 45def InstFormatCL : InstFormat<12>; 46def InstFormatCS : InstFormat<13>; 47def InstFormatCA : InstFormat<14>; 48def InstFormatCB : InstFormat<15>; 49def InstFormatCJ : InstFormat<16>; 50def InstFormatOther : InstFormat<17>; 51 52class RISCVVConstraint<bits<4> val> { 53 bits<4> Value = val; 54} 55def NoConstraint : RISCVVConstraint<0>; 56def WidenV : RISCVVConstraint<1>; 57def WidenW : RISCVVConstraint<2>; 58def WidenCvt : RISCVVConstraint<3>; 59def Narrow : RISCVVConstraint<4>; 60def Iota : RISCVVConstraint<5>; 61def SlideUp : RISCVVConstraint<6>; 62def Vrgather : RISCVVConstraint<7>; 63def Vcompress : RISCVVConstraint<8>; 64 65// The following opcode names match those given in Table 19.1 in the 66// RISC-V User-level ISA specification ("RISC-V base opcode map"). 67class RISCVOpcode<bits<7> val> { 68 bits<7> Value = val; 69} 70def OPC_LOAD : RISCVOpcode<0b0000011>; 71def OPC_LOAD_FP : RISCVOpcode<0b0000111>; 72def OPC_MISC_MEM : RISCVOpcode<0b0001111>; 73def OPC_OP_IMM : RISCVOpcode<0b0010011>; 74def OPC_AUIPC : RISCVOpcode<0b0010111>; 75def OPC_OP_IMM_32 : RISCVOpcode<0b0011011>; 76def OPC_STORE : RISCVOpcode<0b0100011>; 77def OPC_STORE_FP : RISCVOpcode<0b0100111>; 78def OPC_AMO : RISCVOpcode<0b0101111>; 79def OPC_OP : RISCVOpcode<0b0110011>; 80def OPC_LUI : RISCVOpcode<0b0110111>; 81def OPC_OP_32 : RISCVOpcode<0b0111011>; 82def OPC_MADD : RISCVOpcode<0b1000011>; 83def OPC_MSUB : RISCVOpcode<0b1000111>; 84def OPC_NMSUB : RISCVOpcode<0b1001011>; 85def OPC_NMADD : RISCVOpcode<0b1001111>; 86def OPC_OP_FP : RISCVOpcode<0b1010011>; 87def OPC_OP_V : RISCVOpcode<0b1010111>; 88def OPC_BRANCH : RISCVOpcode<0b1100011>; 89def OPC_JALR : RISCVOpcode<0b1100111>; 90def OPC_JAL : RISCVOpcode<0b1101111>; 91def OPC_SYSTEM : RISCVOpcode<0b1110011>; 92 93class RVInst<dag outs, dag ins, string opcodestr, string argstr, 94 list<dag> pattern, InstFormat format> 95 : Instruction { 96 field bits<32> Inst; 97 // SoftFail is a field the disassembler can use to provide a way for 98 // instructions to not match without killing the whole decode process. It is 99 // mainly used for ARM, but Tablegen expects this field to exist or it fails 100 // to build the decode table. 101 field bits<32> SoftFail = 0; 102 let Size = 4; 103 104 bits<7> Opcode = 0; 105 106 let Inst{6-0} = Opcode; 107 108 let Namespace = "RISCV"; 109 110 dag OutOperandList = outs; 111 dag InOperandList = ins; 112 let AsmString = opcodestr # "\t" # argstr; 113 let Pattern = pattern; 114 115 let TSFlags{4-0} = format.Value; 116 117 // Defaults 118 RISCVVConstraint RVVConstraint = NoConstraint; 119 let TSFlags{8-5} = RVVConstraint.Value; 120} 121 122// Pseudo instructions 123class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = ""> 124 : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo>, 125 Sched<[]> { 126 let isPseudo = 1; 127 let isCodeGenOnly = 1; 128} 129 130// Pseudo load instructions. 131class PseudoLoad<string opcodestr, RegisterClass rdty = GPR> 132 : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> { 133 let hasSideEffects = 0; 134 let mayLoad = 1; 135 let mayStore = 0; 136 let isCodeGenOnly = 0; 137 let isAsmParserOnly = 1; 138} 139 140class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR> 141 : Pseudo<(outs rdty:$rd, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> { 142 let hasSideEffects = 0; 143 let mayLoad = 1; 144 let mayStore = 0; 145 let isCodeGenOnly = 0; 146 let isAsmParserOnly = 1; 147} 148 149// Pseudo store instructions. 150class PseudoStore<string opcodestr, RegisterClass rsty = GPR> 151 : Pseudo<(outs rsty:$rs, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> { 152 let hasSideEffects = 0; 153 let mayLoad = 0; 154 let mayStore = 1; 155 let isCodeGenOnly = 0; 156 let isAsmParserOnly = 1; 157} 158 159// Instruction formats are listed in the order they appear in the RISC-V 160// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, 161// RVInstRAtomic) sorted alphabetically. 162 163class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, 164 dag ins, string opcodestr, string argstr> 165 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 166 bits<5> rs2; 167 bits<5> rs1; 168 bits<5> rd; 169 170 let Inst{31-25} = funct7; 171 let Inst{24-20} = rs2; 172 let Inst{19-15} = rs1; 173 let Inst{14-12} = funct3; 174 let Inst{11-7} = rd; 175 let Opcode = opcode.Value; 176} 177 178class RVInstR4<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins, 179 string opcodestr, string argstr> 180 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 181 bits<5> rs3; 182 bits<5> rs2; 183 bits<5> rs1; 184 bits<3> funct3; 185 bits<5> rd; 186 187 let Inst{31-27} = rs3; 188 let Inst{26-25} = funct2; 189 let Inst{24-20} = rs2; 190 let Inst{19-15} = rs1; 191 let Inst{14-12} = funct3; 192 let Inst{11-7} = rd; 193 let Opcode = opcode.Value; 194} 195 196class RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3, 197 RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 198 string argstr> 199 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 200 bits<5> rs2; 201 bits<5> rs1; 202 bits<5> rd; 203 204 let Inst{31-27} = funct5; 205 let Inst{26} = aq; 206 let Inst{25} = rl; 207 let Inst{24-20} = rs2; 208 let Inst{19-15} = rs1; 209 let Inst{14-12} = funct3; 210 let Inst{11-7} = rd; 211 let Opcode = opcode.Value; 212} 213 214class RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins, 215 string opcodestr, string argstr> 216 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 217 bits<5> rs2; 218 bits<5> rs1; 219 bits<3> funct3; 220 bits<5> rd; 221 222 let Inst{31-25} = funct7; 223 let Inst{24-20} = rs2; 224 let Inst{19-15} = rs1; 225 let Inst{14-12} = funct3; 226 let Inst{11-7} = rd; 227 let Opcode = opcode.Value; 228} 229 230class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 231 string opcodestr, string argstr> 232 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 233 bits<12> imm12; 234 bits<5> rs1; 235 bits<5> rd; 236 237 let Inst{31-20} = imm12; 238 let Inst{19-15} = rs1; 239 let Inst{14-12} = funct3; 240 let Inst{11-7} = rd; 241 let Opcode = opcode.Value; 242} 243 244class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 245 dag outs, dag ins, string opcodestr, string argstr> 246 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 247 bits<6> shamt; 248 bits<5> rs1; 249 bits<5> rd; 250 251 let Inst{31} = 0; 252 let Inst{30} = arithshift; 253 let Inst{29-26} = 0; 254 let Inst{25-20} = shamt; 255 let Inst{19-15} = rs1; 256 let Inst{14-12} = funct3; 257 let Inst{11-7} = rd; 258 let Opcode = opcode.Value; 259} 260 261class RVInstIShiftW<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 262 dag outs, dag ins, string opcodestr, string argstr> 263 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 264 bits<5> shamt; 265 bits<5> rs1; 266 bits<5> rd; 267 268 let Inst{31} = 0; 269 let Inst{30} = arithshift; 270 let Inst{29-25} = 0; 271 let Inst{24-20} = shamt; 272 let Inst{19-15} = rs1; 273 let Inst{14-12} = funct3; 274 let Inst{11-7} = rd; 275 let Opcode = opcode.Value; 276} 277 278class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 279 string opcodestr, string argstr> 280 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { 281 bits<12> imm12; 282 bits<5> rs2; 283 bits<5> rs1; 284 285 let Inst{31-25} = imm12{11-5}; 286 let Inst{24-20} = rs2; 287 let Inst{19-15} = rs1; 288 let Inst{14-12} = funct3; 289 let Inst{11-7} = imm12{4-0}; 290 let Opcode = opcode.Value; 291} 292 293class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 294 string opcodestr, string argstr> 295 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { 296 bits<12> imm12; 297 bits<5> rs2; 298 bits<5> rs1; 299 300 let Inst{31} = imm12{11}; 301 let Inst{30-25} = imm12{9-4}; 302 let Inst{24-20} = rs2; 303 let Inst{19-15} = rs1; 304 let Inst{14-12} = funct3; 305 let Inst{11-8} = imm12{3-0}; 306 let Inst{7} = imm12{10}; 307 let Opcode = opcode.Value; 308} 309 310class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 311 string argstr> 312 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { 313 bits<20> imm20; 314 bits<5> rd; 315 316 let Inst{31-12} = imm20; 317 let Inst{11-7} = rd; 318 let Opcode = opcode.Value; 319} 320 321class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 322 string argstr> 323 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { 324 bits<20> imm20; 325 bits<5> rd; 326 327 let Inst{31} = imm20{19}; 328 let Inst{30-21} = imm20{9-0}; 329 let Inst{20} = imm20{10}; 330 let Inst{19-12} = imm20{18-11}; 331 let Inst{11-7} = rd; 332 let Opcode = opcode.Value; 333} 334