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 Sched<[]> { 108 let isPseudo = 1; 109 let isCodeGenOnly = 1; 110} 111 112// Pseudo load instructions. 113class PseudoLoad<string opcodestr, RegisterClass rdty = GPR> 114 : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> { 115 let hasSideEffects = 0; 116 let mayLoad = 1; 117 let mayStore = 0; 118 let isCodeGenOnly = 0; 119 let isAsmParserOnly = 1; 120} 121 122class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR> 123 : Pseudo<(outs rdty:$rd, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> { 124 let hasSideEffects = 0; 125 let mayLoad = 1; 126 let mayStore = 0; 127 let isCodeGenOnly = 0; 128 let isAsmParserOnly = 1; 129} 130 131// Pseudo store instructions. 132class PseudoStore<string opcodestr, RegisterClass rsty = GPR> 133 : Pseudo<(outs rsty:$rs, GPR:$tmp), (ins bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> { 134 let hasSideEffects = 0; 135 let mayLoad = 0; 136 let mayStore = 1; 137 let isCodeGenOnly = 0; 138 let isAsmParserOnly = 1; 139} 140 141// Instruction formats are listed in the order they appear in the RISC-V 142// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, 143// RVInstRAtomic) sorted alphabetically. 144 145class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, 146 dag ins, string opcodestr, string argstr> 147 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 148 bits<5> rs2; 149 bits<5> rs1; 150 bits<5> rd; 151 152 let Inst{31-25} = funct7; 153 let Inst{24-20} = rs2; 154 let Inst{19-15} = rs1; 155 let Inst{14-12} = funct3; 156 let Inst{11-7} = rd; 157 let Opcode = opcode.Value; 158} 159 160class RVInstR4<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins, 161 string opcodestr, string argstr> 162 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 163 bits<5> rs3; 164 bits<5> rs2; 165 bits<5> rs1; 166 bits<3> funct3; 167 bits<5> rd; 168 169 let Inst{31-27} = rs3; 170 let Inst{26-25} = funct2; 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 RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3, 179 RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 180 string argstr> 181 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 182 bits<5> rs2; 183 bits<5> rs1; 184 bits<5> rd; 185 186 let Inst{31-27} = funct5; 187 let Inst{26} = aq; 188 let Inst{25} = rl; 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 RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins, 197 string opcodestr, string argstr> 198 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 199 bits<5> rs2; 200 bits<5> rs1; 201 bits<3> funct3; 202 bits<5> rd; 203 204 let Inst{31-25} = funct7; 205 let Inst{24-20} = rs2; 206 let Inst{19-15} = rs1; 207 let Inst{14-12} = funct3; 208 let Inst{11-7} = rd; 209 let Opcode = opcode.Value; 210} 211 212class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 213 string opcodestr, string argstr> 214 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 215 bits<12> imm12; 216 bits<5> rs1; 217 bits<5> rd; 218 219 let Inst{31-20} = imm12; 220 let Inst{19-15} = rs1; 221 let Inst{14-12} = funct3; 222 let Inst{11-7} = rd; 223 let Opcode = opcode.Value; 224} 225 226class RVInstIShift<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 227 dag outs, dag ins, string opcodestr, string argstr> 228 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 229 bits<6> shamt; 230 bits<5> rs1; 231 bits<5> rd; 232 233 let Inst{31} = 0; 234 let Inst{30} = arithshift; 235 let Inst{29-26} = 0; 236 let Inst{25-20} = shamt; 237 let Inst{19-15} = rs1; 238 let Inst{14-12} = funct3; 239 let Inst{11-7} = rd; 240 let Opcode = opcode.Value; 241} 242 243class RVInstIShiftW<bit arithshift, bits<3> funct3, RISCVOpcode opcode, 244 dag outs, dag ins, string opcodestr, string argstr> 245 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 246 bits<5> shamt; 247 bits<5> rs1; 248 bits<5> rd; 249 250 let Inst{31} = 0; 251 let Inst{30} = arithshift; 252 let Inst{29-25} = 0; 253 let Inst{24-20} = shamt; 254 let Inst{19-15} = rs1; 255 let Inst{14-12} = funct3; 256 let Inst{11-7} = rd; 257 let Opcode = opcode.Value; 258} 259 260class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 261 string opcodestr, string argstr> 262 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { 263 bits<12> imm12; 264 bits<5> rs2; 265 bits<5> rs1; 266 267 let Inst{31-25} = imm12{11-5}; 268 let Inst{24-20} = rs2; 269 let Inst{19-15} = rs1; 270 let Inst{14-12} = funct3; 271 let Inst{11-7} = imm12{4-0}; 272 let Opcode = opcode.Value; 273} 274 275class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 276 string opcodestr, string argstr> 277 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { 278 bits<12> imm12; 279 bits<5> rs2; 280 bits<5> rs1; 281 282 let Inst{31} = imm12{11}; 283 let Inst{30-25} = imm12{9-4}; 284 let Inst{24-20} = rs2; 285 let Inst{19-15} = rs1; 286 let Inst{14-12} = funct3; 287 let Inst{11-8} = imm12{3-0}; 288 let Inst{7} = imm12{10}; 289 let Opcode = opcode.Value; 290} 291 292class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 293 string argstr> 294 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { 295 bits<20> imm20; 296 bits<5> rd; 297 298 let Inst{31-12} = imm20; 299 let Inst{11-7} = rd; 300 let Opcode = opcode.Value; 301} 302 303class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 304 string argstr> 305 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { 306 bits<20> imm20; 307 bits<5> rd; 308 309 let Inst{31} = imm20{19}; 310 let Inst{30-21} = imm20{9-0}; 311 let Inst{20} = imm20{10}; 312 let Inst{19-12} = imm20{18-11}; 313 let Inst{11-7} = rd; 314 let Opcode = opcode.Value; 315} 316