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