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<3> val> { 53 bits<3> Value = val; 54} 55def NoConstraint : RISCVVConstraint<0b000>; 56def VS2Constraint : RISCVVConstraint<0b001>; 57def VS1Constraint : RISCVVConstraint<0b010>; 58def VMConstraint : RISCVVConstraint<0b100>; 59 60// Illegal instructions: 61// 62// * The destination vector register group for a masked vector instruction 63// cannot overlap the source mask register (v0), unless the destination vector 64// register is being written with a mask value (e.g., comparisons) or the 65// scalar result of a reduction. 66// 67// * Widening: The destination EEW is greater than the source EEW, the source 68// EMUL is at least 1. The destination vector register group cannot overlap 69// with the source vector register groups besides the highest-numbered part of 70// the destination register group. 71// 72// * Narrowing: The destination EEW is smaller than the source EEW. The 73// destination vector register group cannot overlap with the source vector 74// register groups besides the lowest-numbered part of the source register 75// group. 76// 77// * vmsbf.m/vmsif.m/vmsof.m: The destination register cannot overlap the 78// source register and, if masked, cannot overlap the mask register ('v0'). 79// 80// * viota: The destination register cannot overlap the source register and, 81// if masked, cannot overlap the mask register ('v0'). 82// 83// * v[f]slide[1]up: The destination vector register group for vslideup cannot 84// overlap the source vector register group. 85// 86// * vrgather: The destination vector register group cannot overlap with the 87// source vector register groups. 88// 89// * vcompress: The destination vector register group cannot overlap the 90// source vector register group or the source mask register 91def WidenV : RISCVVConstraint<!or(VS2Constraint.Value, 92 VS1Constraint.Value, 93 VMConstraint.Value)>; 94def WidenW : RISCVVConstraint<!or(VS1Constraint.Value, 95 VMConstraint.Value)>; 96def WidenCvt : RISCVVConstraint<!or(VS2Constraint.Value, 97 VMConstraint.Value)>; 98def Iota : RISCVVConstraint<!or(VS2Constraint.Value, 99 VMConstraint.Value)>; 100def SlideUp : RISCVVConstraint<!or(VS2Constraint.Value, 101 VMConstraint.Value)>; 102def Vrgather : RISCVVConstraint<!or(VS2Constraint.Value, 103 VS1Constraint.Value, 104 VMConstraint.Value)>; 105def Vcompress : RISCVVConstraint<!or(VS2Constraint.Value, 106 VS1Constraint.Value)>; 107 108// The following opcode names match those given in Table 19.1 in the 109// RISC-V User-level ISA specification ("RISC-V base opcode map"). 110class RISCVOpcode<bits<7> val> { 111 bits<7> Value = val; 112} 113def OPC_LOAD : RISCVOpcode<0b0000011>; 114def OPC_LOAD_FP : RISCVOpcode<0b0000111>; 115def OPC_MISC_MEM : RISCVOpcode<0b0001111>; 116def OPC_OP_IMM : RISCVOpcode<0b0010011>; 117def OPC_AUIPC : RISCVOpcode<0b0010111>; 118def OPC_OP_IMM_32 : RISCVOpcode<0b0011011>; 119def OPC_STORE : RISCVOpcode<0b0100011>; 120def OPC_STORE_FP : RISCVOpcode<0b0100111>; 121def OPC_AMO : RISCVOpcode<0b0101111>; 122def OPC_OP : RISCVOpcode<0b0110011>; 123def OPC_LUI : RISCVOpcode<0b0110111>; 124def OPC_OP_32 : RISCVOpcode<0b0111011>; 125def OPC_MADD : RISCVOpcode<0b1000011>; 126def OPC_MSUB : RISCVOpcode<0b1000111>; 127def OPC_NMSUB : RISCVOpcode<0b1001011>; 128def OPC_NMADD : RISCVOpcode<0b1001111>; 129def OPC_OP_FP : RISCVOpcode<0b1010011>; 130def OPC_OP_V : RISCVOpcode<0b1010111>; 131def OPC_BRANCH : RISCVOpcode<0b1100011>; 132def OPC_JALR : RISCVOpcode<0b1100111>; 133def OPC_JAL : RISCVOpcode<0b1101111>; 134def OPC_SYSTEM : RISCVOpcode<0b1110011>; 135 136class RVInst<dag outs, dag ins, string opcodestr, string argstr, 137 list<dag> pattern, InstFormat format> 138 : Instruction { 139 field bits<32> Inst; 140 // SoftFail is a field the disassembler can use to provide a way for 141 // instructions to not match without killing the whole decode process. It is 142 // mainly used for ARM, but Tablegen expects this field to exist or it fails 143 // to build the decode table. 144 field bits<32> SoftFail = 0; 145 let Size = 4; 146 147 bits<7> Opcode = 0; 148 149 let Inst{6-0} = Opcode; 150 151 let Namespace = "RISCV"; 152 153 dag OutOperandList = outs; 154 dag InOperandList = ins; 155 let AsmString = opcodestr # "\t" # argstr; 156 let Pattern = pattern; 157 158 let TSFlags{4-0} = format.Value; 159 160 // Defaults 161 RISCVVConstraint RVVConstraint = NoConstraint; 162 let TSFlags{7-5} = RVVConstraint.Value; 163 164 bits<3> VLMul = 0; 165 let TSFlags{10-8} = VLMul; 166 167 bit HasDummyMask = 0; 168 let TSFlags{11} = HasDummyMask; 169 170 bit ForceTailAgnostic = false; 171 let TSFlags{12} = ForceTailAgnostic; 172 173 bit HasMergeOp = 0; 174 let TSFlags{13} = HasMergeOp; 175 176 bit HasSEWOp = 0; 177 let TSFlags{14} = HasSEWOp; 178 179 bit HasVLOp = 0; 180 let TSFlags{15} = HasVLOp; 181 182 bit HasVecPolicyOp = 0; 183 let TSFlags{16} = HasVecPolicyOp; 184 185 bit IsRVVWideningReduction = 0; 186 let TSFlags{17} = IsRVVWideningReduction; 187} 188 189// Pseudo instructions 190class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = ""> 191 : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo>, 192 Sched<[]> { 193 let isPseudo = 1; 194 let isCodeGenOnly = 1; 195} 196 197// Pseudo load instructions. 198class PseudoLoad<string opcodestr, RegisterClass rdty = GPR> 199 : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> { 200 let hasSideEffects = 0; 201 let mayLoad = 1; 202 let mayStore = 0; 203 let isCodeGenOnly = 0; 204 let isAsmParserOnly = 1; 205} 206 207class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR> 208 : Pseudo<(outs GPR:$tmp, rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> { 209 let hasSideEffects = 0; 210 let mayLoad = 1; 211 let mayStore = 0; 212 let isCodeGenOnly = 0; 213 let isAsmParserOnly = 1; 214} 215 216// Pseudo store instructions. 217class PseudoStore<string opcodestr, RegisterClass rsty = GPR> 218 : Pseudo<(outs GPR:$tmp), (ins rsty:$rs, bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> { 219 let hasSideEffects = 0; 220 let mayLoad = 0; 221 let mayStore = 1; 222 let isCodeGenOnly = 0; 223 let isAsmParserOnly = 1; 224} 225 226// Instruction formats are listed in the order they appear in the RISC-V 227// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, 228// RVInstRAtomic) sorted alphabetically. 229 230class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, 231 dag ins, string opcodestr, string argstr> 232 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 233 bits<5> rs2; 234 bits<5> rs1; 235 bits<5> rd; 236 237 let Inst{31-25} = funct7; 238 let Inst{24-20} = rs2; 239 let Inst{19-15} = rs1; 240 let Inst{14-12} = funct3; 241 let Inst{11-7} = rd; 242 let Opcode = opcode.Value; 243} 244 245class RVInstR4<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode, dag outs, 246 dag ins, string opcodestr, string argstr> 247 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 248 bits<5> rs3; 249 bits<5> rs2; 250 bits<5> rs1; 251 bits<5> rd; 252 253 let Inst{31-27} = rs3; 254 let Inst{26-25} = funct2; 255 let Inst{24-20} = rs2; 256 let Inst{19-15} = rs1; 257 let Inst{14-12} = funct3; 258 let Inst{11-7} = rd; 259 let Opcode = opcode.Value; 260} 261 262class RVInstR4Frm<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins, 263 string opcodestr, string argstr> 264 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 265 bits<5> rs3; 266 bits<5> rs2; 267 bits<5> rs1; 268 bits<3> funct3; 269 bits<5> rd; 270 271 let Inst{31-27} = rs3; 272 let Inst{26-25} = funct2; 273 let Inst{24-20} = rs2; 274 let Inst{19-15} = rs1; 275 let Inst{14-12} = funct3; 276 let Inst{11-7} = rd; 277 let Opcode = opcode.Value; 278} 279 280class RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3, 281 RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 282 string argstr> 283 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 284 bits<5> rs2; 285 bits<5> rs1; 286 bits<5> rd; 287 288 let Inst{31-27} = funct5; 289 let Inst{26} = aq; 290 let Inst{25} = rl; 291 let Inst{24-20} = rs2; 292 let Inst{19-15} = rs1; 293 let Inst{14-12} = funct3; 294 let Inst{11-7} = rd; 295 let Opcode = opcode.Value; 296} 297 298class RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins, 299 string opcodestr, string argstr> 300 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 301 bits<5> rs2; 302 bits<5> rs1; 303 bits<3> funct3; 304 bits<5> rd; 305 306 let Inst{31-25} = funct7; 307 let Inst{24-20} = rs2; 308 let Inst{19-15} = rs1; 309 let Inst{14-12} = funct3; 310 let Inst{11-7} = rd; 311 let Opcode = opcode.Value; 312} 313 314class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 315 string opcodestr, string argstr> 316 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 317 bits<12> imm12; 318 bits<5> rs1; 319 bits<5> rd; 320 321 let Inst{31-20} = imm12; 322 let Inst{19-15} = rs1; 323 let Inst{14-12} = funct3; 324 let Inst{11-7} = rd; 325 let Opcode = opcode.Value; 326} 327 328class RVInstIShift<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode, 329 dag outs, dag ins, string opcodestr, string argstr> 330 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 331 bits<6> shamt; 332 bits<5> rs1; 333 bits<5> rd; 334 335 let Inst{31-27} = imm11_7; 336 let Inst{26} = 0; 337 let Inst{25-20} = shamt; 338 let Inst{19-15} = rs1; 339 let Inst{14-12} = funct3; 340 let Inst{11-7} = rd; 341 let Opcode = opcode.Value; 342} 343 344class RVInstIShiftW<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode, 345 dag outs, dag ins, string opcodestr, string argstr> 346 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 347 bits<5> shamt; 348 bits<5> rs1; 349 bits<5> rd; 350 351 let Inst{31-25} = imm11_5; 352 let Inst{24-20} = shamt; 353 let Inst{19-15} = rs1; 354 let Inst{14-12} = funct3; 355 let Inst{11-7} = rd; 356 let Opcode = opcode.Value; 357} 358 359class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 360 string opcodestr, string argstr> 361 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { 362 bits<12> imm12; 363 bits<5> rs2; 364 bits<5> rs1; 365 366 let Inst{31-25} = imm12{11-5}; 367 let Inst{24-20} = rs2; 368 let Inst{19-15} = rs1; 369 let Inst{14-12} = funct3; 370 let Inst{11-7} = imm12{4-0}; 371 let Opcode = opcode.Value; 372} 373 374class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 375 string opcodestr, string argstr> 376 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { 377 bits<12> imm12; 378 bits<5> rs2; 379 bits<5> rs1; 380 381 let Inst{31} = imm12{11}; 382 let Inst{30-25} = imm12{9-4}; 383 let Inst{24-20} = rs2; 384 let Inst{19-15} = rs1; 385 let Inst{14-12} = funct3; 386 let Inst{11-8} = imm12{3-0}; 387 let Inst{7} = imm12{10}; 388 let Opcode = opcode.Value; 389} 390 391class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 392 string argstr> 393 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { 394 bits<20> imm20; 395 bits<5> rd; 396 397 let Inst{31-12} = imm20; 398 let Inst{11-7} = rd; 399 let Opcode = opcode.Value; 400} 401 402class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 403 string argstr> 404 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { 405 bits<20> imm20; 406 bits<5> rd; 407 408 let Inst{31} = imm20{19}; 409 let Inst{30-21} = imm20{9-0}; 410 let Inst{20} = imm20{10}; 411 let Inst{19-12} = imm20{18-11}; 412 let Inst{11-7} = rd; 413 let Opcode = opcode.Value; 414} 415 416//===----------------------------------------------------------------------===// 417// Instruction classes for .insn directives 418//===----------------------------------------------------------------------===// 419 420class DirectiveInsnR<dag outs, dag ins, string argstr> 421 : RVInst<outs, ins, "", "", [], InstFormatR> { 422 bits<7> opcode; 423 bits<7> funct7; 424 bits<3> funct3; 425 426 bits<5> rs2; 427 bits<5> rs1; 428 bits<5> rd; 429 430 let Inst{31-25} = funct7; 431 let Inst{24-20} = rs2; 432 let Inst{19-15} = rs1; 433 let Inst{14-12} = funct3; 434 let Inst{11-7} = rd; 435 let Opcode = opcode; 436 437 let AsmString = ".insn r " # argstr; 438} 439 440class DirectiveInsnR4<dag outs, dag ins, string argstr> 441 : RVInst<outs, ins, "", "", [], InstFormatR4> { 442 bits<7> opcode; 443 bits<2> funct2; 444 bits<3> funct3; 445 446 bits<5> rs3; 447 bits<5> rs2; 448 bits<5> rs1; 449 bits<5> rd; 450 451 let Inst{31-27} = rs3; 452 let Inst{26-25} = funct2; 453 let Inst{24-20} = rs2; 454 let Inst{19-15} = rs1; 455 let Inst{14-12} = funct3; 456 let Inst{11-7} = rd; 457 let Opcode = opcode; 458 459 let AsmString = ".insn r4 " # argstr; 460} 461 462class DirectiveInsnI<dag outs, dag ins, string argstr> 463 : RVInst<outs, ins, "", "", [], InstFormatI> { 464 bits<7> opcode; 465 bits<3> funct3; 466 467 bits<12> imm12; 468 bits<5> rs1; 469 bits<5> rd; 470 471 let Inst{31-20} = imm12; 472 let Inst{19-15} = rs1; 473 let Inst{14-12} = funct3; 474 let Inst{11-7} = rd; 475 let Opcode = opcode; 476 477 let AsmString = ".insn i " # argstr; 478} 479 480class DirectiveInsnS<dag outs, dag ins, string argstr> 481 : RVInst<outs, ins, "", "", [], InstFormatS> { 482 bits<7> opcode; 483 bits<3> funct3; 484 485 bits<12> imm12; 486 bits<5> rs2; 487 bits<5> rs1; 488 489 let Inst{31-25} = imm12{11-5}; 490 let Inst{24-20} = rs2; 491 let Inst{19-15} = rs1; 492 let Inst{14-12} = funct3; 493 let Inst{11-7} = imm12{4-0}; 494 let Opcode = opcode; 495 496 let AsmString = ".insn s " # argstr; 497} 498 499class DirectiveInsnB<dag outs, dag ins, string argstr> 500 : RVInst<outs, ins, "", "", [], InstFormatB> { 501 bits<7> opcode; 502 bits<3> funct3; 503 504 bits<12> imm12; 505 bits<5> rs2; 506 bits<5> rs1; 507 508 let Inst{31} = imm12{11}; 509 let Inst{30-25} = imm12{9-4}; 510 let Inst{24-20} = rs2; 511 let Inst{19-15} = rs1; 512 let Inst{14-12} = funct3; 513 let Inst{11-8} = imm12{3-0}; 514 let Inst{7} = imm12{10}; 515 let Opcode = opcode; 516 517 let AsmString = ".insn b " # argstr; 518} 519 520class DirectiveInsnU<dag outs, dag ins, string argstr> 521 : RVInst<outs, ins, "", "", [], InstFormatU> { 522 bits<7> opcode; 523 524 bits<20> imm20; 525 bits<5> rd; 526 527 let Inst{31-12} = imm20; 528 let Inst{11-7} = rd; 529 let Opcode = opcode; 530 531 let AsmString = ".insn u " # argstr; 532} 533 534class DirectiveInsnJ<dag outs, dag ins, string argstr> 535 : RVInst<outs, ins, "", "", [], InstFormatJ> { 536 bits<7> opcode; 537 538 bits<20> imm20; 539 bits<5> rd; 540 541 let Inst{31-12} = imm20; 542 let Inst{11-7} = rd; 543 let Opcode = opcode; 544 545 let AsmString = ".insn j " # argstr; 546} 547