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 52// The following opcode names match those given in Table 19.1 in the 53// RISC-V User-level ISA specification ("RISC-V base opcode map"). 54class RISCVOpcode<bits<7> val> { 55 bits<7> Value = val; 56} 57def OPC_LOAD : RISCVOpcode<0b0000011>; 58def OPC_LOAD_FP : RISCVOpcode<0b0000111>; 59def OPC_MISC_MEM : RISCVOpcode<0b0001111>; 60def OPC_OP_IMM : RISCVOpcode<0b0010011>; 61def OPC_AUIPC : RISCVOpcode<0b0010111>; 62def OPC_OP_IMM_32 : RISCVOpcode<0b0011011>; 63def OPC_STORE : RISCVOpcode<0b0100011>; 64def OPC_STORE_FP : RISCVOpcode<0b0100111>; 65def OPC_AMO : RISCVOpcode<0b0101111>; 66def OPC_OP : RISCVOpcode<0b0110011>; 67def OPC_LUI : RISCVOpcode<0b0110111>; 68def OPC_OP_32 : RISCVOpcode<0b0111011>; 69def OPC_MADD : RISCVOpcode<0b1000011>; 70def OPC_MSUB : RISCVOpcode<0b1000111>; 71def OPC_NMSUB : RISCVOpcode<0b1001011>; 72def OPC_NMADD : RISCVOpcode<0b1001111>; 73def OPC_OP_FP : RISCVOpcode<0b1010011>; 74def OPC_BRANCH : RISCVOpcode<0b1100011>; 75def OPC_JALR : RISCVOpcode<0b1100111>; 76def OPC_JAL : RISCVOpcode<0b1101111>; 77def OPC_SYSTEM : RISCVOpcode<0b1110011>; 78 79class RVInst<dag outs, dag ins, string opcodestr, string argstr, 80 list<dag> pattern, InstFormat format> 81 : Instruction { 82 field bits<32> Inst; 83 // SoftFail is a field the disassembler can use to provide a way for 84 // instructions to not match without killing the whole decode process. It is 85 // mainly used for ARM, but Tablegen expects this field to exist or it fails 86 // to build the decode table. 87 field bits<32> SoftFail = 0; 88 let Size = 4; 89 90 bits<7> Opcode = 0; 91 92 let Inst{6-0} = Opcode; 93 94 let Namespace = "RISCV"; 95 96 dag OutOperandList = outs; 97 dag InOperandList = ins; 98 let AsmString = opcodestr # "\t" # argstr; 99 let Pattern = pattern; 100 101 let TSFlags{4-0} = format.Value; 102} 103 104// Pseudo instructions 105class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = ""> 106 : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo> { 107 let isPseudo = 1; 108 let isCodeGenOnly = 1; 109} 110 111// Pseudo load instructions. 112class PseudoLoad<string opcodestr, RegisterClass rdty = GPR> 113 : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> { 114 let hasSideEffects = 0; 115 let mayLoad = 1; 116 let mayStore = 0; 117 let isCodeGenOnly = 0; 118 let isAsmParserOnly = 1; 119} 120 121class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR> 122 : Pseudo<(outs rdty:$rd, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> { 123 let hasSideEffects = 0; 124 let mayLoad = 1; 125 let mayStore = 0; 126 let isCodeGenOnly = 0; 127 let isAsmParserOnly = 1; 128} 129 130// Pseudo store instructions. 131class PseudoStore<string opcodestr, RegisterClass rsty = GPR> 132 : Pseudo<(outs rsty:$rs, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> { 133 let hasSideEffects = 0; 134 let mayLoad = 0; 135 let mayStore = 1; 136 let isCodeGenOnly = 0; 137 let isAsmParserOnly = 1; 138} 139 140// Instruction formats are listed in the order they appear in the RISC-V 141// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, 142// RVInstRAtomic) sorted alphabetically. 143 144class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, 145 dag ins, string opcodestr, string argstr> 146 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 147 bits<5> rs2; 148 bits<5> rs1; 149 bits<5> rd; 150 151 let Inst{31-25} = funct7; 152 let Inst{24-20} = rs2; 153 let Inst{19-15} = rs1; 154 let Inst{14-12} = funct3; 155 let Inst{11-7} = rd; 156 let Opcode = opcode.Value; 157} 158 159class RVInstR4<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins, 160 string opcodestr, string argstr> 161 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 162 bits<5> rs3; 163 bits<5> rs2; 164 bits<5> rs1; 165 bits<3> funct3; 166 bits<5> rd; 167 168 let Inst{31-27} = rs3; 169 let Inst{26-25} = funct2; 170 let Inst{24-20} = rs2; 171 let Inst{19-15} = rs1; 172 let Inst{14-12} = funct3; 173 let Inst{11-7} = rd; 174 let Opcode = opcode.Value; 175} 176 177class RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3, 178 RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 179 string argstr> 180 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 181 bits<5> rs2; 182 bits<5> rs1; 183 bits<5> rd; 184 185 let Inst{31-27} = funct5; 186 let Inst{26} = aq; 187 let Inst{25} = rl; 188 let Inst{24-20} = rs2; 189 let Inst{19-15} = rs1; 190 let Inst{14-12} = funct3; 191 let Inst{11-7} = rd; 192 let Opcode = opcode.Value; 193} 194 195class RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins, 196 string opcodestr, string argstr> 197 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 198 bits<5> rs2; 199 bits<5> rs1; 200 bits<3> funct3; 201 bits<5> rd; 202 203 let Inst{31-25} = funct7; 204 let Inst{24-20} = rs2; 205 let Inst{19-15} = rs1; 206 let Inst{14-12} = funct3; 207 let Inst{11-7} = rd; 208 let Opcode = opcode.Value; 209} 210 211class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 212 string opcodestr, string argstr> 213 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 214 bits<12> imm12; 215 bits<5> rs1; 216 bits<5> rd; 217 218 let Inst{31-20} = imm12; 219 let Inst{19-15} = rs1; 220 let Inst{14-12} = funct3; 221 let Inst{11-7} = rd; 222 let Opcode = opcode.Value; 223} 224 225class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 226 dag outs, dag ins, string opcodestr, string argstr> 227 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 228 bits<6> shamt; 229 bits<5> rs1; 230 bits<5> rd; 231 232 let Inst{31} = 0; 233 let Inst{30} = arithshift; 234 let Inst{29-26} = 0; 235 let Inst{25-20} = shamt; 236 let Inst{19-15} = rs1; 237 let Inst{14-12} = funct3; 238 let Inst{11-7} = rd; 239 let Opcode = opcode.Value; 240} 241 242class RVInstIShiftW<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 243 dag outs, dag ins, string opcodestr, string argstr> 244 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 245 bits<5> shamt; 246 bits<5> rs1; 247 bits<5> rd; 248 249 let Inst{31} = 0; 250 let Inst{30} = arithshift; 251 let Inst{29-25} = 0; 252 let Inst{24-20} = shamt; 253 let Inst{19-15} = rs1; 254 let Inst{14-12} = funct3; 255 let Inst{11-7} = rd; 256 let Opcode = opcode.Value; 257} 258 259class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 260 string opcodestr, string argstr> 261 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { 262 bits<12> imm12; 263 bits<5> rs2; 264 bits<5> rs1; 265 266 let Inst{31-25} = imm12{11-5}; 267 let Inst{24-20} = rs2; 268 let Inst{19-15} = rs1; 269 let Inst{14-12} = funct3; 270 let Inst{11-7} = imm12{4-0}; 271 let Opcode = opcode.Value; 272} 273 274class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 275 string opcodestr, string argstr> 276 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { 277 bits<12> imm12; 278 bits<5> rs2; 279 bits<5> rs1; 280 281 let Inst{31} = imm12{11}; 282 let Inst{30-25} = imm12{9-4}; 283 let Inst{24-20} = rs2; 284 let Inst{19-15} = rs1; 285 let Inst{14-12} = funct3; 286 let Inst{11-8} = imm12{3-0}; 287 let Inst{7} = imm12{10}; 288 let Opcode = opcode.Value; 289} 290 291class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 292 string argstr> 293 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { 294 bits<20> imm20; 295 bits<5> rd; 296 297 let Inst{31-12} = imm20; 298 let Inst{11-7} = rd; 299 let Opcode = opcode.Value; 300} 301 302class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 303 string argstr> 304 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { 305 bits<20> imm20; 306 bits<5> rd; 307 308 let Inst{31} = imm20{19}; 309 let Inst{30-21} = imm20{9-0}; 310 let Inst{20} = imm20{10}; 311 let Inst{19-12} = imm20{18-11}; 312 let Inst{11-7} = rd; 313 let Opcode = opcode.Value; 314} 315