1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tablegen -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // This file describes AArch64 instruction formats, down to the level of the 10 // instruction's overall class. 11 //===----------------------------------------------------------------------===// 12 13 14 //===----------------------------------------------------------------------===// 15 // A64 Instruction Format Definitions. 16 //===----------------------------------------------------------------------===// 17 18 // A64 is currently the only instruction set supported by the AArch64 19 // architecture. 20 class A64Inst<dag outs, dag ins, string asmstr, list<dag> patterns, 21 InstrItinClass itin> 22 : Instruction { 23 // All A64 instructions are 32-bit. This field will be filled in 24 // gradually going down the hierarchy. 25 field bits<32> Inst; 26 27 field bits<32> Unpredictable = 0; 28 // SoftFail is the generic name for this field, but we alias it so 29 // as to make it more obvious what it means in ARM-land. 30 field bits<32> SoftFail = Unpredictable; 31 32 // LLVM-level model of the AArch64/A64 distinction. 33 let Namespace = "AArch64"; 34 let DecoderNamespace = "A64"; 35 let Size = 4; 36 37 // Set the templated fields 38 let OutOperandList = outs; 39 let InOperandList = ins; 40 let AsmString = asmstr; 41 let Pattern = patterns; 42 let Itinerary = itin; 43 } 44 45 class PseudoInst<dag outs, dag ins, list<dag> patterns> : Instruction { 46 let Namespace = "AArch64"; 47 48 let OutOperandList = outs; 49 let InOperandList= ins; 50 let Pattern = patterns; 51 let isCodeGenOnly = 1; 52 let isPseudo = 1; 53 } 54 55 // Represents a pseudo-instruction that represents a single A64 instruction for 56 // whatever reason, the eventual result will be a 32-bit real instruction. 57 class A64PseudoInst<dag outs, dag ins, list<dag> patterns> 58 : PseudoInst<outs, ins, patterns> { 59 let Size = 4; 60 } 61 62 // As above, this will be a single A64 instruction, but we can actually give the 63 // expansion in TableGen. 64 class A64PseudoExpand<dag outs, dag ins, list<dag> patterns, dag Result> 65 : A64PseudoInst<outs, ins, patterns>, 66 PseudoInstExpansion<Result>; 67 68 69 // First, some common cross-hierarchy register formats. 70 71 class A64InstRd<dag outs, dag ins, string asmstr, 72 list<dag> patterns, InstrItinClass itin> 73 : A64Inst<outs, ins, asmstr, patterns, itin> { 74 bits<5> Rd; 75 76 let Inst{4-0} = Rd; 77 } 78 79 class A64InstRt<dag outs, dag ins, string asmstr, 80 list<dag> patterns, InstrItinClass itin> 81 : A64Inst<outs, ins, asmstr, patterns, itin> { 82 bits<5> Rt; 83 84 let Inst{4-0} = Rt; 85 } 86 87 88 class A64InstRdn<dag outs, dag ins, string asmstr, 89 list<dag> patterns, InstrItinClass itin> 90 : A64InstRd<outs, ins, asmstr, patterns, itin> { 91 // Inherit rdt 92 bits<5> Rn; 93 94 let Inst{9-5} = Rn; 95 } 96 97 class A64InstRtn<dag outs, dag ins, string asmstr, 98 list<dag> patterns, InstrItinClass itin> 99 : A64InstRt<outs, ins, asmstr, patterns, itin> { 100 // Inherit rdt 101 bits<5> Rn; 102 103 let Inst{9-5} = Rn; 104 } 105 106 // Instructions taking Rt,Rt2,Rn 107 class A64InstRtt2n<dag outs, dag ins, string asmstr, 108 list<dag> patterns, InstrItinClass itin> 109 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 110 bits<5> Rt2; 111 112 let Inst{14-10} = Rt2; 113 } 114 115 class A64InstRdnm<dag outs, dag ins, string asmstr, 116 list<dag> patterns, InstrItinClass itin> 117 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 118 bits<5> Rm; 119 120 let Inst{20-16} = Rm; 121 } 122 123 //===----------------------------------------------------------------------===// 124 // 125 // Actual A64 Instruction Formats 126 // 127 128 // Format for Add-subtract (extended register) instructions. 129 class A64I_addsubext<bit sf, bit op, bit S, bits<2> opt, bits<3> option, 130 dag outs, dag ins, string asmstr, list<dag> patterns, 131 InstrItinClass itin> 132 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 133 bits<3> Imm3; 134 135 let Inst{31} = sf; 136 let Inst{30} = op; 137 let Inst{29} = S; 138 let Inst{28-24} = 0b01011; 139 let Inst{23-22} = opt; 140 let Inst{21} = 0b1; 141 // Rm inherited in 20-16 142 let Inst{15-13} = option; 143 let Inst{12-10} = Imm3; 144 // Rn inherited in 9-5 145 // Rd inherited in 4-0 146 } 147 148 // Format for Add-subtract (immediate) instructions. 149 class A64I_addsubimm<bit sf, bit op, bit S, bits<2> shift, 150 dag outs, dag ins, string asmstr, 151 list<dag> patterns, InstrItinClass itin> 152 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 153 bits<12> Imm12; 154 155 let Inst{31} = sf; 156 let Inst{30} = op; 157 let Inst{29} = S; 158 let Inst{28-24} = 0b10001; 159 let Inst{23-22} = shift; 160 let Inst{21-10} = Imm12; 161 } 162 163 // Format for Add-subtract (shifted register) instructions. 164 class A64I_addsubshift<bit sf, bit op, bit S, bits<2> shift, 165 dag outs, dag ins, string asmstr, list<dag> patterns, 166 InstrItinClass itin> 167 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 168 bits<6> Imm6; 169 170 let Inst{31} = sf; 171 let Inst{30} = op; 172 let Inst{29} = S; 173 let Inst{28-24} = 0b01011; 174 let Inst{23-22} = shift; 175 let Inst{21} = 0b0; 176 // Rm inherited in 20-16 177 let Inst{15-10} = Imm6; 178 // Rn inherited in 9-5 179 // Rd inherited in 4-0 180 } 181 182 // Format for Add-subtract (with carry) instructions. 183 class A64I_addsubcarry<bit sf, bit op, bit S, bits<6> opcode2, 184 dag outs, dag ins, string asmstr, list<dag> patterns, 185 InstrItinClass itin> 186 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 187 let Inst{31} = sf; 188 let Inst{30} = op; 189 let Inst{29} = S; 190 let Inst{28-21} = 0b11010000; 191 // Rm inherited in 20-16 192 let Inst{15-10} = opcode2; 193 // Rn inherited in 9-5 194 // Rd inherited in 4-0 195 } 196 197 198 // Format for Bitfield instructions 199 class A64I_bitfield<bit sf, bits<2> opc, bit n, 200 dag outs, dag ins, string asmstr, 201 list<dag> patterns, InstrItinClass itin> 202 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 203 bits<6> ImmR; 204 bits<6> ImmS; 205 206 let Inst{31} = sf; 207 let Inst{30-29} = opc; 208 let Inst{28-23} = 0b100110; 209 let Inst{22} = n; 210 let Inst{21-16} = ImmR; 211 let Inst{15-10} = ImmS; 212 // Inherit Rn in 9-5 213 // Inherit Rd in 4-0 214 } 215 216 // Format for compare and branch (immediate) instructions. 217 class A64I_cmpbr<bit sf, bit op, 218 dag outs, dag ins, string asmstr, 219 list<dag> patterns, InstrItinClass itin> 220 : A64InstRt<outs, ins, asmstr, patterns, itin> { 221 bits<19> Label; 222 223 let Inst{31} = sf; 224 let Inst{30-25} = 0b011010; 225 let Inst{24} = op; 226 let Inst{23-5} = Label; 227 // Inherit Rt in 4-0 228 } 229 230 // Format for conditional branch (immediate) instructions. 231 class A64I_condbr<bit o1, bit o0, 232 dag outs, dag ins, string asmstr, 233 list<dag> patterns, InstrItinClass itin> 234 : A64Inst<outs, ins, asmstr, patterns, itin> { 235 bits<19> Label; 236 bits<4> Cond; 237 238 let Inst{31-25} = 0b0101010; 239 let Inst{24} = o1; 240 let Inst{23-5} = Label; 241 let Inst{4} = o0; 242 let Inst{3-0} = Cond; 243 } 244 245 // Format for conditional compare (immediate) instructions. 246 class A64I_condcmpimm<bit sf, bit op, bit o2, bit o3, bit s, 247 dag outs, dag ins, string asmstr, 248 list<dag> patterns, InstrItinClass itin> 249 : A64Inst<outs, ins, asmstr, patterns, itin> { 250 bits<5> Rn; 251 bits<5> UImm5; 252 bits<4> NZCVImm; 253 bits<4> Cond; 254 255 let Inst{31} = sf; 256 let Inst{30} = op; 257 let Inst{29} = s; 258 let Inst{28-21} = 0b11010010; 259 let Inst{20-16} = UImm5; 260 let Inst{15-12} = Cond; 261 let Inst{11} = 0b1; 262 let Inst{10} = o2; 263 let Inst{9-5} = Rn; 264 let Inst{4} = o3; 265 let Inst{3-0} = NZCVImm; 266 } 267 268 // Format for conditional compare (register) instructions. 269 class A64I_condcmpreg<bit sf, bit op, bit o2, bit o3, bit s, 270 dag outs, dag ins, string asmstr, 271 list<dag> patterns, InstrItinClass itin> 272 : A64Inst<outs, ins, asmstr, patterns, itin> { 273 bits<5> Rn; 274 bits<5> Rm; 275 bits<4> NZCVImm; 276 bits<4> Cond; 277 278 279 let Inst{31} = sf; 280 let Inst{30} = op; 281 let Inst{29} = s; 282 let Inst{28-21} = 0b11010010; 283 let Inst{20-16} = Rm; 284 let Inst{15-12} = Cond; 285 let Inst{11} = 0b0; 286 let Inst{10} = o2; 287 let Inst{9-5} = Rn; 288 let Inst{4} = o3; 289 let Inst{3-0} = NZCVImm; 290 } 291 292 // Format for conditional select instructions. 293 class A64I_condsel<bit sf, bit op, bit s, bits<2> op2, 294 dag outs, dag ins, string asmstr, 295 list<dag> patterns, InstrItinClass itin> 296 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 297 bits<4> Cond; 298 299 let Inst{31} = sf; 300 let Inst{30} = op; 301 let Inst{29} = s; 302 let Inst{28-21} = 0b11010100; 303 // Inherit Rm in 20-16 304 let Inst{15-12} = Cond; 305 let Inst{11-10} = op2; 306 // Inherit Rn in 9-5 307 // Inherit Rd in 4-0 308 } 309 310 // Format for data processing (1 source) instructions 311 class A64I_dp_1src<bit sf, bit S, bits<5> opcode2, bits<6> opcode, 312 string asmstr, dag outs, dag ins, 313 list<dag> patterns, InstrItinClass itin> 314 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 315 let Inst{31} = sf; 316 let Inst{30} = 0b1; 317 let Inst{29} = S; 318 let Inst{28-21} = 0b11010110; 319 let Inst{20-16} = opcode2; 320 let Inst{15-10} = opcode; 321 } 322 323 // Format for data processing (2 source) instructions 324 class A64I_dp_2src<bit sf, bits<6> opcode, bit S, 325 string asmstr, dag outs, dag ins, 326 list<dag> patterns, InstrItinClass itin> 327 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 328 let Inst{31} = sf; 329 let Inst{30} = 0b0; 330 let Inst{29} = S; 331 let Inst{28-21} = 0b11010110; 332 let Inst{15-10} = opcode; 333 } 334 335 // Format for data-processing (3 source) instructions 336 337 class A64I_dp3<bit sf, bits<6> opcode, 338 dag outs, dag ins, string asmstr, 339 list<dag> patterns, InstrItinClass itin> 340 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 341 bits<5> Ra; 342 343 let Inst{31} = sf; 344 let Inst{30-29} = opcode{5-4}; 345 let Inst{28-24} = 0b11011; 346 let Inst{23-21} = opcode{3-1}; 347 // Inherits Rm in 20-16 348 let Inst{15} = opcode{0}; 349 let Inst{14-10} = Ra; 350 // Inherits Rn in 9-5 351 // Inherits Rd in 4-0 352 } 353 354 // Format for exception generation instructions 355 class A64I_exception<bits<3> opc, bits<3> op2, bits<2> ll, 356 dag outs, dag ins, string asmstr, 357 list<dag> patterns, InstrItinClass itin> 358 : A64Inst<outs, ins, asmstr, patterns, itin> { 359 bits<16> UImm16; 360 361 let Inst{31-24} = 0b11010100; 362 let Inst{23-21} = opc; 363 let Inst{20-5} = UImm16; 364 let Inst{4-2} = op2; 365 let Inst{1-0} = ll; 366 } 367 368 // Format for extract (immediate) instructions 369 class A64I_extract<bit sf, bits<3> op, bit n, 370 dag outs, dag ins, string asmstr, 371 list<dag> patterns, InstrItinClass itin> 372 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 373 bits<6> LSB; 374 375 let Inst{31} = sf; 376 let Inst{30-29} = op{2-1}; 377 let Inst{28-23} = 0b100111; 378 let Inst{22} = n; 379 let Inst{21} = op{0}; 380 // Inherits Rm in bits 20-16 381 let Inst{15-10} = LSB; 382 // Inherits Rn in 9-5 383 // Inherits Rd in 4-0 384 } 385 386 // Format for floating-point compare instructions. 387 class A64I_fpcmp<bit m, bit s, bits<2> type, bits<2> op, bits<5> opcode2, 388 dag outs, dag ins, string asmstr, 389 list<dag> patterns, InstrItinClass itin> 390 : A64Inst<outs, ins, asmstr, patterns, itin> { 391 bits<5> Rn; 392 bits<5> Rm; 393 394 let Inst{31} = m; 395 let Inst{30} = 0b0; 396 let Inst{29} = s; 397 let Inst{28-24} = 0b11110; 398 let Inst{23-22} = type; 399 let Inst{21} = 0b1; 400 let Inst{20-16} = Rm; 401 let Inst{15-14} = op; 402 let Inst{13-10} = 0b1000; 403 let Inst{9-5} = Rn; 404 let Inst{4-0} = opcode2; 405 } 406 407 // Format for floating-point conditional compare instructions. 408 class A64I_fpccmp<bit m, bit s, bits<2> type, bit op, 409 dag outs, dag ins, string asmstr, 410 list<dag> patterns, InstrItinClass itin> 411 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 412 bits<5> Rn; 413 bits<5> Rm; 414 bits<4> NZCVImm; 415 bits<4> Cond; 416 417 let Inst{31} = m; 418 let Inst{30} = 0b0; 419 let Inst{29} = s; 420 let Inst{28-24} = 0b11110; 421 let Inst{23-22} = type; 422 let Inst{21} = 0b1; 423 let Inst{20-16} = Rm; 424 let Inst{15-12} = Cond; 425 let Inst{11-10} = 0b01; 426 let Inst{9-5} = Rn; 427 let Inst{4} = op; 428 let Inst{3-0} = NZCVImm; 429 } 430 431 // Format for floating-point conditional select instructions. 432 class A64I_fpcondsel<bit m, bit s, bits<2> type, 433 dag outs, dag ins, string asmstr, 434 list<dag> patterns, InstrItinClass itin> 435 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 436 bits<4> Cond; 437 438 let Inst{31} = m; 439 let Inst{30} = 0b0; 440 let Inst{29} = s; 441 let Inst{28-24} = 0b11110; 442 let Inst{23-22} = type; 443 let Inst{21} = 0b1; 444 // Inherit Rm in 20-16 445 let Inst{15-12} = Cond; 446 let Inst{11-10} = 0b11; 447 // Inherit Rn in 9-5 448 // Inherit Rd in 4-0 449 } 450 451 452 // Format for floating-point data-processing (1 source) instructions. 453 class A64I_fpdp1<bit m, bit s, bits<2> type, bits<6> opcode, 454 dag outs, dag ins, string asmstr, 455 list<dag> patterns, InstrItinClass itin> 456 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 457 let Inst{31} = m; 458 let Inst{30} = 0b0; 459 let Inst{29} = s; 460 let Inst{28-24} = 0b11110; 461 let Inst{23-22} = type; 462 let Inst{21} = 0b1; 463 let Inst{20-15} = opcode; 464 let Inst{14-10} = 0b10000; 465 // Inherit Rn in 9-5 466 // Inherit Rd in 4-0 467 } 468 469 // Format for floating-point data-processing (2 sources) instructions. 470 class A64I_fpdp2<bit m, bit s, bits<2> type, bits<4> opcode, 471 dag outs, dag ins, string asmstr, 472 list<dag> patterns, InstrItinClass itin> 473 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 474 let Inst{31} = m; 475 let Inst{30} = 0b0; 476 let Inst{29} = s; 477 let Inst{28-24} = 0b11110; 478 let Inst{23-22} = type; 479 let Inst{21} = 0b1; 480 // Inherit Rm in 20-16 481 let Inst{15-12} = opcode; 482 let Inst{11-10} = 0b10; 483 // Inherit Rn in 9-5 484 // Inherit Rd in 4-0 485 } 486 487 // Format for floating-point data-processing (3 sources) instructions. 488 class A64I_fpdp3<bit m, bit s, bits<2> type, bit o1, bit o0, 489 dag outs, dag ins, string asmstr, 490 list<dag> patterns, InstrItinClass itin> 491 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 492 bits<5> Ra; 493 494 let Inst{31} = m; 495 let Inst{30} = 0b0; 496 let Inst{29} = s; 497 let Inst{28-24} = 0b11111; 498 let Inst{23-22} = type; 499 let Inst{21} = o1; 500 // Inherit Rm in 20-16 501 let Inst{15} = o0; 502 let Inst{14-10} = Ra; 503 // Inherit Rn in 9-5 504 // Inherit Rd in 4-0 505 } 506 507 // Format for floating-point <-> fixed-point conversion instructions. 508 class A64I_fpfixed<bit sf, bit s, bits<2> type, bits<2> mode, bits<3> opcode, 509 dag outs, dag ins, string asmstr, 510 list<dag> patterns, InstrItinClass itin> 511 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 512 bits<6> Scale; 513 514 let Inst{31} = sf; 515 let Inst{30} = 0b0; 516 let Inst{29} = s; 517 let Inst{28-24} = 0b11110; 518 let Inst{23-22} = type; 519 let Inst{21} = 0b0; 520 let Inst{20-19} = mode; 521 let Inst{18-16} = opcode; 522 let Inst{15-10} = Scale; 523 // Inherit Rn in 9-5 524 // Inherit Rd in 4-0 525 } 526 527 // Format for floating-point <-> integer conversion instructions. 528 class A64I_fpint<bit sf, bit s, bits<2> type, bits<2> rmode, bits<3> opcode, 529 dag outs, dag ins, string asmstr, 530 list<dag> patterns, InstrItinClass itin> 531 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 532 let Inst{31} = sf; 533 let Inst{30} = 0b0; 534 let Inst{29} = s; 535 let Inst{28-24} = 0b11110; 536 let Inst{23-22} = type; 537 let Inst{21} = 0b1; 538 let Inst{20-19} = rmode; 539 let Inst{18-16} = opcode; 540 let Inst{15-10} = 0b000000; 541 // Inherit Rn in 9-5 542 // Inherit Rd in 4-0 543 } 544 545 546 // Format for floating-point immediate instructions. 547 class A64I_fpimm<bit m, bit s, bits<2> type, bits<5> imm5, 548 dag outs, dag ins, string asmstr, 549 list<dag> patterns, InstrItinClass itin> 550 : A64InstRd<outs, ins, asmstr, patterns, itin> { 551 bits<8> Imm8; 552 553 let Inst{31} = m; 554 let Inst{30} = 0b0; 555 let Inst{29} = s; 556 let Inst{28-24} = 0b11110; 557 let Inst{23-22} = type; 558 let Inst{21} = 0b1; 559 let Inst{20-13} = Imm8; 560 let Inst{12-10} = 0b100; 561 let Inst{9-5} = imm5; 562 // Inherit Rd in 4-0 563 } 564 565 // Format for load-register (literal) instructions. 566 class A64I_LDRlit<bits<2> opc, bit v, 567 dag outs, dag ins, string asmstr, 568 list<dag> patterns, InstrItinClass itin> 569 : A64InstRt<outs, ins, asmstr, patterns, itin> { 570 bits<19> Imm19; 571 572 let Inst{31-30} = opc; 573 let Inst{29-27} = 0b011; 574 let Inst{26} = v; 575 let Inst{25-24} = 0b00; 576 let Inst{23-5} = Imm19; 577 // Inherit Rt in 4-0 578 } 579 580 // Format for load-store exclusive instructions. 581 class A64I_LDSTex_tn<bits<2> size, bit o2, bit L, bit o1, bit o0, 582 dag outs, dag ins, string asmstr, 583 list <dag> patterns, InstrItinClass itin> 584 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 585 let Inst{31-30} = size; 586 let Inst{29-24} = 0b001000; 587 let Inst{23} = o2; 588 let Inst{22} = L; 589 let Inst{21} = o1; 590 let Inst{15} = o0; 591 } 592 593 class A64I_LDSTex_tt2n<bits<2> size, bit o2, bit L, bit o1, bit o0, 594 dag outs, dag ins, string asmstr, 595 list <dag> patterns, InstrItinClass itin>: 596 A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ 597 bits<5> Rt2; 598 let Inst{14-10} = Rt2; 599 } 600 601 class A64I_LDSTex_stn<bits<2> size, bit o2, bit L, bit o1, bit o0, 602 dag outs, dag ins, string asmstr, 603 list <dag> patterns, InstrItinClass itin>: 604 A64I_LDSTex_tn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ 605 bits<5> Rs; 606 let Inst{20-16} = Rs; 607 } 608 609 class A64I_LDSTex_stt2n<bits<2> size, bit o2, bit L, bit o1, bit o0, 610 dag outs, dag ins, string asmstr, 611 list <dag> patterns, InstrItinClass itin>: 612 A64I_LDSTex_stn<size, o2, L, o1, o0, outs, ins, asmstr, patterns, itin>{ 613 bits<5> Rt2; 614 let Inst{14-10} = Rt2; 615 } 616 617 // Format for load-store register (immediate post-indexed) instructions 618 class A64I_LSpostind<bits<2> size, bit v, bits<2> opc, 619 dag outs, dag ins, string asmstr, 620 list<dag> patterns, InstrItinClass itin> 621 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 622 bits<9> SImm9; 623 624 let Inst{31-30} = size; 625 let Inst{29-27} = 0b111; 626 let Inst{26} = v; 627 let Inst{25-24} = 0b00; 628 let Inst{23-22} = opc; 629 let Inst{21} = 0b0; 630 let Inst{20-12} = SImm9; 631 let Inst{11-10} = 0b01; 632 // Inherit Rn in 9-5 633 // Inherit Rt in 4-0 634 } 635 636 // Format for load-store register (immediate pre-indexed) instructions 637 class A64I_LSpreind<bits<2> size, bit v, bits<2> opc, 638 dag outs, dag ins, string asmstr, 639 list<dag> patterns, InstrItinClass itin> 640 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 641 bits<9> SImm9; 642 643 644 let Inst{31-30} = size; 645 let Inst{29-27} = 0b111; 646 let Inst{26} = v; 647 let Inst{25-24} = 0b00; 648 let Inst{23-22} = opc; 649 let Inst{21} = 0b0; 650 let Inst{20-12} = SImm9; 651 let Inst{11-10} = 0b11; 652 // Inherit Rn in 9-5 653 // Inherit Rt in 4-0 654 } 655 656 // Format for load-store register (unprivileged) instructions 657 class A64I_LSunpriv<bits<2> size, bit v, bits<2> opc, 658 dag outs, dag ins, string asmstr, 659 list<dag> patterns, InstrItinClass itin> 660 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 661 bits<9> SImm9; 662 663 664 let Inst{31-30} = size; 665 let Inst{29-27} = 0b111; 666 let Inst{26} = v; 667 let Inst{25-24} = 0b00; 668 let Inst{23-22} = opc; 669 let Inst{21} = 0b0; 670 let Inst{20-12} = SImm9; 671 let Inst{11-10} = 0b10; 672 // Inherit Rn in 9-5 673 // Inherit Rt in 4-0 674 } 675 676 // Format for load-store (unscaled immediate) instructions. 677 class A64I_LSunalimm<bits<2> size, bit v, bits<2> opc, 678 dag outs, dag ins, string asmstr, 679 list<dag> patterns, InstrItinClass itin> 680 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 681 bits<9> SImm9; 682 683 let Inst{31-30} = size; 684 let Inst{29-27} = 0b111; 685 let Inst{26} = v; 686 let Inst{25-24} = 0b00; 687 let Inst{23-22} = opc; 688 let Inst{21} = 0b0; 689 let Inst{20-12} = SImm9; 690 let Inst{11-10} = 0b00; 691 // Inherit Rn in 9-5 692 // Inherit Rt in 4-0 693 } 694 695 696 // Format for load-store (unsigned immediate) instructions. 697 class A64I_LSunsigimm<bits<2> size, bit v, bits<2> opc, 698 dag outs, dag ins, string asmstr, 699 list<dag> patterns, InstrItinClass itin> 700 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 701 bits<12> UImm12; 702 703 let Inst{31-30} = size; 704 let Inst{29-27} = 0b111; 705 let Inst{26} = v; 706 let Inst{25-24} = 0b01; 707 let Inst{23-22} = opc; 708 let Inst{21-10} = UImm12; 709 } 710 711 // Format for load-store register (register offset) instructions. 712 class A64I_LSregoff<bits<2> size, bit v, bits<2> opc, bit optionlo, 713 dag outs, dag ins, string asmstr, 714 list<dag> patterns, InstrItinClass itin> 715 : A64InstRtn<outs, ins, asmstr, patterns, itin> { 716 bits<5> Rm; 717 718 // Complex operand selection needed for these instructions, so they 719 // need an "addr" field for encoding/decoding to be generated. 720 bits<3> Ext; 721 // OptionHi = Ext{2-1} 722 // S = Ext{0} 723 724 let Inst{31-30} = size; 725 let Inst{29-27} = 0b111; 726 let Inst{26} = v; 727 let Inst{25-24} = 0b00; 728 let Inst{23-22} = opc; 729 let Inst{21} = 0b1; 730 let Inst{20-16} = Rm; 731 let Inst{15-14} = Ext{2-1}; 732 let Inst{13} = optionlo; 733 let Inst{12} = Ext{0}; 734 let Inst{11-10} = 0b10; 735 // Inherits Rn in 9-5 736 // Inherits Rt in 4-0 737 738 let AddedComplexity = 50; 739 } 740 741 // Format for Load-store register pair (offset) instructions 742 class A64I_LSPoffset<bits<2> opc, bit v, bit l, 743 dag outs, dag ins, string asmstr, 744 list<dag> patterns, InstrItinClass itin> 745 : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { 746 bits<7> SImm7; 747 748 let Inst{31-30} = opc; 749 let Inst{29-27} = 0b101; 750 let Inst{26} = v; 751 let Inst{25-23} = 0b010; 752 let Inst{22} = l; 753 let Inst{21-15} = SImm7; 754 // Inherit Rt2 in 14-10 755 // Inherit Rn in 9-5 756 // Inherit Rt in 4-0 757 } 758 759 // Format for Load-store register pair (post-indexed) instructions 760 class A64I_LSPpostind<bits<2> opc, bit v, bit l, 761 dag outs, dag ins, string asmstr, 762 list<dag> patterns, InstrItinClass itin> 763 : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { 764 bits<7> SImm7; 765 766 let Inst{31-30} = opc; 767 let Inst{29-27} = 0b101; 768 let Inst{26} = v; 769 let Inst{25-23} = 0b001; 770 let Inst{22} = l; 771 let Inst{21-15} = SImm7; 772 // Inherit Rt2 in 14-10 773 // Inherit Rn in 9-5 774 // Inherit Rt in 4-0 775 } 776 777 // Format for Load-store register pair (pre-indexed) instructions 778 class A64I_LSPpreind<bits<2> opc, bit v, bit l, 779 dag outs, dag ins, string asmstr, 780 list<dag> patterns, InstrItinClass itin> 781 : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { 782 bits<7> SImm7; 783 784 let Inst{31-30} = opc; 785 let Inst{29-27} = 0b101; 786 let Inst{26} = v; 787 let Inst{25-23} = 0b011; 788 let Inst{22} = l; 789 let Inst{21-15} = SImm7; 790 // Inherit Rt2 in 14-10 791 // Inherit Rn in 9-5 792 // Inherit Rt in 4-0 793 } 794 795 // Format for Load-store non-temporal register pair (offset) instructions 796 class A64I_LSPnontemp<bits<2> opc, bit v, bit l, 797 dag outs, dag ins, string asmstr, 798 list<dag> patterns, InstrItinClass itin> 799 : A64InstRtt2n<outs, ins, asmstr, patterns, itin> { 800 bits<7> SImm7; 801 802 let Inst{31-30} = opc; 803 let Inst{29-27} = 0b101; 804 let Inst{26} = v; 805 let Inst{25-23} = 0b000; 806 let Inst{22} = l; 807 let Inst{21-15} = SImm7; 808 // Inherit Rt2 in 14-10 809 // Inherit Rn in 9-5 810 // Inherit Rt in 4-0 811 } 812 813 // Format for Logical (immediate) instructions 814 class A64I_logicalimm<bit sf, bits<2> opc, 815 dag outs, dag ins, string asmstr, 816 list<dag> patterns, InstrItinClass itin> 817 : A64InstRdn<outs, ins, asmstr, patterns, itin> { 818 bit N; 819 bits<6> ImmR; 820 bits<6> ImmS; 821 822 // N, ImmR and ImmS have no separate existence in any assembly syntax (or for 823 // selection), so we'll combine them into a single field here. 824 bits<13> Imm; 825 // N = Imm{12}; 826 // ImmR = Imm{11-6}; 827 // ImmS = Imm{5-0}; 828 829 let Inst{31} = sf; 830 let Inst{30-29} = opc; 831 let Inst{28-23} = 0b100100; 832 let Inst{22} = Imm{12}; 833 let Inst{21-16} = Imm{11-6}; 834 let Inst{15-10} = Imm{5-0}; 835 // Rn inherited in 9-5 836 // Rd inherited in 4-0 837 } 838 839 // Format for Logical (shifted register) instructions 840 class A64I_logicalshift<bit sf, bits<2> opc, bits<2> shift, bit N, 841 dag outs, dag ins, string asmstr, 842 list<dag> patterns, InstrItinClass itin> 843 : A64InstRdnm<outs, ins, asmstr, patterns, itin> { 844 bits<6> Imm6; 845 846 let Inst{31} = sf; 847 let Inst{30-29} = opc; 848 let Inst{28-24} = 0b01010; 849 let Inst{23-22} = shift; 850 let Inst{21} = N; 851 // Rm inherited 852 let Inst{15-10} = Imm6; 853 // Rn inherited 854 // Rd inherited 855 } 856 857 // Format for Move wide (immediate) 858 class A64I_movw<bit sf, bits<2> opc, 859 dag outs, dag ins, string asmstr, 860 list<dag> patterns, InstrItinClass itin> 861 : A64InstRd<outs, ins, asmstr, patterns, itin> { 862 bits<16> UImm16; 863 bits<2> Shift; // Called "hw" officially 864 865 let Inst{31} = sf; 866 let Inst{30-29} = opc; 867 let Inst{28-23} = 0b100101; 868 let Inst{22-21} = Shift; 869 let Inst{20-5} = UImm16; 870 // Inherits Rd in 4-0 871 } 872 873 // Format for PC-relative addressing instructions, ADR and ADRP. 874 class A64I_PCADR<bit op, 875 dag outs, dag ins, string asmstr, 876 list<dag> patterns, InstrItinClass itin> 877 : A64InstRd<outs, ins, asmstr, patterns, itin> { 878 bits<21> Label; 879 880 let Inst{31} = op; 881 let Inst{30-29} = Label{1-0}; 882 let Inst{28-24} = 0b10000; 883 let Inst{23-5} = Label{20-2}; 884 } 885 886 // Format for system instructions 887 class A64I_system<bit l, 888 dag outs, dag ins, string asmstr, 889 list<dag> patterns, InstrItinClass itin> 890 : A64Inst<outs, ins, asmstr, patterns, itin> { 891 bits<2> Op0; 892 bits<3> Op1; 893 bits<4> CRn; 894 bits<4> CRm; 895 bits<3> Op2; 896 bits<5> Rt; 897 898 let Inst{31-22} = 0b1101010100; 899 let Inst{21} = l; 900 let Inst{20-19} = Op0; 901 let Inst{18-16} = Op1; 902 let Inst{15-12} = CRn; 903 let Inst{11-8} = CRm; 904 let Inst{7-5} = Op2; 905 let Inst{4-0} = Rt; 906 907 // These instructions can do horrible things. 908 let hasSideEffects = 1; 909 } 910 911 // Format for unconditional branch (immediate) instructions 912 class A64I_Bimm<bit op, 913 dag outs, dag ins, string asmstr, 914 list<dag> patterns, InstrItinClass itin> 915 : A64Inst<outs, ins, asmstr, patterns, itin> { 916 // Doubly special in not even sharing register fields with other 917 // instructions, so we create our own Rn here. 918 bits<26> Label; 919 920 let Inst{31} = op; 921 let Inst{30-26} = 0b00101; 922 let Inst{25-0} = Label; 923 } 924 925 // Format for Test & branch (immediate) instructions 926 class A64I_TBimm<bit op, 927 dag outs, dag ins, string asmstr, 928 list<dag> patterns, InstrItinClass itin> 929 : A64InstRt<outs, ins, asmstr, patterns, itin> { 930 // Doubly special in not even sharing register fields with other 931 // instructions, so we create our own Rn here. 932 bits<6> Imm; 933 bits<14> Label; 934 935 let Inst{31} = Imm{5}; 936 let Inst{30-25} = 0b011011; 937 let Inst{24} = op; 938 let Inst{23-19} = Imm{4-0}; 939 let Inst{18-5} = Label; 940 // Inherit Rt in 4-0 941 } 942 943 // Format for Unconditional branch (register) instructions, including 944 // RET. Shares no fields with instructions further up the hierarchy 945 // so top-level. 946 class A64I_Breg<bits<4> opc, bits<5> op2, bits<6> op3, bits<5> op4, 947 dag outs, dag ins, string asmstr, 948 list<dag> patterns, InstrItinClass itin> 949 : A64Inst<outs, ins, asmstr, patterns, itin> { 950 // Doubly special in not even sharing register fields with other 951 // instructions, so we create our own Rn here. 952 bits<5> Rn; 953 954 let Inst{31-25} = 0b1101011; 955 let Inst{24-21} = opc; 956 let Inst{20-16} = op2; 957 let Inst{15-10} = op3; 958 let Inst{9-5} = Rn; 959 let Inst{4-0} = op4; 960 } 961 962 963 //===----------------------------------------------------------------------===// 964 // 965 // Neon Instruction Format Definitions. 966 // 967 968 let Predicates = [HasNEON] in { 969 970 class NeonInstAlias<string Asm, dag Result, bit Emit = 0b1> 971 : InstAlias<Asm, Result, Emit> { 972 } 973 974 // Format AdvSIMD 3 vector registers with same vector type 975 class NeonI_3VSame<bit q, bit u, bits<2> size, bits<5> opcode, 976 dag outs, dag ins, string asmstr, 977 list<dag> patterns, InstrItinClass itin> 978 : A64InstRdnm<outs, ins, asmstr, patterns, itin> 979 { 980 let Inst{31} = 0b0; 981 let Inst{30} = q; 982 let Inst{29} = u; 983 let Inst{28-24} = 0b01110; 984 let Inst{23-22} = size; 985 let Inst{21} = 0b1; 986 // Inherit Rm in 20-16 987 let Inst{15-11} = opcode; 988 let Inst{10} = 0b1; 989 // Inherit Rn in 9-5 990 // Inherit Rd in 4-0 991 } 992 993 // Format AdvSIMD 1 vector register with modified immediate 994 class NeonI_1VModImm<bit q, bit op, 995 dag outs, dag ins, string asmstr, 996 list<dag> patterns, InstrItinClass itin> 997 : A64InstRd<outs,ins, asmstr, patterns, itin> 998 { 999 bits<8> Imm; 1000 bits<4> cmode; 1001 let Inst{31} = 0b0; 1002 let Inst{30} = q; 1003 let Inst{29} = op; 1004 let Inst{28-19} = 0b0111100000; 1005 let Inst{15-12} = cmode; 1006 let Inst{11} = 0b0; // o2 1007 let Inst{10} = 1; 1008 // Inherit Rd in 4-0 1009 let Inst{18-16} = Imm{7-5}; // imm a:b:c 1010 let Inst{9-5} = Imm{4-0}; // imm d:e:f:g:h 1011 } 1012 1013 // Format AdvSIMD 3 scalar registers with same type 1014 1015 class NeonI_Scalar3Same<bit u, bits<2> size, bits<5> opcode, 1016 dag outs, dag ins, string asmstr, 1017 list<dag> patterns, InstrItinClass itin> 1018 : A64InstRdnm<outs, ins, asmstr, patterns, itin> 1019 { 1020 let Inst{31} = 0b0; 1021 let Inst{30} = 0b1; 1022 let Inst{29} = u; 1023 let Inst{28-24} = 0b11110; 1024 let Inst{23-22} = size; 1025 let Inst{21} = 0b1; 1026 // Inherit Rm in 20-16 1027 let Inst{15-11} = opcode; 1028 let Inst{10} = 0b1; 1029 // Inherit Rn in 9-5 1030 // Inherit Rd in 4-0 1031 } 1032 1033 1034 // Format AdvSIMD 2 vector registers miscellaneous 1035 class NeonI_2VMisc<bit q, bit u, bits<2> size, bits<5> opcode, 1036 dag outs, dag ins, string asmstr, 1037 list<dag> patterns, InstrItinClass itin> 1038 : A64InstRdn<outs, ins, asmstr, patterns, itin> 1039 { 1040 let Inst{31} = 0b0; 1041 let Inst{30} = q; 1042 let Inst{29} = u; 1043 let Inst{28-24} = 0b01110; 1044 let Inst{23-22} = size; 1045 let Inst{21-17} = 0b10000; 1046 let Inst{16-12} = opcode; 1047 let Inst{11-10} = 0b10; 1048 1049 // Inherit Rn in 9-5 1050 // Inherit Rd in 4-0 1051 } 1052 1053 } 1054 1055