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<string name, bits<7> val> { 111 string Name = name; 112 bits<7> Value = val; 113} 114def RISCVOpcodesList : GenericTable { 115 let FilterClass = "RISCVOpcode"; 116 let Fields = [ 117 "Name", "Value" 118 ]; 119 let PrimaryKey = [ "Value" ]; 120 let PrimaryKeyName = "lookupRISCVOpcodeByValue"; 121} 122def lookupRISCVOpcodeByName : SearchIndex { 123 let Table = RISCVOpcodesList; 124 let Key = [ "Name" ]; 125} 126def OPC_LOAD : RISCVOpcode<"LOAD", 0b0000011>; 127def OPC_LOAD_FP : RISCVOpcode<"LOAD_FP", 0b0000111>; 128def OPC_CUSTOM_0 : RISCVOpcode<"CUSTOM_0", 0b0001011>; 129def OPC_MISC_MEM : RISCVOpcode<"MISC_MEM", 0b0001111>; 130def OPC_OP_IMM : RISCVOpcode<"OP_IMM", 0b0010011>; 131def OPC_AUIPC : RISCVOpcode<"AUIPC", 0b0010111>; 132def OPC_OP_IMM_32 : RISCVOpcode<"OP_IMM_32", 0b0011011>; 133def OPC_STORE : RISCVOpcode<"STORE", 0b0100011>; 134def OPC_STORE_FP : RISCVOpcode<"STORE_FP", 0b0100111>; 135def OPC_CUSTOM_1 : RISCVOpcode<"CUSTOM_1", 0b0101011>; 136def OPC_AMO : RISCVOpcode<"AMO", 0b0101111>; 137def OPC_OP : RISCVOpcode<"OP", 0b0110011>; 138def OPC_LUI : RISCVOpcode<"LUI", 0b0110111>; 139def OPC_OP_32 : RISCVOpcode<"OP_32", 0b0111011>; 140def OPC_MADD : RISCVOpcode<"MADD", 0b1000011>; 141def OPC_MSUB : RISCVOpcode<"MSUB", 0b1000111>; 142def OPC_NMSUB : RISCVOpcode<"NMSUB", 0b1001011>; 143def OPC_NMADD : RISCVOpcode<"NMADD", 0b1001111>; 144def OPC_OP_FP : RISCVOpcode<"OP_FP", 0b1010011>; 145def OPC_OP_V : RISCVOpcode<"OP_V", 0b1010111>; 146def OPC_CUSTOM_2 : RISCVOpcode<"CUSTOM_2", 0b1011011>; 147def OPC_BRANCH : RISCVOpcode<"BRANCH", 0b1100011>; 148def OPC_JALR : RISCVOpcode<"JALR", 0b1100111>; 149def OPC_JAL : RISCVOpcode<"JAL", 0b1101111>; 150def OPC_SYSTEM : RISCVOpcode<"SYSTEM", 0b1110011>; 151def OPC_CUSTOM_3 : RISCVOpcode<"CUSTOM_3", 0b1111011>; 152 153class RVInst<dag outs, dag ins, string opcodestr, string argstr, 154 list<dag> pattern, InstFormat format> 155 : Instruction { 156 field bits<32> Inst; 157 // SoftFail is a field the disassembler can use to provide a way for 158 // instructions to not match without killing the whole decode process. It is 159 // mainly used for ARM, but Tablegen expects this field to exist or it fails 160 // to build the decode table. 161 field bits<32> SoftFail = 0; 162 let Size = 4; 163 164 bits<7> Opcode = 0; 165 166 let Inst{6-0} = Opcode; 167 168 let Namespace = "RISCV"; 169 170 dag OutOperandList = outs; 171 dag InOperandList = ins; 172 let AsmString = opcodestr # "\t" # argstr; 173 let Pattern = pattern; 174 175 let TSFlags{4-0} = format.Value; 176 177 // Defaults 178 RISCVVConstraint RVVConstraint = NoConstraint; 179 let TSFlags{7-5} = RVVConstraint.Value; 180 181 bits<3> VLMul = 0; 182 let TSFlags{10-8} = VLMul; 183 184 bit HasDummyMask = 0; 185 let TSFlags{11} = HasDummyMask; 186 187 bit ForceTailAgnostic = false; 188 let TSFlags{12} = ForceTailAgnostic; 189 190 bit HasMergeOp = 0; 191 let TSFlags{13} = HasMergeOp; 192 193 bit HasSEWOp = 0; 194 let TSFlags{14} = HasSEWOp; 195 196 bit HasVLOp = 0; 197 let TSFlags{15} = HasVLOp; 198 199 bit HasVecPolicyOp = 0; 200 let TSFlags{16} = HasVecPolicyOp; 201 202 bit IsRVVWideningReduction = 0; 203 let TSFlags{17} = IsRVVWideningReduction; 204 205 bit UsesMaskPolicy = 0; 206 let TSFlags{18} = UsesMaskPolicy; 207 208 // Indicates that the result can be considered sign extended from bit 31. Some 209 // instructions with this flag aren't W instructions, but are either sign 210 // extended from a smaller size, always outputs a small integer, or put zeros 211 // in bits 63:31. Used by the SExtWRemoval pass. 212 bit IsSignExtendingOpW = 0; 213 let TSFlags{19} = IsSignExtendingOpW; 214} 215 216// Pseudo instructions 217class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = ""> 218 : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo> { 219 let isPseudo = 1; 220 let isCodeGenOnly = 1; 221} 222 223class PseudoQuietFCMP<RegisterClass Ty> 224 : Pseudo<(outs GPR:$rd), (ins Ty:$rs1, Ty:$rs2), []> { 225 let hasSideEffects = 1; 226 let mayLoad = 0; 227 let mayStore = 0; 228} 229 230// Pseudo load instructions. 231class PseudoLoad<string opcodestr, RegisterClass rdty = GPR> 232 : Pseudo<(outs rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr"> { 233 let hasSideEffects = 0; 234 let mayLoad = 1; 235 let mayStore = 0; 236 let isCodeGenOnly = 0; 237 let isAsmParserOnly = 1; 238} 239 240class PseudoFloatLoad<string opcodestr, RegisterClass rdty = GPR> 241 : Pseudo<(outs GPR:$tmp, rdty:$rd), (ins bare_symbol:$addr), [], opcodestr, "$rd, $addr, $tmp"> { 242 let hasSideEffects = 0; 243 let mayLoad = 1; 244 let mayStore = 0; 245 let isCodeGenOnly = 0; 246 let isAsmParserOnly = 1; 247} 248 249// Pseudo store instructions. 250class PseudoStore<string opcodestr, RegisterClass rsty = GPR> 251 : Pseudo<(outs GPR:$tmp), (ins rsty:$rs, bare_symbol:$addr), [], opcodestr, "$rs, $addr, $tmp"> { 252 let hasSideEffects = 0; 253 let mayLoad = 0; 254 let mayStore = 1; 255 let isCodeGenOnly = 0; 256 let isAsmParserOnly = 1; 257} 258 259// Instruction formats are listed in the order they appear in the RISC-V 260// instruction set manual (R, I, S, B, U, J) with sub-formats (e.g. RVInstR4, 261// RVInstRAtomic) sorted alphabetically. 262 263class RVInstR<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, dag outs, 264 dag ins, string opcodestr, string argstr> 265 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 266 bits<5> rs2; 267 bits<5> rs1; 268 bits<5> rd; 269 270 let Inst{31-25} = funct7; 271 let Inst{24-20} = rs2; 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 RVInstR4<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode, dag outs, 279 dag ins, string opcodestr, string argstr> 280 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 281 bits<5> rs3; 282 bits<5> rs2; 283 bits<5> rs1; 284 bits<5> rd; 285 286 let Inst{31-27} = rs3; 287 let Inst{26-25} = funct2; 288 let Inst{24-20} = rs2; 289 let Inst{19-15} = rs1; 290 let Inst{14-12} = funct3; 291 let Inst{11-7} = rd; 292 let Opcode = opcode.Value; 293} 294 295class RVInstR4Frm<bits<2> funct2, RISCVOpcode opcode, dag outs, dag ins, 296 string opcodestr, string argstr> 297 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR4> { 298 bits<5> rs3; 299 bits<5> rs2; 300 bits<5> rs1; 301 bits<3> frm; 302 bits<5> rd; 303 304 let Inst{31-27} = rs3; 305 let Inst{26-25} = funct2; 306 let Inst{24-20} = rs2; 307 let Inst{19-15} = rs1; 308 let Inst{14-12} = frm; 309 let Inst{11-7} = rd; 310 let Opcode = opcode.Value; 311} 312 313class RVInstRAtomic<bits<5> funct5, bit aq, bit rl, bits<3> funct3, 314 RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 315 string argstr> 316 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 317 bits<5> rs2; 318 bits<5> rs1; 319 bits<5> rd; 320 321 let Inst{31-27} = funct5; 322 let Inst{26} = aq; 323 let Inst{25} = rl; 324 let Inst{24-20} = rs2; 325 let Inst{19-15} = rs1; 326 let Inst{14-12} = funct3; 327 let Inst{11-7} = rd; 328 let Opcode = opcode.Value; 329} 330 331class RVInstRFrm<bits<7> funct7, RISCVOpcode opcode, dag outs, dag ins, 332 string opcodestr, string argstr> 333 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 334 bits<5> rs2; 335 bits<5> rs1; 336 bits<3> frm; 337 bits<5> rd; 338 339 let Inst{31-25} = funct7; 340 let Inst{24-20} = rs2; 341 let Inst{19-15} = rs1; 342 let Inst{14-12} = frm; 343 let Inst{11-7} = rd; 344 let Opcode = opcode.Value; 345} 346 347class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 348 string opcodestr, string argstr> 349 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 350 bits<12> imm12; 351 bits<5> rs1; 352 bits<5> rd; 353 354 let Inst{31-20} = imm12; 355 let Inst{19-15} = rs1; 356 let Inst{14-12} = funct3; 357 let Inst{11-7} = rd; 358 let Opcode = opcode.Value; 359} 360 361class RVInstIShift<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode, 362 dag outs, dag ins, string opcodestr, string argstr> 363 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 364 bits<6> shamt; 365 bits<5> rs1; 366 bits<5> rd; 367 368 let Inst{31-27} = imm11_7; 369 let Inst{26} = 0; 370 let Inst{25-20} = shamt; 371 let Inst{19-15} = rs1; 372 let Inst{14-12} = funct3; 373 let Inst{11-7} = rd; 374 let Opcode = opcode.Value; 375} 376 377class RVInstIShiftW<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode, 378 dag outs, dag ins, string opcodestr, string argstr> 379 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> { 380 bits<5> shamt; 381 bits<5> rs1; 382 bits<5> rd; 383 384 let Inst{31-25} = imm11_5; 385 let Inst{24-20} = shamt; 386 let Inst{19-15} = rs1; 387 let Inst{14-12} = funct3; 388 let Inst{11-7} = rd; 389 let Opcode = opcode.Value; 390} 391 392class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 393 string opcodestr, string argstr> 394 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { 395 bits<12> imm12; 396 bits<5> rs2; 397 bits<5> rs1; 398 399 let Inst{31-25} = imm12{11-5}; 400 let Inst{24-20} = rs2; 401 let Inst{19-15} = rs1; 402 let Inst{14-12} = funct3; 403 let Inst{11-7} = imm12{4-0}; 404 let Opcode = opcode.Value; 405} 406 407class RVInstB<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, 408 string opcodestr, string argstr> 409 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatB> { 410 bits<12> imm12; 411 bits<5> rs2; 412 bits<5> rs1; 413 414 let Inst{31} = imm12{11}; 415 let Inst{30-25} = imm12{9-4}; 416 let Inst{24-20} = rs2; 417 let Inst{19-15} = rs1; 418 let Inst{14-12} = funct3; 419 let Inst{11-8} = imm12{3-0}; 420 let Inst{7} = imm12{10}; 421 let Opcode = opcode.Value; 422} 423 424class RVInstU<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 425 string argstr> 426 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatU> { 427 bits<20> imm20; 428 bits<5> rd; 429 430 let Inst{31-12} = imm20; 431 let Inst{11-7} = rd; 432 let Opcode = opcode.Value; 433} 434 435class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr, 436 string argstr> 437 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatJ> { 438 bits<20> imm20; 439 bits<5> rd; 440 441 let Inst{31} = imm20{19}; 442 let Inst{30-21} = imm20{9-0}; 443 let Inst{20} = imm20{10}; 444 let Inst{19-12} = imm20{18-11}; 445 let Inst{11-7} = rd; 446 let Opcode = opcode.Value; 447} 448 449//===----------------------------------------------------------------------===// 450// Instruction classes for .insn directives 451//===----------------------------------------------------------------------===// 452 453class DirectiveInsnR<dag outs, dag ins, string argstr> 454 : RVInst<outs, ins, "", "", [], InstFormatR> { 455 bits<7> opcode; 456 bits<7> funct7; 457 bits<3> funct3; 458 459 bits<5> rs2; 460 bits<5> rs1; 461 bits<5> rd; 462 463 let Inst{31-25} = funct7; 464 let Inst{24-20} = rs2; 465 let Inst{19-15} = rs1; 466 let Inst{14-12} = funct3; 467 let Inst{11-7} = rd; 468 let Opcode = opcode; 469 470 let AsmString = ".insn r " # argstr; 471} 472 473class DirectiveInsnR4<dag outs, dag ins, string argstr> 474 : RVInst<outs, ins, "", "", [], InstFormatR4> { 475 bits<7> opcode; 476 bits<2> funct2; 477 bits<3> funct3; 478 479 bits<5> rs3; 480 bits<5> rs2; 481 bits<5> rs1; 482 bits<5> rd; 483 484 let Inst{31-27} = rs3; 485 let Inst{26-25} = funct2; 486 let Inst{24-20} = rs2; 487 let Inst{19-15} = rs1; 488 let Inst{14-12} = funct3; 489 let Inst{11-7} = rd; 490 let Opcode = opcode; 491 492 let AsmString = ".insn r4 " # argstr; 493} 494 495class DirectiveInsnI<dag outs, dag ins, string argstr> 496 : RVInst<outs, ins, "", "", [], InstFormatI> { 497 bits<7> opcode; 498 bits<3> funct3; 499 500 bits<12> imm12; 501 bits<5> rs1; 502 bits<5> rd; 503 504 let Inst{31-20} = imm12; 505 let Inst{19-15} = rs1; 506 let Inst{14-12} = funct3; 507 let Inst{11-7} = rd; 508 let Opcode = opcode; 509 510 let AsmString = ".insn i " # argstr; 511} 512 513class DirectiveInsnS<dag outs, dag ins, string argstr> 514 : RVInst<outs, ins, "", "", [], InstFormatS> { 515 bits<7> opcode; 516 bits<3> funct3; 517 518 bits<12> imm12; 519 bits<5> rs2; 520 bits<5> rs1; 521 522 let Inst{31-25} = imm12{11-5}; 523 let Inst{24-20} = rs2; 524 let Inst{19-15} = rs1; 525 let Inst{14-12} = funct3; 526 let Inst{11-7} = imm12{4-0}; 527 let Opcode = opcode; 528 529 let AsmString = ".insn s " # argstr; 530} 531 532class DirectiveInsnB<dag outs, dag ins, string argstr> 533 : RVInst<outs, ins, "", "", [], InstFormatB> { 534 bits<7> opcode; 535 bits<3> funct3; 536 537 bits<12> imm12; 538 bits<5> rs2; 539 bits<5> rs1; 540 541 let Inst{31} = imm12{11}; 542 let Inst{30-25} = imm12{9-4}; 543 let Inst{24-20} = rs2; 544 let Inst{19-15} = rs1; 545 let Inst{14-12} = funct3; 546 let Inst{11-8} = imm12{3-0}; 547 let Inst{7} = imm12{10}; 548 let Opcode = opcode; 549 550 let AsmString = ".insn b " # argstr; 551} 552 553class DirectiveInsnU<dag outs, dag ins, string argstr> 554 : RVInst<outs, ins, "", "", [], InstFormatU> { 555 bits<7> opcode; 556 557 bits<20> imm20; 558 bits<5> rd; 559 560 let Inst{31-12} = imm20; 561 let Inst{11-7} = rd; 562 let Opcode = opcode; 563 564 let AsmString = ".insn u " # argstr; 565} 566 567class DirectiveInsnJ<dag outs, dag ins, string argstr> 568 : RVInst<outs, ins, "", "", [], InstFormatJ> { 569 bits<7> opcode; 570 571 bits<20> imm20; 572 bits<5> rd; 573 574 let Inst{31-12} = imm20; 575 let Inst{11-7} = rd; 576 let Opcode = opcode; 577 578 let AsmString = ".insn j " # argstr; 579} 580