ARMInstrFormats.td revision 200581
1//===- ARMInstrFormats.td - ARM 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 10//===----------------------------------------------------------------------===// 11// 12// ARM Instruction Format Definitions. 13// 14 15// Format specifies the encoding used by the instruction. This is part of the 16// ad-hoc solution used to emit machine instruction encodings by our machine 17// code emitter. 18class Format<bits<5> val> { 19 bits<5> Value = val; 20} 21 22def Pseudo : Format<0>; 23def MulFrm : Format<1>; 24def BrFrm : Format<2>; 25def BrMiscFrm : Format<3>; 26 27def DPFrm : Format<4>; 28def DPSoRegFrm : Format<5>; 29 30def LdFrm : Format<6>; 31def StFrm : Format<7>; 32def LdMiscFrm : Format<8>; 33def StMiscFrm : Format<9>; 34def LdStMulFrm : Format<10>; 35 36def LdStExFrm : Format<28>; 37 38def ArithMiscFrm : Format<11>; 39def ExtFrm : Format<12>; 40 41def VFPUnaryFrm : Format<13>; 42def VFPBinaryFrm : Format<14>; 43def VFPConv1Frm : Format<15>; 44def VFPConv2Frm : Format<16>; 45def VFPConv3Frm : Format<17>; 46def VFPConv4Frm : Format<18>; 47def VFPConv5Frm : Format<19>; 48def VFPLdStFrm : Format<20>; 49def VFPLdStMulFrm : Format<21>; 50def VFPMiscFrm : Format<22>; 51 52def ThumbFrm : Format<23>; 53 54def NEONFrm : Format<24>; 55def NEONGetLnFrm : Format<25>; 56def NEONSetLnFrm : Format<26>; 57def NEONDupFrm : Format<27>; 58 59// Misc flags. 60 61// the instruction has a Rn register operand. 62// UnaryDP - Indicates this is a unary data processing instruction, i.e. 63// it doesn't have a Rn operand. 64class UnaryDP { bit isUnaryDataProc = 1; } 65 66// Xform16Bit - Indicates this Thumb2 instruction may be transformed into 67// a 16-bit Thumb instruction if certain conditions are met. 68class Xform16Bit { bit canXformTo16Bit = 1; } 69 70//===----------------------------------------------------------------------===// 71// ARM Instruction flags. These need to match ARMInstrInfo.h. 72// 73 74// Addressing mode. 75class AddrMode<bits<4> val> { 76 bits<4> Value = val; 77} 78def AddrModeNone : AddrMode<0>; 79def AddrMode1 : AddrMode<1>; 80def AddrMode2 : AddrMode<2>; 81def AddrMode3 : AddrMode<3>; 82def AddrMode4 : AddrMode<4>; 83def AddrMode5 : AddrMode<5>; 84def AddrMode6 : AddrMode<6>; 85def AddrModeT1_1 : AddrMode<7>; 86def AddrModeT1_2 : AddrMode<8>; 87def AddrModeT1_4 : AddrMode<9>; 88def AddrModeT1_s : AddrMode<10>; 89def AddrModeT2_i12: AddrMode<11>; 90def AddrModeT2_i8 : AddrMode<12>; 91def AddrModeT2_so : AddrMode<13>; 92def AddrModeT2_pc : AddrMode<14>; 93def AddrModeT2_i8s4 : AddrMode<15>; 94 95// Instruction size. 96class SizeFlagVal<bits<3> val> { 97 bits<3> Value = val; 98} 99def SizeInvalid : SizeFlagVal<0>; // Unset. 100def SizeSpecial : SizeFlagVal<1>; // Pseudo or special. 101def Size8Bytes : SizeFlagVal<2>; 102def Size4Bytes : SizeFlagVal<3>; 103def Size2Bytes : SizeFlagVal<4>; 104 105// Load / store index mode. 106class IndexMode<bits<2> val> { 107 bits<2> Value = val; 108} 109def IndexModeNone : IndexMode<0>; 110def IndexModePre : IndexMode<1>; 111def IndexModePost : IndexMode<2>; 112 113// Instruction execution domain. 114class Domain<bits<2> val> { 115 bits<2> Value = val; 116} 117def GenericDomain : Domain<0>; 118def VFPDomain : Domain<1>; // Instructions in VFP domain only 119def NeonDomain : Domain<2>; // Instructions in Neon domain only 120def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains 121 122//===----------------------------------------------------------------------===// 123 124// ARM special operands. 125// 126 127// ARM Predicate operand. Default to 14 = always (AL). Second part is CC 128// register whose default is 0 (no register). 129def pred : PredicateOperand<OtherVT, (ops i32imm, CCR), 130 (ops (i32 14), (i32 zero_reg))> { 131 let PrintMethod = "printPredicateOperand"; 132} 133 134// Conditional code result for instructions whose 's' bit is set, e.g. subs. 135def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> { 136 let PrintMethod = "printSBitModifierOperand"; 137} 138 139// Same as cc_out except it defaults to setting CPSR. 140def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> { 141 let PrintMethod = "printSBitModifierOperand"; 142} 143 144//===----------------------------------------------------------------------===// 145 146// ARM Instruction templates. 147// 148 149class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im, 150 Format f, Domain d, string cstr, InstrItinClass itin> 151 : Instruction { 152 field bits<32> Inst; 153 154 let Namespace = "ARM"; 155 156 // TSFlagsFields 157 AddrMode AM = am; 158 bits<4> AddrModeBits = AM.Value; 159 160 SizeFlagVal SZ = sz; 161 bits<3> SizeFlag = SZ.Value; 162 163 IndexMode IM = im; 164 bits<2> IndexModeBits = IM.Value; 165 166 Format F = f; 167 bits<5> Form = F.Value; 168 169 Domain D = d; 170 bits<2> Dom = D.Value; 171 172 // 173 // Attributes specific to ARM instructions... 174 // 175 bit isUnaryDataProc = 0; 176 bit canXformTo16Bit = 0; 177 178 let Constraints = cstr; 179 let Itinerary = itin; 180} 181 182class PseudoInst<dag oops, dag iops, InstrItinClass itin, 183 string asm, list<dag> pattern> 184 : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, GenericDomain, 185 "", itin> { 186 let OutOperandList = oops; 187 let InOperandList = iops; 188 let AsmString = asm; 189 let Pattern = pattern; 190} 191 192// Almost all ARM instructions are predicable. 193class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 194 IndexMode im, Format f, InstrItinClass itin, 195 string opc, string asm, string cstr, 196 list<dag> pattern> 197 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 198 let OutOperandList = oops; 199 let InOperandList = !con(iops, (ops pred:$p)); 200 let AsmString = !strconcat(opc, !strconcat("${p}", asm)); 201 let Pattern = pattern; 202 list<Predicate> Predicates = [IsARM]; 203} 204// A few are not predicable 205class InoP<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 206 IndexMode im, Format f, InstrItinClass itin, 207 string opc, string asm, string cstr, 208 list<dag> pattern> 209 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 210 let OutOperandList = oops; 211 let InOperandList = iops; 212 let AsmString = !strconcat(opc, asm); 213 let Pattern = pattern; 214 let isPredicable = 0; 215 list<Predicate> Predicates = [IsARM]; 216} 217 218// Same as I except it can optionally modify CPSR. Note it's modeled as 219// an input operand since by default it's a zero register. It will 220// become an implicit def once it's "flipped". 221class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 222 IndexMode im, Format f, InstrItinClass itin, 223 string opc, string asm, string cstr, 224 list<dag> pattern> 225 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 226 let OutOperandList = oops; 227 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s)); 228 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm)); 229 let Pattern = pattern; 230 list<Predicate> Predicates = [IsARM]; 231} 232 233// Special cases 234class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 235 IndexMode im, Format f, InstrItinClass itin, 236 string asm, string cstr, list<dag> pattern> 237 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 238 let OutOperandList = oops; 239 let InOperandList = iops; 240 let AsmString = asm; 241 let Pattern = pattern; 242 list<Predicate> Predicates = [IsARM]; 243} 244 245class AI<dag oops, dag iops, Format f, InstrItinClass itin, 246 string opc, string asm, list<dag> pattern> 247 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin, 248 opc, asm, "", pattern>; 249class AsI<dag oops, dag iops, Format f, InstrItinClass itin, 250 string opc, string asm, list<dag> pattern> 251 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin, 252 opc, asm, "", pattern>; 253class AXI<dag oops, dag iops, Format f, InstrItinClass itin, 254 string asm, list<dag> pattern> 255 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin, 256 asm, "", pattern>; 257class AInoP<dag oops, dag iops, Format f, InstrItinClass itin, 258 string opc, string asm, list<dag> pattern> 259 : InoP<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin, 260 opc, asm, "", pattern>; 261 262// Ctrl flow instructions 263class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 264 string opc, string asm, list<dag> pattern> 265 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin, 266 opc, asm, "", pattern> { 267 let Inst{27-24} = opcod; 268} 269class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 270 string asm, list<dag> pattern> 271 : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, itin, 272 asm, "", pattern> { 273 let Inst{27-24} = opcod; 274} 275class ABXIx2<dag oops, dag iops, InstrItinClass itin, 276 string asm, list<dag> pattern> 277 : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, itin, 278 asm, "", pattern>; 279 280// BR_JT instructions 281class JTI<dag oops, dag iops, InstrItinClass itin, 282 string asm, list<dag> pattern> 283 : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm, itin, 284 asm, "", pattern>; 285 286 287// Atomic load/store instructions 288 289class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 290 string opc, string asm, list<dag> pattern> 291 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin, 292 opc, asm, "", pattern> { 293 let Inst{27-23} = 0b00011; 294 let Inst{22-21} = opcod; 295 let Inst{20} = 1; 296 let Inst{11-0} = 0b111110011111; 297} 298class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 299 string opc, string asm, list<dag> pattern> 300 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, LdStExFrm, itin, 301 opc, asm, "", pattern> { 302 let Inst{27-23} = 0b00011; 303 let Inst{22-21} = opcod; 304 let Inst{20} = 0; 305 let Inst{11-4} = 0b11111001; 306} 307 308// addrmode1 instructions 309class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 310 string opc, string asm, list<dag> pattern> 311 : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin, 312 opc, asm, "", pattern> { 313 let Inst{24-21} = opcod; 314 let Inst{27-26} = {0,0}; 315} 316class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 317 string opc, string asm, list<dag> pattern> 318 : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin, 319 opc, asm, "", pattern> { 320 let Inst{24-21} = opcod; 321 let Inst{27-26} = {0,0}; 322} 323class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 324 string asm, list<dag> pattern> 325 : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, itin, 326 asm, "", pattern> { 327 let Inst{24-21} = opcod; 328 let Inst{27-26} = {0,0}; 329} 330class AI1x2<dag oops, dag iops, Format f, InstrItinClass itin, 331 string opc, string asm, list<dag> pattern> 332 : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, itin, 333 opc, asm, "", pattern>; 334 335 336// addrmode2 loads and stores 337class AI2<dag oops, dag iops, Format f, InstrItinClass itin, 338 string opc, string asm, list<dag> pattern> 339 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 340 opc, asm, "", pattern> { 341 let Inst{27-26} = {0,1}; 342} 343 344// loads 345class AI2ldw<dag oops, dag iops, Format f, InstrItinClass itin, 346 string opc, string asm, list<dag> pattern> 347 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 348 opc, asm, "", pattern> { 349 let Inst{20} = 1; // L bit 350 let Inst{21} = 0; // W bit 351 let Inst{22} = 0; // B bit 352 let Inst{24} = 1; // P bit 353 let Inst{27-26} = {0,1}; 354} 355class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin, 356 string asm, list<dag> pattern> 357 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 358 asm, "", pattern> { 359 let Inst{20} = 1; // L bit 360 let Inst{21} = 0; // W bit 361 let Inst{22} = 0; // B bit 362 let Inst{24} = 1; // P bit 363 let Inst{27-26} = {0,1}; 364} 365class AI2ldb<dag oops, dag iops, Format f, InstrItinClass itin, 366 string opc, string asm, list<dag> pattern> 367 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 368 opc, asm, "", pattern> { 369 let Inst{20} = 1; // L bit 370 let Inst{21} = 0; // W bit 371 let Inst{22} = 1; // B bit 372 let Inst{24} = 1; // P bit 373 let Inst{27-26} = {0,1}; 374} 375class AXI2ldb<dag oops, dag iops, Format f, InstrItinClass itin, 376 string asm, list<dag> pattern> 377 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 378 asm, "", pattern> { 379 let Inst{20} = 1; // L bit 380 let Inst{21} = 0; // W bit 381 let Inst{22} = 1; // B bit 382 let Inst{24} = 1; // P bit 383 let Inst{27-26} = {0,1}; 384} 385 386// stores 387class AI2stw<dag oops, dag iops, Format f, InstrItinClass itin, 388 string opc, string asm, list<dag> pattern> 389 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 390 opc, asm, "", pattern> { 391 let Inst{20} = 0; // L bit 392 let Inst{21} = 0; // W bit 393 let Inst{22} = 0; // B bit 394 let Inst{24} = 1; // P bit 395 let Inst{27-26} = {0,1}; 396} 397class AXI2stw<dag oops, dag iops, Format f, InstrItinClass itin, 398 string asm, list<dag> pattern> 399 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 400 asm, "", pattern> { 401 let Inst{20} = 0; // L bit 402 let Inst{21} = 0; // W bit 403 let Inst{22} = 0; // B bit 404 let Inst{24} = 1; // P bit 405 let Inst{27-26} = {0,1}; 406} 407class AI2stb<dag oops, dag iops, Format f, InstrItinClass itin, 408 string opc, string asm, list<dag> pattern> 409 : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 410 opc, asm, "", pattern> { 411 let Inst{20} = 0; // L bit 412 let Inst{21} = 0; // W bit 413 let Inst{22} = 1; // B bit 414 let Inst{24} = 1; // P bit 415 let Inst{27-26} = {0,1}; 416} 417class AXI2stb<dag oops, dag iops, Format f, InstrItinClass itin, 418 string asm, list<dag> pattern> 419 : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, itin, 420 asm, "", pattern> { 421 let Inst{20} = 0; // L bit 422 let Inst{21} = 0; // W bit 423 let Inst{22} = 1; // B bit 424 let Inst{24} = 1; // P bit 425 let Inst{27-26} = {0,1}; 426} 427 428// Pre-indexed loads 429class AI2ldwpr<dag oops, dag iops, Format f, InstrItinClass itin, 430 string opc, string asm, string cstr, list<dag> pattern> 431 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin, 432 opc, asm, cstr, pattern> { 433 let Inst{20} = 1; // L bit 434 let Inst{21} = 1; // W bit 435 let Inst{22} = 0; // B bit 436 let Inst{24} = 1; // P bit 437 let Inst{27-26} = {0,1}; 438} 439class AI2ldbpr<dag oops, dag iops, Format f, InstrItinClass itin, 440 string opc, string asm, string cstr, list<dag> pattern> 441 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin, 442 opc, asm, cstr, pattern> { 443 let Inst{20} = 1; // L bit 444 let Inst{21} = 1; // W bit 445 let Inst{22} = 1; // B bit 446 let Inst{24} = 1; // P bit 447 let Inst{27-26} = {0,1}; 448} 449 450// Pre-indexed stores 451class AI2stwpr<dag oops, dag iops, Format f, InstrItinClass itin, 452 string opc, string asm, string cstr, list<dag> pattern> 453 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin, 454 opc, asm, cstr, pattern> { 455 let Inst{20} = 0; // L bit 456 let Inst{21} = 1; // W bit 457 let Inst{22} = 0; // B bit 458 let Inst{24} = 1; // P bit 459 let Inst{27-26} = {0,1}; 460} 461class AI2stbpr<dag oops, dag iops, Format f, InstrItinClass itin, 462 string opc, string asm, string cstr, list<dag> pattern> 463 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, itin, 464 opc, asm, cstr, pattern> { 465 let Inst{20} = 0; // L bit 466 let Inst{21} = 1; // W bit 467 let Inst{22} = 1; // B bit 468 let Inst{24} = 1; // P bit 469 let Inst{27-26} = {0,1}; 470} 471 472// Post-indexed loads 473class AI2ldwpo<dag oops, dag iops, Format f, InstrItinClass itin, 474 string opc, string asm, string cstr, list<dag> pattern> 475 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin, 476 opc, asm, cstr,pattern> { 477 let Inst{20} = 1; // L bit 478 let Inst{21} = 0; // W bit 479 let Inst{22} = 0; // B bit 480 let Inst{24} = 0; // P bit 481 let Inst{27-26} = {0,1}; 482} 483class AI2ldbpo<dag oops, dag iops, Format f, InstrItinClass itin, 484 string opc, string asm, string cstr, list<dag> pattern> 485 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin, 486 opc, asm, cstr,pattern> { 487 let Inst{20} = 1; // L bit 488 let Inst{21} = 0; // W bit 489 let Inst{22} = 1; // B bit 490 let Inst{24} = 0; // P bit 491 let Inst{27-26} = {0,1}; 492} 493 494// Post-indexed stores 495class AI2stwpo<dag oops, dag iops, Format f, InstrItinClass itin, 496 string opc, string asm, string cstr, list<dag> pattern> 497 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin, 498 opc, asm, cstr,pattern> { 499 let Inst{20} = 0; // L bit 500 let Inst{21} = 0; // W bit 501 let Inst{22} = 0; // B bit 502 let Inst{24} = 0; // P bit 503 let Inst{27-26} = {0,1}; 504} 505class AI2stbpo<dag oops, dag iops, Format f, InstrItinClass itin, 506 string opc, string asm, string cstr, list<dag> pattern> 507 : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, itin, 508 opc, asm, cstr,pattern> { 509 let Inst{20} = 0; // L bit 510 let Inst{21} = 0; // W bit 511 let Inst{22} = 1; // B bit 512 let Inst{24} = 0; // P bit 513 let Inst{27-26} = {0,1}; 514} 515 516// addrmode3 instructions 517class AI3<dag oops, dag iops, Format f, InstrItinClass itin, 518 string opc, string asm, list<dag> pattern> 519 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 520 opc, asm, "", pattern>; 521class AXI3<dag oops, dag iops, Format f, InstrItinClass itin, 522 string asm, list<dag> pattern> 523 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 524 asm, "", pattern>; 525 526// loads 527class AI3ldh<dag oops, dag iops, Format f, InstrItinClass itin, 528 string opc, string asm, list<dag> pattern> 529 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 530 opc, asm, "", pattern> { 531 let Inst{4} = 1; 532 let Inst{5} = 1; // H bit 533 let Inst{6} = 0; // S bit 534 let Inst{7} = 1; 535 let Inst{20} = 1; // L bit 536 let Inst{21} = 0; // W bit 537 let Inst{24} = 1; // P bit 538 let Inst{27-25} = 0b000; 539} 540class AXI3ldh<dag oops, dag iops, Format f, InstrItinClass itin, 541 string asm, list<dag> pattern> 542 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 543 asm, "", pattern> { 544 let Inst{4} = 1; 545 let Inst{5} = 1; // H bit 546 let Inst{6} = 0; // S bit 547 let Inst{7} = 1; 548 let Inst{20} = 1; // L bit 549 let Inst{21} = 0; // W bit 550 let Inst{24} = 1; // P bit 551} 552class AI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin, 553 string opc, string asm, list<dag> pattern> 554 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 555 opc, asm, "", pattern> { 556 let Inst{4} = 1; 557 let Inst{5} = 1; // H bit 558 let Inst{6} = 1; // S bit 559 let Inst{7} = 1; 560 let Inst{20} = 1; // L bit 561 let Inst{21} = 0; // W bit 562 let Inst{24} = 1; // P bit 563 let Inst{27-25} = 0b000; 564} 565class AXI3ldsh<dag oops, dag iops, Format f, InstrItinClass itin, 566 string asm, list<dag> pattern> 567 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 568 asm, "", pattern> { 569 let Inst{4} = 1; 570 let Inst{5} = 1; // H bit 571 let Inst{6} = 1; // S bit 572 let Inst{7} = 1; 573 let Inst{20} = 1; // L bit 574 let Inst{21} = 0; // W bit 575 let Inst{24} = 1; // P bit 576} 577class AI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin, 578 string opc, string asm, list<dag> pattern> 579 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 580 opc, asm, "", pattern> { 581 let Inst{4} = 1; 582 let Inst{5} = 0; // H bit 583 let Inst{6} = 1; // S bit 584 let Inst{7} = 1; 585 let Inst{20} = 1; // L bit 586 let Inst{21} = 0; // W bit 587 let Inst{24} = 1; // P bit 588 let Inst{27-25} = 0b000; 589} 590class AXI3ldsb<dag oops, dag iops, Format f, InstrItinClass itin, 591 string asm, list<dag> pattern> 592 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 593 asm, "", pattern> { 594 let Inst{4} = 1; 595 let Inst{5} = 0; // H bit 596 let Inst{6} = 1; // S bit 597 let Inst{7} = 1; 598 let Inst{20} = 1; // L bit 599 let Inst{21} = 0; // W bit 600 let Inst{24} = 1; // P bit 601} 602class AI3ldd<dag oops, dag iops, Format f, InstrItinClass itin, 603 string opc, string asm, list<dag> pattern> 604 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 605 opc, asm, "", pattern> { 606 let Inst{4} = 1; 607 let Inst{5} = 0; // H bit 608 let Inst{6} = 1; // S bit 609 let Inst{7} = 1; 610 let Inst{20} = 0; // L bit 611 let Inst{21} = 0; // W bit 612 let Inst{24} = 1; // P bit 613 let Inst{27-25} = 0b000; 614} 615 616// stores 617class AI3sth<dag oops, dag iops, Format f, InstrItinClass itin, 618 string opc, string asm, list<dag> pattern> 619 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 620 opc, asm, "", pattern> { 621 let Inst{4} = 1; 622 let Inst{5} = 1; // H bit 623 let Inst{6} = 0; // S bit 624 let Inst{7} = 1; 625 let Inst{20} = 0; // L bit 626 let Inst{21} = 0; // W bit 627 let Inst{24} = 1; // P bit 628 let Inst{27-25} = 0b000; 629} 630class AXI3sth<dag oops, dag iops, Format f, InstrItinClass itin, 631 string asm, list<dag> pattern> 632 : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 633 asm, "", pattern> { 634 let Inst{4} = 1; 635 let Inst{5} = 1; // H bit 636 let Inst{6} = 0; // S bit 637 let Inst{7} = 1; 638 let Inst{20} = 0; // L bit 639 let Inst{21} = 0; // W bit 640 let Inst{24} = 1; // P bit 641} 642class AI3std<dag oops, dag iops, Format f, InstrItinClass itin, 643 string opc, string asm, list<dag> pattern> 644 : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, itin, 645 opc, asm, "", pattern> { 646 let Inst{4} = 1; 647 let Inst{5} = 1; // H bit 648 let Inst{6} = 1; // S bit 649 let Inst{7} = 1; 650 let Inst{20} = 0; // L bit 651 let Inst{21} = 0; // W bit 652 let Inst{24} = 1; // P bit 653 let Inst{27-25} = 0b000; 654} 655 656// Pre-indexed loads 657class AI3ldhpr<dag oops, dag iops, Format f, InstrItinClass itin, 658 string opc, string asm, string cstr, list<dag> pattern> 659 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin, 660 opc, asm, cstr, pattern> { 661 let Inst{4} = 1; 662 let Inst{5} = 1; // H bit 663 let Inst{6} = 0; // S bit 664 let Inst{7} = 1; 665 let Inst{20} = 1; // L bit 666 let Inst{21} = 1; // W bit 667 let Inst{24} = 1; // P bit 668 let Inst{27-25} = 0b000; 669} 670class AI3ldshpr<dag oops, dag iops, Format f, InstrItinClass itin, 671 string opc, string asm, string cstr, list<dag> pattern> 672 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin, 673 opc, asm, cstr, pattern> { 674 let Inst{4} = 1; 675 let Inst{5} = 1; // H bit 676 let Inst{6} = 1; // S bit 677 let Inst{7} = 1; 678 let Inst{20} = 1; // L bit 679 let Inst{21} = 1; // W bit 680 let Inst{24} = 1; // P bit 681 let Inst{27-25} = 0b000; 682} 683class AI3ldsbpr<dag oops, dag iops, Format f, InstrItinClass itin, 684 string opc, string asm, string cstr, list<dag> pattern> 685 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin, 686 opc, asm, cstr, pattern> { 687 let Inst{4} = 1; 688 let Inst{5} = 0; // H bit 689 let Inst{6} = 1; // S bit 690 let Inst{7} = 1; 691 let Inst{20} = 1; // L bit 692 let Inst{21} = 1; // W bit 693 let Inst{24} = 1; // P bit 694 let Inst{27-25} = 0b000; 695} 696 697// Pre-indexed stores 698class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin, 699 string opc, string asm, string cstr, list<dag> pattern> 700 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, itin, 701 opc, asm, cstr, pattern> { 702 let Inst{4} = 1; 703 let Inst{5} = 1; // H bit 704 let Inst{6} = 0; // S bit 705 let Inst{7} = 1; 706 let Inst{20} = 0; // L bit 707 let Inst{21} = 1; // W bit 708 let Inst{24} = 1; // P bit 709 let Inst{27-25} = 0b000; 710} 711 712// Post-indexed loads 713class AI3ldhpo<dag oops, dag iops, Format f, InstrItinClass itin, 714 string opc, string asm, string cstr, list<dag> pattern> 715 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin, 716 opc, asm, cstr,pattern> { 717 let Inst{4} = 1; 718 let Inst{5} = 1; // H bit 719 let Inst{6} = 0; // S bit 720 let Inst{7} = 1; 721 let Inst{20} = 1; // L bit 722 let Inst{21} = 1; // W bit 723 let Inst{24} = 0; // P bit 724 let Inst{27-25} = 0b000; 725} 726class AI3ldshpo<dag oops, dag iops, Format f, InstrItinClass itin, 727 string opc, string asm, string cstr, list<dag> pattern> 728 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin, 729 opc, asm, cstr,pattern> { 730 let Inst{4} = 1; 731 let Inst{5} = 1; // H bit 732 let Inst{6} = 1; // S bit 733 let Inst{7} = 1; 734 let Inst{20} = 1; // L bit 735 let Inst{21} = 1; // W bit 736 let Inst{24} = 0; // P bit 737 let Inst{27-25} = 0b000; 738} 739class AI3ldsbpo<dag oops, dag iops, Format f, InstrItinClass itin, 740 string opc, string asm, string cstr, list<dag> pattern> 741 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin, 742 opc, asm, cstr,pattern> { 743 let Inst{4} = 1; 744 let Inst{5} = 0; // H bit 745 let Inst{6} = 1; // S bit 746 let Inst{7} = 1; 747 let Inst{20} = 1; // L bit 748 let Inst{21} = 1; // W bit 749 let Inst{24} = 0; // P bit 750 let Inst{27-25} = 0b000; 751} 752 753// Post-indexed stores 754class AI3sthpo<dag oops, dag iops, Format f, InstrItinClass itin, 755 string opc, string asm, string cstr, list<dag> pattern> 756 : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, itin, 757 opc, asm, cstr,pattern> { 758 let Inst{4} = 1; 759 let Inst{5} = 1; // H bit 760 let Inst{6} = 0; // S bit 761 let Inst{7} = 1; 762 let Inst{20} = 0; // L bit 763 let Inst{21} = 1; // W bit 764 let Inst{24} = 0; // P bit 765 let Inst{27-25} = 0b000; 766} 767 768 769// addrmode4 instructions 770class AXI4ld<dag oops, dag iops, Format f, InstrItinClass itin, 771 string asm, list<dag> pattern> 772 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin, 773 asm, "", pattern> { 774 let Inst{20} = 1; // L bit 775 let Inst{22} = 0; // S bit 776 let Inst{27-25} = 0b100; 777} 778class AXI4st<dag oops, dag iops, Format f, InstrItinClass itin, 779 string asm, list<dag> pattern> 780 : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin, 781 asm, "", pattern> { 782 let Inst{20} = 0; // L bit 783 let Inst{22} = 0; // S bit 784 let Inst{27-25} = 0b100; 785} 786 787// Unsigned multiply, multiply-accumulate instructions. 788class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 789 string opc, string asm, list<dag> pattern> 790 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin, 791 opc, asm, "", pattern> { 792 let Inst{7-4} = 0b1001; 793 let Inst{20} = 0; // S bit 794 let Inst{27-21} = opcod; 795} 796class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 797 string opc, string asm, list<dag> pattern> 798 : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin, 799 opc, asm, "", pattern> { 800 let Inst{7-4} = 0b1001; 801 let Inst{27-21} = opcod; 802} 803 804// Most significant word multiply 805class AMul2I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 806 string opc, string asm, list<dag> pattern> 807 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin, 808 opc, asm, "", pattern> { 809 let Inst{7-4} = 0b1001; 810 let Inst{20} = 1; 811 let Inst{27-21} = opcod; 812} 813 814// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y> 815class AMulxyI<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 816 string opc, string asm, list<dag> pattern> 817 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin, 818 opc, asm, "", pattern> { 819 let Inst{4} = 0; 820 let Inst{7} = 1; 821 let Inst{20} = 0; 822 let Inst{27-21} = opcod; 823} 824 825// Extend instructions. 826class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 827 string opc, string asm, list<dag> pattern> 828 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin, 829 opc, asm, "", pattern> { 830 let Inst{7-4} = 0b0111; 831 let Inst{27-20} = opcod; 832} 833 834// Misc Arithmetic instructions. 835class AMiscA1I<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 836 string opc, string asm, list<dag> pattern> 837 : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, itin, 838 opc, asm, "", pattern> { 839 let Inst{27-20} = opcod; 840} 841 842//===----------------------------------------------------------------------===// 843 844// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode. 845class ARMPat<dag pattern, dag result> : Pat<pattern, result> { 846 list<Predicate> Predicates = [IsARM]; 847} 848class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> { 849 list<Predicate> Predicates = [IsARM, HasV5TE]; 850} 851class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> { 852 list<Predicate> Predicates = [IsARM, HasV6]; 853} 854 855//===----------------------------------------------------------------------===// 856// 857// Thumb Instruction Format Definitions. 858// 859 860// TI - Thumb instruction. 861 862class ThumbI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 863 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 864 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 865 let OutOperandList = oops; 866 let InOperandList = iops; 867 let AsmString = asm; 868 let Pattern = pattern; 869 list<Predicate> Predicates = [IsThumb]; 870} 871 872class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 873 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>; 874 875// Two-address instructions 876class TIt<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 877 : ThumbI<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "$lhs = $dst", pattern>; 878 879// tBL, tBX instructions 880class TIx2<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 881 : ThumbI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>; 882 883// BR_JT instructions 884class TJTI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 885 : ThumbI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>; 886 887// Thumb1 only 888class Thumb1I<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 889 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 890 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 891 let OutOperandList = oops; 892 let InOperandList = iops; 893 let AsmString = asm; 894 let Pattern = pattern; 895 list<Predicate> Predicates = [IsThumb1Only]; 896} 897 898class T1I<dag oops, dag iops, InstrItinClass itin, 899 string asm, list<dag> pattern> 900 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, asm, "", pattern>; 901class T1Ix2<dag oops, dag iops, InstrItinClass itin, 902 string asm, list<dag> pattern> 903 : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>; 904class T1JTI<dag oops, dag iops, InstrItinClass itin, 905 string asm, list<dag> pattern> 906 : Thumb1I<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>; 907 908// Two-address instructions 909class T1It<dag oops, dag iops, InstrItinClass itin, 910 string asm, list<dag> pattern> 911 : Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin, 912 asm, "$lhs = $dst", pattern>; 913 914// Thumb1 instruction that can either be predicated or set CPSR. 915class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 916 InstrItinClass itin, 917 string opc, string asm, string cstr, list<dag> pattern> 918 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 919 let OutOperandList = !con(oops, (ops s_cc_out:$s)); 920 let InOperandList = !con(iops, (ops pred:$p)); 921 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); 922 let Pattern = pattern; 923 list<Predicate> Predicates = [IsThumb1Only]; 924} 925 926class T1sI<dag oops, dag iops, InstrItinClass itin, 927 string opc, string asm, list<dag> pattern> 928 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>; 929 930// Two-address instructions 931class T1sIt<dag oops, dag iops, InstrItinClass itin, 932 string opc, string asm, list<dag> pattern> 933 : Thumb1sI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, 934 "$lhs = $dst", pattern>; 935 936// Thumb1 instruction that can be predicated. 937class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 938 InstrItinClass itin, 939 string opc, string asm, string cstr, list<dag> pattern> 940 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 941 let OutOperandList = oops; 942 let InOperandList = !con(iops, (ops pred:$p)); 943 let AsmString = !strconcat(opc, !strconcat("${p}", asm)); 944 let Pattern = pattern; 945 list<Predicate> Predicates = [IsThumb1Only]; 946} 947 948class T1pI<dag oops, dag iops, InstrItinClass itin, 949 string opc, string asm, list<dag> pattern> 950 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, "", pattern>; 951 952// Two-address instructions 953class T1pIt<dag oops, dag iops, InstrItinClass itin, 954 string opc, string asm, list<dag> pattern> 955 : Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm, 956 "$lhs = $dst", pattern>; 957 958class T1pI1<dag oops, dag iops, InstrItinClass itin, 959 string opc, string asm, list<dag> pattern> 960 : Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, itin, opc, asm, "", pattern>; 961class T1pI2<dag oops, dag iops, InstrItinClass itin, 962 string opc, string asm, list<dag> pattern> 963 : Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, itin, opc, asm, "", pattern>; 964class T1pI4<dag oops, dag iops, InstrItinClass itin, 965 string opc, string asm, list<dag> pattern> 966 : Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, itin, opc, asm, "", pattern>; 967class T1pIs<dag oops, dag iops, 968 InstrItinClass itin, string opc, string asm, list<dag> pattern> 969 : Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, itin, opc, asm, "", pattern>; 970 971// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 972class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 973 InstrItinClass itin, 974 string opc, string asm, string cstr, list<dag> pattern> 975 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 976 let OutOperandList = oops; 977 let InOperandList = !con(iops, (ops pred:$p)); 978 let AsmString = !strconcat(opc, !strconcat("${p}", asm)); 979 let Pattern = pattern; 980 list<Predicate> Predicates = [IsThumb2]; 981} 982 983// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as 984// an input operand since by default it's a zero register. It will 985// become an implicit def once it's "flipped". 986// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 987// more consistent. 988class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 989 InstrItinClass itin, 990 string opc, string asm, string cstr, list<dag> pattern> 991 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 992 let OutOperandList = oops; 993 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s)); 994 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); 995 let Pattern = pattern; 996 list<Predicate> Predicates = [IsThumb2]; 997} 998 999// Special cases 1000class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 1001 InstrItinClass itin, 1002 string asm, string cstr, list<dag> pattern> 1003 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1004 let OutOperandList = oops; 1005 let InOperandList = iops; 1006 let AsmString = asm; 1007 let Pattern = pattern; 1008 list<Predicate> Predicates = [IsThumb2]; 1009} 1010 1011class ThumbXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 1012 InstrItinClass itin, 1013 string asm, string cstr, list<dag> pattern> 1014 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1015 let OutOperandList = oops; 1016 let InOperandList = iops; 1017 let AsmString = asm; 1018 let Pattern = pattern; 1019 list<Predicate> Predicates = [IsThumb1Only]; 1020} 1021 1022class T2I<dag oops, dag iops, InstrItinClass itin, 1023 string opc, string asm, list<dag> pattern> 1024 : Thumb2I<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>; 1025class T2Ii12<dag oops, dag iops, InstrItinClass itin, 1026 string opc, string asm, list<dag> pattern> 1027 : Thumb2I<oops, iops, AddrModeT2_i12, Size4Bytes, itin, opc, asm, "", pattern>; 1028class T2Ii8<dag oops, dag iops, InstrItinClass itin, 1029 string opc, string asm, list<dag> pattern> 1030 : Thumb2I<oops, iops, AddrModeT2_i8, Size4Bytes, itin, opc, asm, "", pattern>; 1031class T2Iso<dag oops, dag iops, InstrItinClass itin, 1032 string opc, string asm, list<dag> pattern> 1033 : Thumb2I<oops, iops, AddrModeT2_so, Size4Bytes, itin, opc, asm, "", pattern>; 1034class T2Ipc<dag oops, dag iops, InstrItinClass itin, 1035 string opc, string asm, list<dag> pattern> 1036 : Thumb2I<oops, iops, AddrModeT2_pc, Size4Bytes, itin, opc, asm, "", pattern>; 1037class T2Ii8s4<dag oops, dag iops, InstrItinClass itin, 1038 string opc, string asm, list<dag> pattern> 1039 : Thumb2I<oops, iops, AddrModeT2_i8s4, Size4Bytes, itin, opc, asm, "", pattern>; 1040 1041class T2sI<dag oops, dag iops, InstrItinClass itin, 1042 string opc, string asm, list<dag> pattern> 1043 : Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>; 1044 1045class T2XI<dag oops, dag iops, InstrItinClass itin, 1046 string asm, list<dag> pattern> 1047 : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>; 1048class T2JTI<dag oops, dag iops, InstrItinClass itin, 1049 string asm, list<dag> pattern> 1050 : Thumb2XI<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>; 1051 1052class T2Ix2<dag oops, dag iops, InstrItinClass itin, 1053 string opc, string asm, list<dag> pattern> 1054 : Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>; 1055 1056 1057// T2Iidxldst - Thumb2 indexed load / store instructions. 1058class T2Iidxldst<dag oops, dag iops, AddrMode am, IndexMode im, 1059 InstrItinClass itin, 1060 string opc, string asm, string cstr, list<dag> pattern> 1061 : InstARM<am, Size4Bytes, im, ThumbFrm, GenericDomain, cstr, itin> { 1062 let OutOperandList = oops; 1063 let InOperandList = !con(iops, (ops pred:$p)); 1064 let AsmString = !strconcat(opc, !strconcat("${p}", asm)); 1065 let Pattern = pattern; 1066 list<Predicate> Predicates = [IsThumb2]; 1067} 1068 1069// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. 1070class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> { 1071 list<Predicate> Predicates = [IsThumb1Only, HasV5T]; 1072} 1073 1074// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 1075class T1Pat<dag pattern, dag result> : Pat<pattern, result> { 1076 list<Predicate> Predicates = [IsThumb1Only]; 1077} 1078 1079// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 1080class T2Pat<dag pattern, dag result> : Pat<pattern, result> { 1081 list<Predicate> Predicates = [IsThumb2]; 1082} 1083 1084//===----------------------------------------------------------------------===// 1085 1086//===----------------------------------------------------------------------===// 1087// ARM VFP Instruction templates. 1088// 1089 1090// Almost all VFP instructions are predicable. 1091class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 1092 IndexMode im, Format f, InstrItinClass itin, 1093 string opc, string asm, string cstr, list<dag> pattern> 1094 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1095 let OutOperandList = oops; 1096 let InOperandList = !con(iops, (ops pred:$p)); 1097 let AsmString = !strconcat(opc, !strconcat("${p}", asm)); 1098 let Pattern = pattern; 1099 list<Predicate> Predicates = [HasVFP2]; 1100} 1101 1102// Special cases 1103class VFPXI<dag oops, dag iops, AddrMode am, SizeFlagVal sz, 1104 IndexMode im, Format f, InstrItinClass itin, 1105 string asm, string cstr, list<dag> pattern> 1106 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1107 let OutOperandList = oops; 1108 let InOperandList = iops; 1109 let AsmString = asm; 1110 let Pattern = pattern; 1111 list<Predicate> Predicates = [HasVFP2]; 1112} 1113 1114class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 1115 string opc, string asm, list<dag> pattern> 1116 : VFPI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, itin, 1117 opc, asm, "", pattern>; 1118 1119// ARM VFP addrmode5 loads and stores 1120class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1121 InstrItinClass itin, 1122 string opc, string asm, list<dag> pattern> 1123 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone, 1124 VFPLdStFrm, itin, opc, asm, "", pattern> { 1125 // TODO: Mark the instructions with the appropriate subtarget info. 1126 let Inst{27-24} = opcod1; 1127 let Inst{21-20} = opcod2; 1128 let Inst{11-8} = 0b1011; 1129 1130 // 64-bit loads & stores operate on both NEON and VFP pipelines. 1131 let Dom = VFPNeonDomain.Value; 1132} 1133 1134class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1135 InstrItinClass itin, 1136 string opc, string asm, list<dag> pattern> 1137 : VFPI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone, 1138 VFPLdStFrm, itin, opc, asm, "", pattern> { 1139 // TODO: Mark the instructions with the appropriate subtarget info. 1140 let Inst{27-24} = opcod1; 1141 let Inst{21-20} = opcod2; 1142 let Inst{11-8} = 0b1010; 1143} 1144 1145// Load / store multiple 1146class AXDI5<dag oops, dag iops, InstrItinClass itin, 1147 string asm, list<dag> pattern> 1148 : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone, 1149 VFPLdStMulFrm, itin, asm, "", pattern> { 1150 // TODO: Mark the instructions with the appropriate subtarget info. 1151 let Inst{27-25} = 0b110; 1152 let Inst{11-8} = 0b1011; 1153 1154 // 64-bit loads & stores operate on both NEON and VFP pipelines. 1155 let Dom = VFPNeonDomain.Value; 1156} 1157 1158class AXSI5<dag oops, dag iops, InstrItinClass itin, 1159 string asm, list<dag> pattern> 1160 : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone, 1161 VFPLdStMulFrm, itin, asm, "", pattern> { 1162 // TODO: Mark the instructions with the appropriate subtarget info. 1163 let Inst{27-25} = 0b110; 1164 let Inst{11-8} = 0b1010; 1165} 1166 1167// Double precision, unary 1168class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, 1169 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1170 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1171 let Inst{27-20} = opcod1; 1172 let Inst{19-16} = opcod2; 1173 let Inst{11-8} = 0b1011; 1174 let Inst{7-4} = opcod3; 1175} 1176 1177// Double precision, binary 1178class ADbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 1179 string opc, string asm, list<dag> pattern> 1180 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1181 let Inst{27-20} = opcod; 1182 let Inst{11-8} = 0b1011; 1183} 1184 1185// Single precision, unary 1186class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, 1187 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1188 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1189 // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding. 1190 let Inst{27-20} = opcod1; 1191 let Inst{19-16} = opcod2; 1192 let Inst{11-8} = 0b1010; 1193 let Inst{7-4} = opcod3; 1194} 1195 1196// Single precision unary, if no NEON 1197// Same as ASuI except not available if NEON is enabled 1198class ASuIn<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, 1199 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1200 : ASuI<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> { 1201 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1202} 1203 1204// Single precision, binary 1205class ASbI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 1206 string opc, string asm, list<dag> pattern> 1207 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1208 // Bit 22 (D bit) can be changed during instruction encoding. 1209 let Inst{27-20} = opcod; 1210 let Inst{11-8} = 0b1010; 1211} 1212 1213// Single precision binary, if no NEON 1214// Same as ASbI except not available if NEON is enabled 1215class ASbIn<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 1216 string opc, string asm, list<dag> pattern> 1217 : ASbI<opcod, oops, iops, itin, opc, asm, pattern> { 1218 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1219} 1220 1221// VFP conversion instructions 1222class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, 1223 dag oops, dag iops, InstrItinClass itin, 1224 string opc, string asm, list<dag> pattern> 1225 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> { 1226 let Inst{27-20} = opcod1; 1227 let Inst{19-16} = opcod2; 1228 let Inst{11-8} = opcod3; 1229 let Inst{6} = 1; 1230} 1231 1232// VFP conversion instructions, if no NEON 1233class AVConv1In<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, 1234 dag oops, dag iops, InstrItinClass itin, 1235 string opc, string asm, list<dag> pattern> 1236 : AVConv1I<opcod1, opcod2, opcod3, oops, iops, itin, opc, asm, pattern> { 1237 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1238} 1239 1240class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 1241 InstrItinClass itin, 1242 string opc, string asm, list<dag> pattern> 1243 : VFPAI<oops, iops, f, itin, opc, asm, pattern> { 1244 let Inst{27-20} = opcod1; 1245 let Inst{11-8} = opcod2; 1246 let Inst{4} = 1; 1247} 1248 1249class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1250 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1251 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>; 1252 1253class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1254 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1255 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>; 1256 1257class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1258 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1259 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>; 1260 1261class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1262 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1263 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 1264 1265//===----------------------------------------------------------------------===// 1266 1267//===----------------------------------------------------------------------===// 1268// ARM NEON Instruction templates. 1269// 1270 1271class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin, 1272 string opc, string dt, string asm, string cstr, list<dag> pattern> 1273 : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> { 1274 let OutOperandList = oops; 1275 let InOperandList = !con(iops, (ops pred:$p)); 1276 let AsmString = !strconcat( 1277 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)), 1278 !strconcat("\t", asm)); 1279 let Pattern = pattern; 1280 list<Predicate> Predicates = [HasNEON]; 1281} 1282 1283// Same as NeonI except it does not have a "data type" specifier. 1284class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin, 1285 string opc, string asm, string cstr, list<dag> pattern> 1286 : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> { 1287 let OutOperandList = oops; 1288 let InOperandList = !con(iops, (ops pred:$p)); 1289 let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm)); 1290 let Pattern = pattern; 1291 list<Predicate> Predicates = [HasNEON]; 1292} 1293 1294class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm, 1295 list<dag> pattern> 1296 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, "", 1297 pattern> { 1298} 1299 1300class NI4<dag oops, dag iops, InstrItinClass itin, string opc, 1301 string asm, list<dag> pattern> 1302 : NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "", 1303 pattern> { 1304} 1305 1306class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 1307 dag oops, dag iops, InstrItinClass itin, 1308 string opc, string dt, string asm, string cstr, list<dag> pattern> 1309 : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, dt, asm, cstr, 1310 pattern> { 1311 let Inst{31-24} = 0b11110100; 1312 let Inst{23} = op23; 1313 let Inst{21-20} = op21_20; 1314 let Inst{11-8} = op11_8; 1315 let Inst{7-4} = op7_4; 1316} 1317 1318class NDataI<dag oops, dag iops, InstrItinClass itin, 1319 string opc, string dt, string asm, string cstr, list<dag> pattern> 1320 : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, dt, asm, 1321 cstr, pattern> { 1322 let Inst{31-25} = 0b1111001; 1323} 1324 1325class NDataXI<dag oops, dag iops, InstrItinClass itin, 1326 string opc, string asm, string cstr, list<dag> pattern> 1327 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, 1328 cstr, pattern> { 1329 let Inst{31-25} = 0b1111001; 1330} 1331 1332// NEON "one register and a modified immediate" format. 1333class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 1334 bit op5, bit op4, 1335 dag oops, dag iops, InstrItinClass itin, 1336 string opc, string dt, string asm, string cstr, list<dag> pattern> 1337 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> { 1338 let Inst{23} = op23; 1339 let Inst{21-19} = op21_19; 1340 let Inst{11-8} = op11_8; 1341 let Inst{7} = op7; 1342 let Inst{6} = op6; 1343 let Inst{5} = op5; 1344 let Inst{4} = op4; 1345} 1346 1347// NEON 2 vector register format. 1348class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 1349 bits<5> op11_7, bit op6, bit op4, 1350 dag oops, dag iops, InstrItinClass itin, 1351 string opc, string dt, string asm, string cstr, list<dag> pattern> 1352 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> { 1353 let Inst{24-23} = op24_23; 1354 let Inst{21-20} = op21_20; 1355 let Inst{19-18} = op19_18; 1356 let Inst{17-16} = op17_16; 1357 let Inst{11-7} = op11_7; 1358 let Inst{6} = op6; 1359 let Inst{4} = op4; 1360} 1361 1362// Same as N2V except it doesn't have a datatype suffix. 1363class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 1364 bits<5> op11_7, bit op6, bit op4, 1365 dag oops, dag iops, InstrItinClass itin, 1366 string opc, string asm, string cstr, list<dag> pattern> 1367 : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> { 1368 let Inst{24-23} = op24_23; 1369 let Inst{21-20} = op21_20; 1370 let Inst{19-18} = op19_18; 1371 let Inst{17-16} = op17_16; 1372 let Inst{11-7} = op11_7; 1373 let Inst{6} = op6; 1374 let Inst{4} = op4; 1375} 1376 1377// NEON 2 vector register with immediate. 1378class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 1379 dag oops, dag iops, InstrItinClass itin, 1380 string opc, string dt, string asm, string cstr, list<dag> pattern> 1381 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> { 1382 let Inst{24} = op24; 1383 let Inst{23} = op23; 1384 let Inst{11-8} = op11_8; 1385 let Inst{7} = op7; 1386 let Inst{6} = op6; 1387 let Inst{4} = op4; 1388} 1389 1390// NEON 3 vector register format. 1391class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 1392 dag oops, dag iops, InstrItinClass itin, 1393 string opc, string dt, string asm, string cstr, list<dag> pattern> 1394 : NDataI<oops, iops, itin, opc, dt, asm, cstr, pattern> { 1395 let Inst{24} = op24; 1396 let Inst{23} = op23; 1397 let Inst{21-20} = op21_20; 1398 let Inst{11-8} = op11_8; 1399 let Inst{6} = op6; 1400 let Inst{4} = op4; 1401} 1402 1403// Same as N3VX except it doesn't have a data type suffix. 1404class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 1405 dag oops, dag iops, InstrItinClass itin, 1406 string opc, string asm, string cstr, list<dag> pattern> 1407 : NDataXI<oops, iops, itin, opc, asm, cstr, pattern> { 1408 let Inst{24} = op24; 1409 let Inst{23} = op23; 1410 let Inst{21-20} = op21_20; 1411 let Inst{11-8} = op11_8; 1412 let Inst{6} = op6; 1413 let Inst{4} = op4; 1414} 1415 1416// NEON VMOVs between scalar and core registers. 1417class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 1418 dag oops, dag iops, Format f, InstrItinClass itin, 1419 string opc, string dt, string asm, list<dag> pattern> 1420 : InstARM<AddrModeNone, Size4Bytes, IndexModeNone, f, GenericDomain, 1421 "", itin> { 1422 let Inst{27-20} = opcod1; 1423 let Inst{11-8} = opcod2; 1424 let Inst{6-5} = opcod3; 1425 let Inst{4} = 1; 1426 1427 let OutOperandList = oops; 1428 let InOperandList = !con(iops, (ops pred:$p)); 1429 let AsmString = !strconcat( 1430 !strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)), 1431 !strconcat("\t", asm)); 1432 let Pattern = pattern; 1433 list<Predicate> Predicates = [HasNEON]; 1434} 1435class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 1436 dag oops, dag iops, InstrItinClass itin, 1437 string opc, string dt, string asm, list<dag> pattern> 1438 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, itin, 1439 opc, dt, asm, pattern>; 1440class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 1441 dag oops, dag iops, InstrItinClass itin, 1442 string opc, string dt, string asm, list<dag> pattern> 1443 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, itin, 1444 opc, dt, asm, pattern>; 1445class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 1446 dag oops, dag iops, InstrItinClass itin, 1447 string opc, string dt, string asm, list<dag> pattern> 1448 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, itin, 1449 opc, dt, asm, pattern>; 1450 1451// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 1452// for single-precision FP. 1453class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 1454 list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 1455} 1456