1//===-- ARMInstrFormats.td - ARM 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// ARM Instruction Format Definitions. 12// 13 14// Format specifies the encoding used by the instruction. This is part of the 15// ad-hoc solution used to emit machine instruction encodings by our machine 16// code emitter. 17class Format<bits<6> val> { 18 bits<6> Value = val; 19} 20 21def Pseudo : Format<0>; 22def MulFrm : Format<1>; 23def BrFrm : Format<2>; 24def BrMiscFrm : Format<3>; 25 26def DPFrm : Format<4>; 27def DPSoRegRegFrm : Format<5>; 28 29def LdFrm : Format<6>; 30def StFrm : Format<7>; 31def LdMiscFrm : Format<8>; 32def StMiscFrm : Format<9>; 33def LdStMulFrm : Format<10>; 34 35def LdStExFrm : Format<11>; 36 37def ArithMiscFrm : Format<12>; 38def SatFrm : Format<13>; 39def ExtFrm : Format<14>; 40 41def VFPUnaryFrm : Format<15>; 42def VFPBinaryFrm : Format<16>; 43def VFPConv1Frm : Format<17>; 44def VFPConv2Frm : Format<18>; 45def VFPConv3Frm : Format<19>; 46def VFPConv4Frm : Format<20>; 47def VFPConv5Frm : Format<21>; 48def VFPLdStFrm : Format<22>; 49def VFPLdStMulFrm : Format<23>; 50def VFPMiscFrm : Format<24>; 51 52def ThumbFrm : Format<25>; 53def MiscFrm : Format<26>; 54 55def NGetLnFrm : Format<27>; 56def NSetLnFrm : Format<28>; 57def NDupFrm : Format<29>; 58def NLdStFrm : Format<30>; 59def N1RegModImmFrm: Format<31>; 60def N2RegFrm : Format<32>; 61def NVCVTFrm : Format<33>; 62def NVDupLnFrm : Format<34>; 63def N2RegVShLFrm : Format<35>; 64def N2RegVShRFrm : Format<36>; 65def N3RegFrm : Format<37>; 66def N3RegVShFrm : Format<38>; 67def NVExtFrm : Format<39>; 68def NVMulSLFrm : Format<40>; 69def NVTBLFrm : Format<41>; 70def DPSoRegImmFrm : Format<42>; 71def N3RegCplxFrm : Format<43>; 72 73// Misc flags. 74 75// The instruction has an Rn register operand. 76// UnaryDP - Indicates this is a unary data processing instruction, i.e. 77// it doesn't have a Rn operand. 78class UnaryDP { bit isUnaryDataProc = 1; } 79 80// Xform16Bit - Indicates this Thumb2 instruction may be transformed into 81// a 16-bit Thumb instruction if certain conditions are met. 82class Xform16Bit { bit canXformTo16Bit = 1; } 83 84//===----------------------------------------------------------------------===// 85// ARM Instruction flags. These need to match ARMBaseInstrInfo.h. 86// 87 88// FIXME: Once the JIT is MC-ized, these can go away. 89// Addressing mode. 90class AddrMode<bits<5> val> { 91 bits<5> Value = val; 92} 93def AddrModeNone : AddrMode<0>; 94def AddrMode1 : AddrMode<1>; 95def AddrMode2 : AddrMode<2>; 96def AddrMode3 : AddrMode<3>; 97def AddrMode4 : AddrMode<4>; 98def AddrMode5 : AddrMode<5>; 99def AddrMode6 : AddrMode<6>; 100def AddrModeT1_1 : AddrMode<7>; 101def AddrModeT1_2 : AddrMode<8>; 102def AddrModeT1_4 : AddrMode<9>; 103def AddrModeT1_s : AddrMode<10>; 104def AddrModeT2_i12 : AddrMode<11>; 105def AddrModeT2_i8 : AddrMode<12>; 106def AddrModeT2_so : AddrMode<13>; 107def AddrModeT2_pc : AddrMode<14>; 108def AddrModeT2_i8s4 : AddrMode<15>; 109def AddrMode_i12 : AddrMode<16>; 110def AddrMode5FP16 : AddrMode<17>; 111def AddrModeT2_ldrex : AddrMode<18>; 112def AddrModeT2_i7s4 : AddrMode<19>; 113def AddrModeT2_i7s2 : AddrMode<20>; 114def AddrModeT2_i7 : AddrMode<21>; 115 116// Load / store index mode. 117class IndexMode<bits<2> val> { 118 bits<2> Value = val; 119} 120def IndexModeNone : IndexMode<0>; 121def IndexModePre : IndexMode<1>; 122def IndexModePost : IndexMode<2>; 123def IndexModeUpd : IndexMode<3>; 124 125// Instruction execution domain. 126class Domain<bits<4> val> { 127 bits<4> Value = val; 128} 129def GenericDomain : Domain<0>; 130def VFPDomain : Domain<1>; // Instructions in VFP domain only 131def NeonDomain : Domain<2>; // Instructions in Neon domain only 132def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains 133def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8 134def MVEDomain : Domain<8>; // Instructions in MVE and ARMv8.1m 135 136//===----------------------------------------------------------------------===// 137// ARM special operands. 138// 139 140// ARM imod and iflag operands, used only by the CPS instruction. 141def imod_op : Operand<i32> { 142 let PrintMethod = "printCPSIMod"; 143} 144 145def ProcIFlagsOperand : AsmOperandClass { 146 let Name = "ProcIFlags"; 147 let ParserMethod = "parseProcIFlagsOperand"; 148} 149def iflags_op : Operand<i32> { 150 let PrintMethod = "printCPSIFlag"; 151 let ParserMatchClass = ProcIFlagsOperand; 152} 153 154// ARM Predicate operand. Default to 14 = always (AL). Second part is CC 155// register whose default is 0 (no register). 156def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; } 157def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), 158 (ops (i32 14), (i32 zero_reg))> { 159 let PrintMethod = "printPredicateOperand"; 160 let ParserMatchClass = CondCodeOperand; 161 let DecoderMethod = "DecodePredicateOperand"; 162} 163 164// Selectable predicate operand for CMOV instructions. We can't use a normal 165// predicate because the default values interfere with instruction selection. In 166// all other respects it is identical though: pseudo-instruction expansion 167// relies on the MachineOperands being compatible. 168def cmovpred : Operand<i32>, PredicateOp, 169 ComplexPattern<i32, 2, "SelectCMOVPred"> { 170 let MIOperandInfo = (ops i32imm, i32imm); 171 let PrintMethod = "printPredicateOperand"; 172} 173 174// Conditional code result for instructions whose 's' bit is set, e.g. subs. 175def CCOutOperand : AsmOperandClass { let Name = "CCOut"; } 176def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> { 177 let EncoderMethod = "getCCOutOpValue"; 178 let PrintMethod = "printSBitModifierOperand"; 179 let ParserMatchClass = CCOutOperand; 180 let DecoderMethod = "DecodeCCOutOperand"; 181} 182 183// Same as cc_out except it defaults to setting CPSR. 184def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> { 185 let EncoderMethod = "getCCOutOpValue"; 186 let PrintMethod = "printSBitModifierOperand"; 187 let ParserMatchClass = CCOutOperand; 188 let DecoderMethod = "DecodeCCOutOperand"; 189} 190 191// Transform to generate the inverse of a condition code during ISel 192def inv_cond_XFORM : SDNodeXForm<imm, [{ 193 ARMCC::CondCodes CC = static_cast<ARMCC::CondCodes>(N->getZExtValue()); 194 return CurDAG->getTargetConstant(ARMCC::getOppositeCondition(CC), SDLoc(N), 195 MVT::i32); 196}]>; 197 198// VPT predicate 199 200def VPTPredNOperand : AsmOperandClass { 201 let Name = "VPTPredN"; 202 let PredicateMethod = "isVPTPred"; 203} 204def VPTPredROperand : AsmOperandClass { 205 let Name = "VPTPredR"; 206 let PredicateMethod = "isVPTPred"; 207} 208 209// Operand classes for the cluster of MC operands describing a 210// VPT-predicated MVE instruction. 211// 212// There are two of these classes. Both of them have the same first 213// two options: 214// 215// $cond (an integer) indicates the instruction's predication status: 216// * ARMVCC::None means it's unpredicated 217// * ARMVCC::Then means it's in a VPT block and appears with the T suffix 218// * ARMVCC::Else means it's in a VPT block and appears with the E suffix. 219// During code generation, unpredicated and predicated instructions 220// are indicated by setting this parameter to 'None' or to 'Then'; the 221// third value 'Else' is only used for assembly and disassembly. 222// 223// $cond_reg (type VCCR) gives the input predicate register. This is 224// always either zero_reg or VPR, but needs to be modelled as an 225// explicit operand so that it can be register-allocated and spilled 226// when these operands are used in code generation). 227// 228// For 'vpred_r', there's an extra operand $inactive, which specifies 229// the vector register which will supply any lanes of the output 230// register that the predication mask prevents from being written by 231// this instruction. It's always tied to the actual output register 232// (i.e. must be allocated into the same physical reg), but again, 233// code generation will need to model it as a separate input value. 234// 235// 'vpred_n' doesn't have that extra operand: it only has $cond and 236// $cond_reg. This variant is used for any instruction that can't, or 237// doesn't want to, tie $inactive to the output register. Sometimes 238// that's because another input parameter is already tied to it (e.g. 239// instructions that both read and write their Qd register even when 240// unpredicated, either because they only partially overwrite it like 241// a narrowing integer conversion, or simply because the instruction 242// encoding doesn't have enough register fields to make the output 243// independent of all inputs). It can also be because the instruction 244// is defined to set disabled output lanes to zero rather than leaving 245// them unchanged (vector loads), or because it doesn't output a 246// vector register at all (stores, compares). In any of these 247// situations it's unnecessary to have an extra operand tied to the 248// output, and inconvenient to leave it there unused. 249 250// Base class for both kinds of vpred. 251class vpred_ops<dag extra_op, dag extra_mi> : OperandWithDefaultOps<OtherVT, 252 !con((ops (i32 0), (i32 zero_reg), (i32 zero_reg)), extra_op)> { 253 let PrintMethod = "printVPTPredicateOperand"; 254 let OperandNamespace = "ARM"; 255 let MIOperandInfo = !con((ops i32imm:$cond, VCCR:$cond_reg, GPRlr:$tp_reg), extra_mi); 256 257 // For convenience, we provide a string value that can be appended 258 // to the constraints string. It's empty for vpred_n, and for 259 // vpred_r it ties the $inactive operand to the output q-register 260 // (which by convention will be called $Qd). 261 string vpred_constraint; 262} 263 264def vpred_r : vpred_ops<(ops (v4i32 undef_tied_input)), (ops MQPR:$inactive)> { 265 let ParserMatchClass = VPTPredROperand; 266 let OperandType = "OPERAND_VPRED_R"; 267 let DecoderMethod = "DecodeVpredROperand"; 268 let vpred_constraint = ",$Qd = $vp.inactive"; 269} 270 271def vpred_n : vpred_ops<(ops), (ops)> { 272 let ParserMatchClass = VPTPredNOperand; 273 let OperandType = "OPERAND_VPRED_N"; 274 let vpred_constraint = ""; 275} 276 277// ARM special operands for disassembly only. 278// 279def SetEndAsmOperand : ImmAsmOperand<0,1> { 280 let Name = "SetEndImm"; 281 let ParserMethod = "parseSetEndImm"; 282} 283def setend_op : Operand<i32> { 284 let PrintMethod = "printSetendOperand"; 285 let ParserMatchClass = SetEndAsmOperand; 286} 287 288def MSRMaskOperand : AsmOperandClass { 289 let Name = "MSRMask"; 290 let ParserMethod = "parseMSRMaskOperand"; 291} 292def msr_mask : Operand<i32> { 293 let PrintMethod = "printMSRMaskOperand"; 294 let DecoderMethod = "DecodeMSRMask"; 295 let ParserMatchClass = MSRMaskOperand; 296} 297 298def BankedRegOperand : AsmOperandClass { 299 let Name = "BankedReg"; 300 let ParserMethod = "parseBankedRegOperand"; 301} 302def banked_reg : Operand<i32> { 303 let PrintMethod = "printBankedRegOperand"; 304 let DecoderMethod = "DecodeBankedReg"; 305 let ParserMatchClass = BankedRegOperand; 306} 307 308// Shift Right Immediate - A shift right immediate is encoded differently from 309// other shift immediates. The imm6 field is encoded like so: 310// 311// Offset Encoding 312// 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0> 313// 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0> 314// 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0> 315// 64 64 - <imm> is encoded in imm6<5:0> 316def shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; } 317def shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> { 318 let EncoderMethod = "getShiftRight8Imm"; 319 let DecoderMethod = "DecodeShiftRight8Imm"; 320 let ParserMatchClass = shr_imm8_asm_operand; 321} 322def shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; } 323def shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> { 324 let EncoderMethod = "getShiftRight16Imm"; 325 let DecoderMethod = "DecodeShiftRight16Imm"; 326 let ParserMatchClass = shr_imm16_asm_operand; 327} 328def shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; } 329def shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> { 330 let EncoderMethod = "getShiftRight32Imm"; 331 let DecoderMethod = "DecodeShiftRight32Imm"; 332 let ParserMatchClass = shr_imm32_asm_operand; 333} 334def shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; } 335def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> { 336 let EncoderMethod = "getShiftRight64Imm"; 337 let DecoderMethod = "DecodeShiftRight64Imm"; 338 let ParserMatchClass = shr_imm64_asm_operand; 339} 340 341 342// ARM Assembler operand for ldr Rd, =expression which generates an offset 343// to a constant pool entry or a MOV depending on the value of expression 344def const_pool_asm_operand : AsmOperandClass { let Name = "ConstPoolAsmImm"; } 345def const_pool_asm_imm : Operand<i32> { 346 let ParserMatchClass = const_pool_asm_operand; 347} 348 349 350//===----------------------------------------------------------------------===// 351// ARM Assembler alias templates. 352// 353// Note: When EmitPriority == 1, the alias will be used for printing 354class ARMInstAlias<string Asm, dag Result, bit EmitPriority = 0> 355 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsARM]>; 356class ARMInstSubst<string Asm, dag Result, bit EmitPriority = 0> 357 : InstAlias<Asm, Result, EmitPriority>, 358 Requires<[IsARM,UseNegativeImmediates]>; 359class tInstAlias<string Asm, dag Result, bit EmitPriority = 0> 360 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb]>; 361class tInstSubst<string Asm, dag Result, bit EmitPriority = 0> 362 : InstAlias<Asm, Result, EmitPriority>, 363 Requires<[IsThumb,UseNegativeImmediates]>; 364class t2InstAlias<string Asm, dag Result, bit EmitPriority = 0> 365 : InstAlias<Asm, Result, EmitPriority>, Requires<[IsThumb2]>; 366class t2InstSubst<string Asm, dag Result, bit EmitPriority = 0> 367 : InstAlias<Asm, Result, EmitPriority>, 368 Requires<[IsThumb2,UseNegativeImmediates]>; 369class VFP2InstAlias<string Asm, dag Result, bit EmitPriority = 0> 370 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2]>; 371class VFP2DPInstAlias<string Asm, dag Result, bit EmitPriority = 0> 372 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP2,HasDPVFP]>; 373class VFP3InstAlias<string Asm, dag Result, bit EmitPriority = 0> 374 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasVFP3]>; 375class NEONInstAlias<string Asm, dag Result, bit EmitPriority = 0> 376 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasNEON]>; 377class MVEInstAlias<string Asm, dag Result, bit EmitPriority = 1> 378 : InstAlias<Asm, Result, EmitPriority>, Requires<[HasMVEInt, IsThumb]>; 379 380 381class VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 382 Requires<[HasVFP2]>; 383class NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 384 Requires<[HasNEON]>; 385 386//===----------------------------------------------------------------------===// 387// ARM Instruction templates. 388// 389 390 391class InstTemplate<AddrMode am, int sz, IndexMode im, 392 Format f, Domain d, string cstr, InstrItinClass itin> 393 : Instruction { 394 let Namespace = "ARM"; 395 396 AddrMode AM = am; 397 int Size = sz; 398 IndexMode IM = im; 399 bits<2> IndexModeBits = IM.Value; 400 Format F = f; 401 bits<6> Form = F.Value; 402 Domain D = d; 403 bit isUnaryDataProc = 0; 404 bit canXformTo16Bit = 0; 405 // The instruction is a 16-bit flag setting Thumb instruction. Used 406 // by the parser and if-converter to determine whether to require the 'S' 407 // suffix on the mnemonic (when not in an IT block) or preclude it (when 408 // in an IT block). 409 bit thumbArithFlagSetting = 0; 410 411 bits<2> VecSize = 0; 412 bit validForTailPredication = 0; 413 bit retainsPreviousHalfElement = 0; 414 bit horizontalReduction = 0; 415 bit doubleWidthResult = 0; 416 417 // If this is a pseudo instruction, mark it isCodeGenOnly. 418 let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo"); 419 420 // The layout of TSFlags should be kept in sync with ARMBaseInfo.h. 421 let TSFlags{4-0} = AM.Value; 422 let TSFlags{6-5} = IndexModeBits; 423 let TSFlags{12-7} = Form; 424 let TSFlags{13} = isUnaryDataProc; 425 let TSFlags{14} = canXformTo16Bit; 426 let TSFlags{18-15} = D.Value; 427 let TSFlags{19} = thumbArithFlagSetting; 428 let TSFlags{20} = validForTailPredication; 429 let TSFlags{21} = retainsPreviousHalfElement; 430 let TSFlags{22} = horizontalReduction; 431 let TSFlags{23} = doubleWidthResult; 432 let TSFlags{25-24} = VecSize; 433 434 let Constraints = cstr; 435 let Itinerary = itin; 436} 437 438class Encoding { 439 field bits<32> Inst; 440 // Mask of bits that cause an encoding to be UNPREDICTABLE. 441 // If a bit is set, then if the corresponding bit in the 442 // target encoding differs from its value in the "Inst" field, 443 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 444 field bits<32> Unpredictable = 0; 445 // SoftFail is the generic name for this field, but we alias it so 446 // as to make it more obvious what it means in ARM-land. 447 field bits<32> SoftFail = Unpredictable; 448} 449 450class InstARM<AddrMode am, int sz, IndexMode im, 451 Format f, Domain d, string cstr, InstrItinClass itin> 452 : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding { 453 let DecoderNamespace = "ARM"; 454} 455 456// This Encoding-less class is used by Thumb1 to specify the encoding bits later 457// on by adding flavors to specific instructions. 458class InstThumb<AddrMode am, int sz, IndexMode im, 459 Format f, Domain d, string cstr, InstrItinClass itin> 460 : InstTemplate<am, sz, im, f, d, cstr, itin> { 461 let DecoderNamespace = "Thumb"; 462} 463 464// Pseudo-instructions for alternate assembly syntax (never used by codegen). 465// These are aliases that require C++ handling to convert to the target 466// instruction, while InstAliases can be handled directly by tblgen. 467class AsmPseudoInst<string asm, dag iops, dag oops = (outs)> 468 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, 469 "", NoItinerary> { 470 let OutOperandList = oops; 471 let InOperandList = iops; 472 let Pattern = []; 473 let isCodeGenOnly = 0; // So we get asm matcher for it. 474 let AsmString = asm; 475 let isPseudo = 1; 476 let hasNoSchedulingInfo = 1; 477} 478 479class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)> 480 : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>; 481class tAsmPseudo<string asm, dag iops, dag oops = (outs)> 482 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>; 483class t2AsmPseudo<string asm, dag iops, dag oops = (outs)> 484 : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>; 485class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)> 486 : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>; 487class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)> 488 : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>; 489class MVEAsmPseudo<string asm, dag iops, dag oops = (outs)> 490 : AsmPseudoInst<asm, iops, oops>, Requires<[HasMVEInt]>; 491 492// Pseudo instructions for the code generator. 493class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern> 494 : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, 495 GenericDomain, "", itin> { 496 let OutOperandList = oops; 497 let InOperandList = iops; 498 let Pattern = pattern; 499 let isCodeGenOnly = 1; 500 let isPseudo = 1; 501} 502 503// PseudoInst that's ARM-mode only. 504class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 505 list<dag> pattern> 506 : PseudoInst<oops, iops, itin, pattern> { 507 let Size = sz; 508 list<Predicate> Predicates = [IsARM]; 509} 510 511// PseudoInst that's Thumb-mode only. 512class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 513 list<dag> pattern> 514 : PseudoInst<oops, iops, itin, pattern> { 515 let Size = sz; 516 list<Predicate> Predicates = [IsThumb]; 517} 518 519// PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2) 520class t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 521 list<dag> pattern> 522 : PseudoInst<oops, iops, itin, pattern> { 523 let Size = sz; 524 list<Predicate> Predicates = [IsThumb,HasV8MBaseline]; 525} 526 527// PseudoInst that's Thumb2-mode only. 528class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 529 list<dag> pattern> 530 : PseudoInst<oops, iops, itin, pattern> { 531 let Size = sz; 532 list<Predicate> Predicates = [IsThumb2]; 533} 534 535class ARMPseudoExpand<dag oops, dag iops, int sz, 536 InstrItinClass itin, list<dag> pattern, 537 dag Result> 538 : ARMPseudoInst<oops, iops, sz, itin, pattern>, 539 PseudoInstExpansion<Result>; 540 541class tPseudoExpand<dag oops, dag iops, int sz, 542 InstrItinClass itin, list<dag> pattern, 543 dag Result> 544 : tPseudoInst<oops, iops, sz, itin, pattern>, 545 PseudoInstExpansion<Result>; 546 547class t2PseudoExpand<dag oops, dag iops, int sz, 548 InstrItinClass itin, list<dag> pattern, 549 dag Result> 550 : t2PseudoInst<oops, iops, sz, itin, pattern>, 551 PseudoInstExpansion<Result>; 552 553// Almost all ARM instructions are predicable. 554class I<dag oops, dag iops, AddrMode am, int sz, 555 IndexMode im, Format f, InstrItinClass itin, 556 string opc, string asm, string cstr, 557 list<dag> pattern> 558 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 559 bits<4> p; 560 let Inst{31-28} = p; 561 let OutOperandList = oops; 562 let InOperandList = !con(iops, (ins pred:$p)); 563 let AsmString = !strconcat(opc, "${p}", asm); 564 let Pattern = pattern; 565 list<Predicate> Predicates = [IsARM]; 566} 567 568// A few are not predicable 569class InoP<dag oops, dag iops, AddrMode am, int sz, 570 IndexMode im, Format f, InstrItinClass itin, 571 string opc, string asm, string cstr, 572 list<dag> pattern> 573 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 574 let OutOperandList = oops; 575 let InOperandList = iops; 576 let AsmString = !strconcat(opc, asm); 577 let Pattern = pattern; 578 let isPredicable = 0; 579 list<Predicate> Predicates = [IsARM]; 580} 581 582// Same as I except it can optionally modify CPSR. Note it's modeled as an input 583// operand since by default it's a zero register. It will become an implicit def 584// once it's "flipped". 585class sI<dag oops, dag iops, AddrMode am, int sz, 586 IndexMode im, Format f, InstrItinClass itin, 587 string opc, string asm, string cstr, 588 list<dag> pattern> 589 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 590 bits<4> p; // Predicate operand 591 bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 592 let Inst{31-28} = p; 593 let Inst{20} = s; 594 595 let OutOperandList = oops; 596 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 597 let AsmString = !strconcat(opc, "${s}${p}", asm); 598 let Pattern = pattern; 599 list<Predicate> Predicates = [IsARM]; 600} 601 602// Special cases 603class XI<dag oops, dag iops, AddrMode am, int sz, 604 IndexMode im, Format f, InstrItinClass itin, 605 string asm, string cstr, list<dag> pattern> 606 : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 607 let OutOperandList = oops; 608 let InOperandList = iops; 609 let AsmString = asm; 610 let Pattern = pattern; 611 list<Predicate> Predicates = [IsARM]; 612} 613 614class AI<dag oops, dag iops, Format f, InstrItinClass itin, 615 string opc, string asm, list<dag> pattern> 616 : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 617 opc, asm, "", pattern>; 618class AsI<dag oops, dag iops, Format f, InstrItinClass itin, 619 string opc, string asm, list<dag> pattern> 620 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 621 opc, asm, "", pattern>; 622class AXI<dag oops, dag iops, Format f, InstrItinClass itin, 623 string asm, list<dag> pattern> 624 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 625 asm, "", pattern>; 626class AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin, 627 string asm, list<dag> pattern> 628 : XI<oops, iops, am, 4, IndexModeNone, f, itin, 629 asm, "", pattern>; 630class AInoP<dag oops, dag iops, Format f, InstrItinClass itin, 631 string opc, string asm, list<dag> pattern> 632 : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 633 opc, asm, "", pattern>; 634 635// Ctrl flow instructions 636class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 637 string opc, string asm, list<dag> pattern> 638 : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 639 opc, asm, "", pattern> { 640 let Inst{27-24} = opcod; 641} 642class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 643 string asm, list<dag> pattern> 644 : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 645 asm, "", pattern> { 646 let Inst{27-24} = opcod; 647} 648 649// BR_JT instructions 650class JTI<dag oops, dag iops, InstrItinClass itin, 651 string asm, list<dag> pattern> 652 : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin, 653 asm, "", pattern>; 654 655class AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 656 string opc, string asm, list<dag> pattern> 657 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 658 opc, asm, "", pattern> { 659 bits<4> Rt; 660 bits<4> addr; 661 let Inst{27-23} = 0b00011; 662 let Inst{22-21} = opcod; 663 let Inst{20} = 1; 664 let Inst{19-16} = addr; 665 let Inst{15-12} = Rt; 666 let Inst{11-10} = 0b11; 667 let Inst{9-8} = opcod2; 668 let Inst{7-0} = 0b10011111; 669} 670class AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 671 string opc, string asm, list<dag> pattern> 672 : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 673 opc, asm, "", pattern> { 674 bits<4> Rt; 675 bits<4> addr; 676 let Inst{27-23} = 0b00011; 677 let Inst{22-21} = opcod; 678 let Inst{20} = 0; 679 let Inst{19-16} = addr; 680 let Inst{11-10} = 0b11; 681 let Inst{9-8} = opcod2; 682 let Inst{7-4} = 0b1001; 683 let Inst{3-0} = Rt; 684} 685// Atomic load/store instructions 686class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 687 string opc, string asm, list<dag> pattern> 688 : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>; 689 690class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 691 string opc, string asm, list<dag> pattern> 692 : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> { 693 bits<4> Rd; 694 let Inst{15-12} = Rd; 695} 696 697// Exclusive load/store instructions 698 699class AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 700 string opc, string asm, list<dag> pattern> 701 : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 702 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>; 703 704class AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 705 string opc, string asm, list<dag> pattern> 706 : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 707 Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> { 708 bits<4> Rd; 709 let Inst{15-12} = Rd; 710} 711 712class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> 713 : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> { 714 bits<4> Rt; 715 bits<4> Rt2; 716 bits<4> addr; 717 let Inst{27-23} = 0b00010; 718 let Inst{22} = b; 719 let Inst{21-20} = 0b00; 720 let Inst{19-16} = addr; 721 let Inst{15-12} = Rt; 722 let Inst{11-4} = 0b00001001; 723 let Inst{3-0} = Rt2; 724 725 let Unpredictable{11-8} = 0b1111; 726 let DecoderMethod = "DecodeSwap"; 727} 728// Acquire/Release load/store instructions 729class AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 730 string opc, string asm, list<dag> pattern> 731 : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 732 Requires<[IsARM, HasAcquireRelease]>; 733 734class AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 735 string opc, string asm, list<dag> pattern> 736 : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 737 Requires<[IsARM, HasAcquireRelease]> { 738 let Inst{15-12} = 0b1111; 739} 740 741// addrmode1 instructions 742class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 743 string opc, string asm, list<dag> pattern> 744 : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 745 opc, asm, "", pattern> { 746 let Inst{24-21} = opcod; 747 let Inst{27-26} = 0b00; 748} 749class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 750 string opc, string asm, list<dag> pattern> 751 : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 752 opc, asm, "", pattern> { 753 let Inst{24-21} = opcod; 754 let Inst{27-26} = 0b00; 755} 756class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 757 string asm, list<dag> pattern> 758 : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 759 asm, "", pattern> { 760 let Inst{24-21} = opcod; 761 let Inst{27-26} = 0b00; 762} 763 764// loads 765 766// LDR/LDRB/STR/STRB/... 767class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am, 768 Format f, InstrItinClass itin, string opc, string asm, 769 list<dag> pattern> 770 : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm, 771 "", pattern> { 772 let Inst{27-25} = op; 773 let Inst{24} = 1; // 24 == P 774 // 23 == U 775 let Inst{22} = isByte; 776 let Inst{21} = 0; // 21 == W 777 let Inst{20} = isLd; 778} 779// Indexed load/stores 780class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops, 781 IndexMode im, Format f, InstrItinClass itin, string opc, 782 string asm, string cstr, list<dag> pattern> 783 : I<oops, iops, AddrMode2, 4, im, f, itin, 784 opc, asm, cstr, pattern> { 785 bits<4> Rt; 786 let Inst{27-26} = 0b01; 787 let Inst{24} = isPre; // P bit 788 let Inst{22} = isByte; // B bit 789 let Inst{21} = isPre; // W bit 790 let Inst{20} = isLd; // L bit 791 let Inst{15-12} = Rt; 792} 793class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops, 794 IndexMode im, Format f, InstrItinClass itin, string opc, 795 string asm, string cstr, list<dag> pattern> 796 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 797 pattern> { 798 // AM2 store w/ two operands: (GPR, am2offset) 799 // {12} isAdd 800 // {11-0} imm12/Rm 801 bits<14> offset; 802 bits<4> Rn; 803 let Inst{25} = 1; 804 let Inst{23} = offset{12}; 805 let Inst{19-16} = Rn; 806 let Inst{11-5} = offset{11-5}; 807 let Inst{4} = 0; 808 let Inst{3-0} = offset{3-0}; 809} 810 811class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops, 812 IndexMode im, Format f, InstrItinClass itin, string opc, 813 string asm, string cstr, list<dag> pattern> 814 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 815 pattern> { 816 // AM2 store w/ two operands: (GPR, am2offset) 817 // {12} isAdd 818 // {11-0} imm12/Rm 819 bits<14> offset; 820 bits<4> Rn; 821 let Inst{25} = 0; 822 let Inst{23} = offset{12}; 823 let Inst{19-16} = Rn; 824 let Inst{11-0} = offset{11-0}; 825} 826 827 828// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB 829// but for now use this class for STRT and STRBT. 830class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops, 831 IndexMode im, Format f, InstrItinClass itin, string opc, 832 string asm, string cstr, list<dag> pattern> 833 : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 834 pattern> { 835 // AM2 store w/ two operands: (GPR, am2offset) 836 // {17-14} Rn 837 // {13} 1 == Rm, 0 == imm12 838 // {12} isAdd 839 // {11-0} imm12/Rm 840 bits<18> addr; 841 let Inst{25} = addr{13}; 842 let Inst{23} = addr{12}; 843 let Inst{19-16} = addr{17-14}; 844 let Inst{11-0} = addr{11-0}; 845} 846 847// addrmode3 instructions 848class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f, 849 InstrItinClass itin, string opc, string asm, list<dag> pattern> 850 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 851 opc, asm, "", pattern> { 852 bits<14> addr; 853 bits<4> Rt; 854 let Inst{27-25} = 0b000; 855 let Inst{24} = 1; // P bit 856 let Inst{23} = addr{8}; // U bit 857 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 858 let Inst{21} = 0; // W bit 859 let Inst{20} = op20; // L bit 860 let Inst{19-16} = addr{12-9}; // Rn 861 let Inst{15-12} = Rt; // Rt 862 let Inst{11-8} = addr{7-4}; // imm7_4/zero 863 let Inst{7-4} = op; 864 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 865 866 let DecoderMethod = "DecodeAddrMode3Instruction"; 867} 868 869class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops, 870 IndexMode im, Format f, InstrItinClass itin, string opc, 871 string asm, string cstr, list<dag> pattern> 872 : I<oops, iops, AddrMode3, 4, im, f, itin, 873 opc, asm, cstr, pattern> { 874 bits<4> Rt; 875 let Inst{27-25} = 0b000; 876 let Inst{24} = isPre; // P bit 877 let Inst{21} = isPre; // W bit 878 let Inst{20} = op20; // L bit 879 let Inst{15-12} = Rt; // Rt 880 let Inst{7-4} = op; 881} 882 883// FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB 884// but for now use this class for LDRSBT, LDRHT, LDSHT. 885class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops, 886 IndexMode im, Format f, InstrItinClass itin, string opc, 887 string asm, string cstr, list<dag> pattern> 888 : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> { 889 // {13} 1 == imm8, 0 == Rm 890 // {12-9} Rn 891 // {8} isAdd 892 // {7-4} imm7_4/zero 893 // {3-0} imm3_0/Rm 894 bits<4> addr; 895 bits<4> Rt; 896 let Inst{27-25} = 0b000; 897 let Inst{24} = 0; // P bit 898 let Inst{21} = 1; 899 let Inst{20} = isLoad; // L bit 900 let Inst{19-16} = addr; // Rn 901 let Inst{15-12} = Rt; // Rt 902 let Inst{7-4} = op; 903} 904 905// stores 906class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin, 907 string opc, string asm, list<dag> pattern> 908 : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 909 opc, asm, "", pattern> { 910 bits<14> addr; 911 bits<4> Rt; 912 let Inst{27-25} = 0b000; 913 let Inst{24} = 1; // P bit 914 let Inst{23} = addr{8}; // U bit 915 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 916 let Inst{21} = 0; // W bit 917 let Inst{20} = 0; // L bit 918 let Inst{19-16} = addr{12-9}; // Rn 919 let Inst{15-12} = Rt; // Rt 920 let Inst{11-8} = addr{7-4}; // imm7_4/zero 921 let Inst{7-4} = op; 922 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 923 let DecoderMethod = "DecodeAddrMode3Instruction"; 924} 925 926// addrmode4 instructions 927class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, 928 string asm, string cstr, list<dag> pattern> 929 : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> { 930 bits<4> p; 931 bits<16> regs; 932 bits<4> Rn; 933 let Inst{31-28} = p; 934 let Inst{27-25} = 0b100; 935 let Inst{22} = 0; // S bit 936 let Inst{19-16} = Rn; 937 let Inst{15-0} = regs; 938} 939 940// Unsigned multiply, multiply-accumulate instructions. 941class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 942 string opc, string asm, list<dag> pattern> 943 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 944 opc, asm, "", pattern> { 945 let Inst{7-4} = 0b1001; 946 let Inst{20} = 0; // S bit 947 let Inst{27-21} = opcod; 948} 949class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 950 string opc, string asm, list<dag> pattern> 951 : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 952 opc, asm, "", pattern> { 953 let Inst{7-4} = 0b1001; 954 let Inst{27-21} = opcod; 955} 956 957// Most significant word multiply 958class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 959 InstrItinClass itin, string opc, string asm, list<dag> pattern> 960 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 961 opc, asm, "", pattern> { 962 bits<4> Rd; 963 bits<4> Rn; 964 bits<4> Rm; 965 let Inst{7-4} = opc7_4; 966 let Inst{20} = 1; 967 let Inst{27-21} = opcod; 968 let Inst{19-16} = Rd; 969 let Inst{11-8} = Rm; 970 let Inst{3-0} = Rn; 971} 972// MSW multiple w/ Ra operand 973class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 974 InstrItinClass itin, string opc, string asm, list<dag> pattern> 975 : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> { 976 bits<4> Ra; 977 let Inst{15-12} = Ra; 978} 979 980// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y> 981class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 982 InstrItinClass itin, string opc, string asm, list<dag> pattern> 983 : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 984 opc, asm, "", pattern> { 985 bits<4> Rn; 986 bits<4> Rm; 987 let Inst{4} = 0; 988 let Inst{7} = 1; 989 let Inst{20} = 0; 990 let Inst{27-21} = opcod; 991 let Inst{6-5} = bit6_5; 992 let Inst{11-8} = Rm; 993 let Inst{3-0} = Rn; 994} 995class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 996 InstrItinClass itin, string opc, string asm, list<dag> pattern> 997 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 998 bits<4> Rd; 999 let Inst{19-16} = Rd; 1000} 1001 1002// AMulxyI with Ra operand 1003class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 1004 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1005 : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 1006 bits<4> Ra; 1007 let Inst{15-12} = Ra; 1008} 1009// SMLAL* 1010class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 1011 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1012 : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 1013 bits<4> RdLo; 1014 bits<4> RdHi; 1015 let Inst{19-16} = RdHi; 1016 let Inst{15-12} = RdLo; 1017} 1018 1019// Extend instructions. 1020class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 1021 string opc, string asm, list<dag> pattern> 1022 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin, 1023 opc, asm, "", pattern> { 1024 // All AExtI instructions have Rd and Rm register operands. 1025 bits<4> Rd; 1026 bits<4> Rm; 1027 let Inst{15-12} = Rd; 1028 let Inst{3-0} = Rm; 1029 let Inst{7-4} = 0b0111; 1030 let Inst{9-8} = 0b00; 1031 let Inst{27-20} = opcod; 1032 1033 let Unpredictable{9-8} = 0b11; 1034} 1035 1036// Misc Arithmetic instructions. 1037class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops, 1038 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1039 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 1040 opc, asm, "", pattern> { 1041 bits<4> Rd; 1042 bits<4> Rm; 1043 let Inst{27-20} = opcod; 1044 let Inst{19-16} = 0b1111; 1045 let Inst{15-12} = Rd; 1046 let Inst{11-8} = 0b1111; 1047 let Inst{7-4} = opc7_4; 1048 let Inst{3-0} = Rm; 1049} 1050 1051// Division instructions. 1052class ADivA1I<bits<3> opcod, dag oops, dag iops, 1053 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1054 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 1055 opc, asm, "", pattern> { 1056 bits<4> Rd; 1057 bits<4> Rn; 1058 bits<4> Rm; 1059 let Inst{27-23} = 0b01110; 1060 let Inst{22-20} = opcod; 1061 let Inst{19-16} = Rd; 1062 let Inst{15-12} = 0b1111; 1063 let Inst{11-8} = Rm; 1064 let Inst{7-4} = 0b0001; 1065 let Inst{3-0} = Rn; 1066} 1067 1068// PKH instructions 1069def PKHLSLAsmOperand : ImmAsmOperand<0,31> { 1070 let Name = "PKHLSLImm"; 1071 let ParserMethod = "parsePKHLSLImm"; 1072} 1073def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{ 1074 let PrintMethod = "printPKHLSLShiftImm"; 1075 let ParserMatchClass = PKHLSLAsmOperand; 1076} 1077def PKHASRAsmOperand : AsmOperandClass { 1078 let Name = "PKHASRImm"; 1079 let ParserMethod = "parsePKHASRImm"; 1080} 1081def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{ 1082 let PrintMethod = "printPKHASRShiftImm"; 1083 let ParserMatchClass = PKHASRAsmOperand; 1084} 1085 1086class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin, 1087 string opc, string asm, list<dag> pattern> 1088 : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 1089 opc, asm, "", pattern> { 1090 bits<4> Rd; 1091 bits<4> Rn; 1092 bits<4> Rm; 1093 bits<5> sh; 1094 let Inst{27-20} = opcod; 1095 let Inst{19-16} = Rn; 1096 let Inst{15-12} = Rd; 1097 let Inst{11-7} = sh; 1098 let Inst{6} = tb; 1099 let Inst{5-4} = 0b01; 1100 let Inst{3-0} = Rm; 1101} 1102 1103//===----------------------------------------------------------------------===// 1104 1105// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode. 1106class ARMPat<dag pattern, dag result> : Pat<pattern, result> { 1107 list<Predicate> Predicates = [IsARM]; 1108} 1109class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> { 1110 list<Predicate> Predicates = [IsARM, HasV5T]; 1111} 1112class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> { 1113 list<Predicate> Predicates = [IsARM, HasV5TE]; 1114} 1115// ARMV5MOPat - Same as ARMV5TEPat with UseMulOps. 1116class ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> { 1117 list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps]; 1118} 1119class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> { 1120 list<Predicate> Predicates = [IsARM, HasV6]; 1121} 1122class VFPPat<dag pattern, dag result> : Pat<pattern, result> { 1123 list<Predicate> Predicates = [HasVFP2]; 1124} 1125class VFPNoNEONPat<dag pattern, dag result> : Pat<pattern, result> { 1126 list<Predicate> Predicates = [HasVFP2, DontUseNEONForFP]; 1127} 1128class Thumb2DSPPat<dag pattern, dag result> : Pat<pattern, result> { 1129 list<Predicate> Predicates = [IsThumb2, HasDSP]; 1130} 1131class Thumb2DSPMulPat<dag pattern, dag result> : Pat<pattern, result> { 1132 list<Predicate> Predicates = [IsThumb2, UseMulOps, HasDSP]; 1133} 1134class FPRegs16Pat<dag pattern, dag result> : Pat<pattern, result> { 1135 list<Predicate> Predicates = [HasFPRegs16]; 1136} 1137class FP16Pat<dag pattern, dag result> : Pat<pattern, result> { 1138 list<Predicate> Predicates = [HasFP16]; 1139} 1140class FullFP16Pat<dag pattern, dag result> : Pat<pattern, result> { 1141 list<Predicate> Predicates = [HasFullFP16]; 1142} 1143//===----------------------------------------------------------------------===// 1144// Thumb Instruction Format Definitions. 1145// 1146 1147class ThumbI<dag oops, dag iops, AddrMode am, int sz, 1148 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1149 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1150 let OutOperandList = oops; 1151 let InOperandList = iops; 1152 let AsmString = asm; 1153 let Pattern = pattern; 1154 list<Predicate> Predicates = [IsThumb]; 1155} 1156 1157// TI - Thumb instruction. 1158class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 1159 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1160 1161// Two-address instructions 1162class TIt<dag oops, dag iops, InstrItinClass itin, string asm, 1163 list<dag> pattern> 1164 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst", 1165 pattern>; 1166 1167// tBL, tBX 32-bit instructions 1168class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3, 1169 dag oops, dag iops, InstrItinClass itin, string asm, 1170 list<dag> pattern> 1171 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>, 1172 Encoding { 1173 let Inst{31-27} = opcod1; 1174 let Inst{15-14} = opcod2; 1175 let Inst{12} = opcod3; 1176} 1177 1178// BR_JT instructions 1179class TJTI<dag oops, dag iops, InstrItinClass itin, string asm, 1180 list<dag> pattern> 1181 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1182 1183// Thumb1 only 1184class Thumb1I<dag oops, dag iops, AddrMode am, int sz, 1185 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1186 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1187 let OutOperandList = oops; 1188 let InOperandList = iops; 1189 let AsmString = asm; 1190 let Pattern = pattern; 1191 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1192} 1193 1194class T1I<dag oops, dag iops, InstrItinClass itin, 1195 string asm, list<dag> pattern> 1196 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1197class T1Ix2<dag oops, dag iops, InstrItinClass itin, 1198 string asm, list<dag> pattern> 1199 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1200 1201// Two-address instructions 1202class T1It<dag oops, dag iops, InstrItinClass itin, 1203 string asm, string cstr, list<dag> pattern> 1204 : Thumb1I<oops, iops, AddrModeNone, 2, itin, 1205 asm, cstr, pattern>; 1206 1207// Thumb1 instruction that can either be predicated or set CPSR. 1208class Thumb1sI<dag oops, dag iops, AddrMode am, int sz, 1209 InstrItinClass itin, 1210 string opc, string asm, string cstr, list<dag> pattern> 1211 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1212 let OutOperandList = !con(oops, (outs s_cc_out:$s)); 1213 let InOperandList = !con(iops, (ins pred:$p)); 1214 let AsmString = !strconcat(opc, "${s}${p}", asm); 1215 let Pattern = pattern; 1216 let thumbArithFlagSetting = 1; 1217 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1218 let DecoderNamespace = "ThumbSBit"; 1219} 1220 1221class T1sI<dag oops, dag iops, InstrItinClass itin, 1222 string opc, string asm, list<dag> pattern> 1223 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1224 1225// Two-address instructions 1226class T1sIt<dag oops, dag iops, InstrItinClass itin, 1227 string opc, string asm, list<dag> pattern> 1228 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1229 "$Rn = $Rdn", pattern>; 1230 1231// Thumb1 instruction that can be predicated. 1232class Thumb1pI<dag oops, dag iops, AddrMode am, int sz, 1233 InstrItinClass itin, 1234 string opc, string asm, string cstr, list<dag> pattern> 1235 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1236 let OutOperandList = oops; 1237 let InOperandList = !con(iops, (ins pred:$p)); 1238 let AsmString = !strconcat(opc, "${p}", asm); 1239 let Pattern = pattern; 1240 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1241} 1242 1243class T1pI<dag oops, dag iops, InstrItinClass itin, 1244 string opc, string asm, list<dag> pattern> 1245 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1246 1247// Two-address instructions 1248class T1pIt<dag oops, dag iops, InstrItinClass itin, 1249 string opc, string asm, list<dag> pattern> 1250 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1251 "$Rn = $Rdn", pattern>; 1252 1253class T1pIs<dag oops, dag iops, 1254 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1255 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>; 1256 1257class Encoding16 : Encoding { 1258 let Inst{31-16} = 0x0000; 1259} 1260 1261// A6.2 16-bit Thumb instruction encoding 1262class T1Encoding<bits<6> opcode> : Encoding16 { 1263 let Inst{15-10} = opcode; 1264} 1265 1266// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. 1267class T1General<bits<5> opcode> : Encoding16 { 1268 let Inst{15-14} = 0b00; 1269 let Inst{13-9} = opcode; 1270} 1271 1272// A6.2.2 Data-processing encoding. 1273class T1DataProcessing<bits<4> opcode> : Encoding16 { 1274 let Inst{15-10} = 0b010000; 1275 let Inst{9-6} = opcode; 1276} 1277 1278// A6.2.3 Special data instructions and branch and exchange encoding. 1279class T1Special<bits<4> opcode> : Encoding16 { 1280 let Inst{15-10} = 0b010001; 1281 let Inst{9-6} = opcode; 1282} 1283 1284// A6.2.4 Load/store single data item encoding. 1285class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 { 1286 let Inst{15-12} = opA; 1287 let Inst{11-9} = opB; 1288} 1289class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative 1290 1291class T1BranchCond<bits<4> opcode> : Encoding16 { 1292 let Inst{15-12} = opcode; 1293} 1294 1295// Helper classes to encode Thumb1 loads and stores. For immediates, the 1296// following bits are used for "opA" (see A6.2.4): 1297// 1298// 0b0110 => Immediate, 4 bytes 1299// 0b1000 => Immediate, 2 bytes 1300// 0b0111 => Immediate, 1 byte 1301class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am, 1302 InstrItinClass itin, string opc, string asm, 1303 list<dag> pattern> 1304 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1305 T1LoadStore<0b0101, opcode> { 1306 bits<3> Rt; 1307 bits<8> addr; 1308 let Inst{8-6} = addr{5-3}; // Rm 1309 let Inst{5-3} = addr{2-0}; // Rn 1310 let Inst{2-0} = Rt; 1311} 1312class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am, 1313 InstrItinClass itin, string opc, string asm, 1314 list<dag> pattern> 1315 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1316 T1LoadStore<opA, {opB,?,?}> { 1317 bits<3> Rt; 1318 bits<8> addr; 1319 let Inst{10-6} = addr{7-3}; // imm5 1320 let Inst{5-3} = addr{2-0}; // Rn 1321 let Inst{2-0} = Rt; 1322} 1323 1324// A6.2.5 Miscellaneous 16-bit instructions encoding. 1325class T1Misc<bits<7> opcode> : Encoding16 { 1326 let Inst{15-12} = 0b1011; 1327 let Inst{11-5} = opcode; 1328} 1329 1330// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 1331class Thumb2I<dag oops, dag iops, AddrMode am, int sz, 1332 InstrItinClass itin, 1333 string opc, string asm, string cstr, list<dag> pattern> 1334 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1335 let OutOperandList = oops; 1336 let InOperandList = !con(iops, (ins pred:$p)); 1337 let AsmString = !strconcat(opc, "${p}", asm); 1338 let Pattern = pattern; 1339 list<Predicate> Predicates = [IsThumb2]; 1340 let DecoderNamespace = "Thumb2"; 1341} 1342 1343// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an 1344// input operand since by default it's a zero register. It will become an 1345// implicit def once it's "flipped". 1346// 1347// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 1348// more consistent. 1349class Thumb2sI<dag oops, dag iops, AddrMode am, int sz, 1350 InstrItinClass itin, 1351 string opc, string asm, string cstr, list<dag> pattern> 1352 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1353 bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 1354 let Inst{20} = s; 1355 1356 let OutOperandList = oops; 1357 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 1358 let AsmString = !strconcat(opc, "${s}${p}", asm); 1359 let Pattern = pattern; 1360 list<Predicate> Predicates = [IsThumb2]; 1361 let DecoderNamespace = "Thumb2"; 1362} 1363 1364// Special cases 1365class Thumb2XI<dag oops, dag iops, AddrMode am, int sz, 1366 InstrItinClass itin, 1367 string asm, string cstr, list<dag> pattern> 1368 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1369 let OutOperandList = oops; 1370 let InOperandList = iops; 1371 let AsmString = asm; 1372 let Pattern = pattern; 1373 list<Predicate> Predicates = [IsThumb2]; 1374 let DecoderNamespace = "Thumb2"; 1375} 1376 1377class ThumbXI<dag oops, dag iops, AddrMode am, int sz, 1378 InstrItinClass itin, 1379 string asm, string cstr, list<dag> pattern> 1380 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1381 let OutOperandList = oops; 1382 let InOperandList = iops; 1383 let AsmString = asm; 1384 let Pattern = pattern; 1385 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1386 let DecoderNamespace = "Thumb"; 1387} 1388 1389class T2I<dag oops, dag iops, InstrItinClass itin, 1390 string opc, string asm, list<dag> pattern, AddrMode am = AddrModeNone> 1391 : Thumb2I<oops, iops, am, 4, itin, opc, asm, "", pattern>; 1392class T2Ii12<dag oops, dag iops, InstrItinClass itin, 1393 string opc, string asm, list<dag> pattern> 1394 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>; 1395class T2Ii8<dag oops, dag iops, InstrItinClass itin, 1396 string opc, string asm, list<dag> pattern> 1397 : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>; 1398class T2Iso<dag oops, dag iops, InstrItinClass itin, 1399 string opc, string asm, list<dag> pattern> 1400 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>; 1401class T2Ipc<dag oops, dag iops, InstrItinClass itin, 1402 string opc, string asm, list<dag> pattern> 1403 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>; 1404class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin, 1405 string opc, string asm, string cstr, list<dag> pattern> 1406 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1407 pattern> { 1408 bits<4> Rt; 1409 bits<4> Rt2; 1410 bits<13> addr; 1411 let Inst{31-25} = 0b1110100; 1412 let Inst{24} = P; 1413 let Inst{23} = addr{8}; 1414 let Inst{22} = 1; 1415 let Inst{21} = W; 1416 let Inst{20} = isLoad; 1417 let Inst{19-16} = addr{12-9}; 1418 let Inst{15-12} = Rt{3-0}; 1419 let Inst{11-8} = Rt2{3-0}; 1420 let Inst{7-0} = addr{7-0}; 1421} 1422class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops, 1423 InstrItinClass itin, string opc, string asm, string cstr, 1424 list<dag> pattern> 1425 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1426 pattern> { 1427 bits<4> Rt; 1428 bits<4> Rt2; 1429 bits<4> addr; 1430 bits<9> imm; 1431 let Inst{31-25} = 0b1110100; 1432 let Inst{24} = P; 1433 let Inst{23} = imm{8}; 1434 let Inst{22} = 1; 1435 let Inst{21} = W; 1436 let Inst{20} = isLoad; 1437 let Inst{19-16} = addr; 1438 let Inst{15-12} = Rt{3-0}; 1439 let Inst{11-8} = Rt2{3-0}; 1440 let Inst{7-0} = imm{7-0}; 1441} 1442 1443class T2sI<dag oops, dag iops, InstrItinClass itin, 1444 string opc, string asm, list<dag> pattern> 1445 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1446 1447class T2XI<dag oops, dag iops, InstrItinClass itin, 1448 string asm, list<dag> pattern> 1449 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1450class T2JTI<dag oops, dag iops, InstrItinClass itin, 1451 string asm, list<dag> pattern> 1452 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1453 1454// Move to/from coprocessor instructions 1455class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm, 1456 list<dag> pattern> 1457 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> { 1458 let Inst{31-28} = opc; 1459} 1460 1461// Two-address instructions 1462class T2XIt<dag oops, dag iops, InstrItinClass itin, 1463 string asm, string cstr, list<dag> pattern> 1464 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>; 1465 1466// T2Ipreldst - Thumb2 pre-indexed load / store instructions. 1467class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre, 1468 dag oops, dag iops, 1469 AddrMode am, IndexMode im, InstrItinClass itin, 1470 string opc, string asm, string cstr, list<dag> pattern> 1471 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1472 let OutOperandList = oops; 1473 let InOperandList = !con(iops, (ins pred:$p)); 1474 let AsmString = !strconcat(opc, "${p}", asm); 1475 let Pattern = pattern; 1476 list<Predicate> Predicates = [IsThumb2]; 1477 let DecoderNamespace = "Thumb2"; 1478 1479 bits<4> Rt; 1480 bits<13> addr; 1481 let Inst{31-27} = 0b11111; 1482 let Inst{26-25} = 0b00; 1483 let Inst{24} = signed; 1484 let Inst{23} = 0; 1485 let Inst{22-21} = opcod; 1486 let Inst{20} = load; 1487 let Inst{19-16} = addr{12-9}; 1488 let Inst{15-12} = Rt{3-0}; 1489 let Inst{11} = 1; 1490 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1491 let Inst{10} = pre; // The P bit. 1492 let Inst{9} = addr{8}; // Sign bit 1493 let Inst{8} = 1; // The W bit. 1494 let Inst{7-0} = addr{7-0}; 1495 1496 let DecoderMethod = "DecodeT2LdStPre"; 1497} 1498 1499// T2Ipostldst - Thumb2 post-indexed load / store instructions. 1500class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, 1501 dag oops, dag iops, 1502 AddrMode am, IndexMode im, InstrItinClass itin, 1503 string opc, string asm, string cstr, list<dag> pattern> 1504 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1505 let OutOperandList = oops; 1506 let InOperandList = !con(iops, (ins pred:$p)); 1507 let AsmString = !strconcat(opc, "${p}", asm); 1508 let Pattern = pattern; 1509 list<Predicate> Predicates = [IsThumb2]; 1510 let DecoderNamespace = "Thumb2"; 1511 1512 bits<4> Rt; 1513 bits<4> Rn; 1514 bits<9> offset; 1515 let Inst{31-27} = 0b11111; 1516 let Inst{26-25} = 0b00; 1517 let Inst{24} = signed; 1518 let Inst{23} = 0; 1519 let Inst{22-21} = opcod; 1520 let Inst{20} = load; 1521 let Inst{19-16} = Rn; 1522 let Inst{15-12} = Rt{3-0}; 1523 let Inst{11} = 1; 1524 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1525 let Inst{10} = pre; // The P bit. 1526 let Inst{9} = offset{8}; // Sign bit 1527 let Inst{8} = 1; // The W bit. 1528 let Inst{7-0} = offset{7-0}; 1529 1530 let DecoderMethod = "DecodeT2LdStPre"; 1531} 1532 1533// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 1534class T1Pat<dag pattern, dag result> : Pat<pattern, result> { 1535 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1536} 1537 1538// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode. 1539class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> { 1540 list<Predicate> Predicates = [IsThumb2, HasV6T2]; 1541} 1542 1543// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 1544class T2Pat<dag pattern, dag result> : Pat<pattern, result> { 1545 list<Predicate> Predicates = [IsThumb2]; 1546} 1547 1548//===----------------------------------------------------------------------===// 1549 1550//===----------------------------------------------------------------------===// 1551// ARM VFP Instruction templates. 1552// 1553 1554// Almost all VFP instructions are predicable. 1555class VFPI<dag oops, dag iops, AddrMode am, int sz, 1556 IndexMode im, Format f, InstrItinClass itin, 1557 string opc, string asm, string cstr, list<dag> pattern> 1558 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1559 bits<4> p; 1560 let Inst{31-28} = p; 1561 let OutOperandList = oops; 1562 let InOperandList = !con(iops, (ins pred:$p)); 1563 let AsmString = !strconcat(opc, "${p}", asm); 1564 let Pattern = pattern; 1565 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1566 let DecoderNamespace = "VFP"; 1567 list<Predicate> Predicates = [HasVFP2]; 1568} 1569 1570// Special cases 1571class VFPXI<dag oops, dag iops, AddrMode am, int sz, 1572 IndexMode im, Format f, InstrItinClass itin, 1573 string asm, string cstr, list<dag> pattern> 1574 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1575 bits<4> p; 1576 let Inst{31-28} = p; 1577 let OutOperandList = oops; 1578 let InOperandList = iops; 1579 let AsmString = asm; 1580 let Pattern = pattern; 1581 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1582 let DecoderNamespace = "VFP"; 1583 list<Predicate> Predicates = [HasVFP2]; 1584} 1585 1586class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 1587 string opc, string asm, list<dag> pattern> 1588 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 1589 opc, asm, "", pattern> { 1590 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1591} 1592 1593// ARM VFP addrmode5 loads and stores 1594class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1595 InstrItinClass itin, 1596 string opc, string asm, list<dag> pattern> 1597 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1598 VFPLdStFrm, itin, opc, asm, "", pattern> { 1599 // Instruction operands. 1600 bits<5> Dd; 1601 bits<13> addr; 1602 1603 // Encode instruction operands. 1604 let Inst{23} = addr{8}; // U (add = (U == '1')) 1605 let Inst{22} = Dd{4}; 1606 let Inst{19-16} = addr{12-9}; // Rn 1607 let Inst{15-12} = Dd{3-0}; 1608 let Inst{7-0} = addr{7-0}; // imm8 1609 1610 let Inst{27-24} = opcod1; 1611 let Inst{21-20} = opcod2; 1612 let Inst{11-9} = 0b101; 1613 let Inst{8} = 1; // Double precision 1614 1615 // Loads & stores operate on both NEON and VFP pipelines. 1616 let D = VFPNeonDomain; 1617} 1618 1619class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1620 InstrItinClass itin, 1621 string opc, string asm, list<dag> pattern> 1622 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1623 VFPLdStFrm, itin, opc, asm, "", pattern> { 1624 // Instruction operands. 1625 bits<5> Sd; 1626 bits<13> addr; 1627 1628 // Encode instruction operands. 1629 let Inst{23} = addr{8}; // U (add = (U == '1')) 1630 let Inst{22} = Sd{0}; 1631 let Inst{19-16} = addr{12-9}; // Rn 1632 let Inst{15-12} = Sd{4-1}; 1633 let Inst{7-0} = addr{7-0}; // imm8 1634 1635 let Inst{27-24} = opcod1; 1636 let Inst{21-20} = opcod2; 1637 let Inst{11-9} = 0b101; 1638 let Inst{8} = 0; // Single precision 1639 1640 // Loads & stores operate on both NEON and VFP pipelines. 1641 let D = VFPNeonDomain; 1642} 1643 1644class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1645 InstrItinClass itin, 1646 string opc, string asm, list<dag> pattern> 1647 : VFPI<oops, iops, AddrMode5FP16, 4, IndexModeNone, 1648 VFPLdStFrm, itin, opc, asm, "", pattern> { 1649 list<Predicate> Predicates = [HasFullFP16]; 1650 1651 // Instruction operands. 1652 bits<5> Sd; 1653 bits<13> addr; 1654 1655 // Encode instruction operands. 1656 let Inst{23} = addr{8}; // U (add = (U == '1')) 1657 let Inst{22} = Sd{0}; 1658 let Inst{19-16} = addr{12-9}; // Rn 1659 let Inst{15-12} = Sd{4-1}; 1660 let Inst{7-0} = addr{7-0}; // imm8 1661 1662 let Inst{27-24} = opcod1; 1663 let Inst{21-20} = opcod2; 1664 let Inst{11-8} = 0b1001; // Half precision 1665 1666 // Loads & stores operate on both NEON and VFP pipelines. 1667 let D = VFPNeonDomain; 1668 1669 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 1670} 1671 1672// VFP Load / store multiple pseudo instructions. 1673class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, 1674 list<dag> pattern> 1675 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain, 1676 cstr, itin> { 1677 let OutOperandList = oops; 1678 let InOperandList = !con(iops, (ins pred:$p)); 1679 let Pattern = pattern; 1680 list<Predicate> Predicates = [HasVFP2]; 1681} 1682 1683// Load / store multiple 1684 1685// Unknown precision 1686class AXXI4<dag oops, dag iops, IndexMode im, 1687 string asm, string cstr, list<dag> pattern> 1688 : VFPXI<oops, iops, AddrMode4, 4, im, 1689 VFPLdStFrm, NoItinerary, asm, cstr, pattern> { 1690 // Instruction operands. 1691 bits<4> Rn; 1692 bits<13> regs; 1693 1694 // Encode instruction operands. 1695 let Inst{19-16} = Rn; 1696 let Inst{22} = 0; 1697 let Inst{15-12} = regs{11-8}; 1698 let Inst{7-1} = regs{7-1}; 1699 1700 let Inst{27-25} = 0b110; 1701 let Inst{11-8} = 0b1011; 1702 let Inst{0} = 1; 1703} 1704 1705// Double precision 1706class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1707 string asm, string cstr, list<dag> pattern> 1708 : VFPXI<oops, iops, AddrMode4, 4, im, 1709 VFPLdStMulFrm, itin, asm, cstr, pattern> { 1710 // Instruction operands. 1711 bits<4> Rn; 1712 bits<13> regs; 1713 1714 // Encode instruction operands. 1715 let Inst{19-16} = Rn; 1716 let Inst{22} = regs{12}; 1717 let Inst{15-12} = regs{11-8}; 1718 let Inst{7-1} = regs{7-1}; 1719 1720 let Inst{27-25} = 0b110; 1721 let Inst{11-9} = 0b101; 1722 let Inst{8} = 1; // Double precision 1723 let Inst{0} = 0; 1724} 1725 1726// Single Precision 1727class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1728 string asm, string cstr, list<dag> pattern> 1729 : VFPXI<oops, iops, AddrMode4, 4, im, 1730 VFPLdStMulFrm, itin, asm, cstr, pattern> { 1731 // Instruction operands. 1732 bits<4> Rn; 1733 bits<13> regs; 1734 1735 // Encode instruction operands. 1736 let Inst{19-16} = Rn; 1737 let Inst{22} = regs{8}; 1738 let Inst{15-12} = regs{12-9}; 1739 let Inst{7-0} = regs{7-0}; 1740 1741 let Inst{27-25} = 0b110; 1742 let Inst{11-9} = 0b101; 1743 let Inst{8} = 0; // Single precision 1744} 1745 1746// Double precision, unary 1747class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1748 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1749 string asm, list<dag> pattern> 1750 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1751 // Instruction operands. 1752 bits<5> Dd; 1753 bits<5> Dm; 1754 1755 // Encode instruction operands. 1756 let Inst{3-0} = Dm{3-0}; 1757 let Inst{5} = Dm{4}; 1758 let Inst{15-12} = Dd{3-0}; 1759 let Inst{22} = Dd{4}; 1760 1761 let Inst{27-23} = opcod1; 1762 let Inst{21-20} = opcod2; 1763 let Inst{19-16} = opcod3; 1764 let Inst{11-9} = 0b101; 1765 let Inst{8} = 1; // Double precision 1766 let Inst{7-6} = opcod4; 1767 let Inst{4} = opcod5; 1768 1769 let Predicates = [HasVFP2, HasDPVFP]; 1770} 1771 1772// Double precision, unary, not-predicated 1773class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1774 bit opcod5, dag oops, dag iops, InstrItinClass itin, 1775 string asm, list<dag> pattern> 1776 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> { 1777 // Instruction operands. 1778 bits<5> Dd; 1779 bits<5> Dm; 1780 1781 let Inst{31-28} = 0b1111; 1782 1783 // Encode instruction operands. 1784 let Inst{3-0} = Dm{3-0}; 1785 let Inst{5} = Dm{4}; 1786 let Inst{15-12} = Dd{3-0}; 1787 let Inst{22} = Dd{4}; 1788 1789 let Inst{27-23} = opcod1; 1790 let Inst{21-20} = opcod2; 1791 let Inst{19-16} = opcod3; 1792 let Inst{11-9} = 0b101; 1793 let Inst{8} = 1; // Double precision 1794 let Inst{7-6} = opcod4; 1795 let Inst{4} = opcod5; 1796} 1797 1798// Double precision, binary 1799class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1800 dag iops, InstrItinClass itin, string opc, string asm, 1801 list<dag> pattern> 1802 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1803 // Instruction operands. 1804 bits<5> Dd; 1805 bits<5> Dn; 1806 bits<5> Dm; 1807 1808 // Encode instruction operands. 1809 let Inst{3-0} = Dm{3-0}; 1810 let Inst{5} = Dm{4}; 1811 let Inst{19-16} = Dn{3-0}; 1812 let Inst{7} = Dn{4}; 1813 let Inst{15-12} = Dd{3-0}; 1814 let Inst{22} = Dd{4}; 1815 1816 let Inst{27-23} = opcod1; 1817 let Inst{21-20} = opcod2; 1818 let Inst{11-9} = 0b101; 1819 let Inst{8} = 1; // Double precision 1820 let Inst{6} = op6; 1821 let Inst{4} = op4; 1822 1823 let Predicates = [HasVFP2, HasDPVFP]; 1824} 1825 1826// FP, binary, not predicated 1827class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1828 InstrItinClass itin, string asm, list<dag> pattern> 1829 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin, 1830 asm, "", pattern> 1831{ 1832 // Instruction operands. 1833 bits<5> Dd; 1834 bits<5> Dn; 1835 bits<5> Dm; 1836 1837 let Inst{31-28} = 0b1111; 1838 1839 // Encode instruction operands. 1840 let Inst{3-0} = Dm{3-0}; 1841 let Inst{5} = Dm{4}; 1842 let Inst{19-16} = Dn{3-0}; 1843 let Inst{7} = Dn{4}; 1844 let Inst{15-12} = Dd{3-0}; 1845 let Inst{22} = Dd{4}; 1846 1847 let Inst{27-23} = opcod1; 1848 let Inst{21-20} = opcod2; 1849 let Inst{11-9} = 0b101; 1850 let Inst{8} = 1; // double precision 1851 let Inst{6} = opcod3; 1852 let Inst{4} = 0; 1853 1854 let Predicates = [HasVFP2, HasDPVFP]; 1855} 1856 1857// Single precision, unary, predicated 1858class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1859 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1860 string asm, list<dag> pattern> 1861 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1862 // Instruction operands. 1863 bits<5> Sd; 1864 bits<5> Sm; 1865 1866 // Encode instruction operands. 1867 let Inst{3-0} = Sm{4-1}; 1868 let Inst{5} = Sm{0}; 1869 let Inst{15-12} = Sd{4-1}; 1870 let Inst{22} = Sd{0}; 1871 1872 let Inst{27-23} = opcod1; 1873 let Inst{21-20} = opcod2; 1874 let Inst{19-16} = opcod3; 1875 let Inst{11-9} = 0b101; 1876 let Inst{8} = 0; // Single precision 1877 let Inst{7-6} = opcod4; 1878 let Inst{4} = opcod5; 1879} 1880 1881// Single precision, unary, non-predicated 1882class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1883 bit opcod5, dag oops, dag iops, InstrItinClass itin, 1884 string asm, list<dag> pattern> 1885 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1886 VFPUnaryFrm, itin, asm, "", pattern> { 1887 // Instruction operands. 1888 bits<5> Sd; 1889 bits<5> Sm; 1890 1891 let Inst{31-28} = 0b1111; 1892 1893 // Encode instruction operands. 1894 let Inst{3-0} = Sm{4-1}; 1895 let Inst{5} = Sm{0}; 1896 let Inst{15-12} = Sd{4-1}; 1897 let Inst{22} = Sd{0}; 1898 1899 let Inst{27-23} = opcod1; 1900 let Inst{21-20} = opcod2; 1901 let Inst{19-16} = opcod3; 1902 let Inst{11-9} = 0b101; 1903 let Inst{8} = 0; // Single precision 1904 let Inst{7-6} = opcod4; 1905 let Inst{4} = opcod5; 1906} 1907 1908// Single precision unary, if no NEON. Same as ASuI except not available if 1909// NEON is enabled. 1910class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1911 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1912 string asm, list<dag> pattern> 1913 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm, 1914 pattern> { 1915 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1916} 1917 1918// Single precision, binary 1919class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 1920 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1921 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1922 // Instruction operands. 1923 bits<5> Sd; 1924 bits<5> Sn; 1925 bits<5> Sm; 1926 1927 // Encode instruction operands. 1928 let Inst{3-0} = Sm{4-1}; 1929 let Inst{5} = Sm{0}; 1930 let Inst{19-16} = Sn{4-1}; 1931 let Inst{7} = Sn{0}; 1932 let Inst{15-12} = Sd{4-1}; 1933 let Inst{22} = Sd{0}; 1934 1935 let Inst{27-23} = opcod1; 1936 let Inst{21-20} = opcod2; 1937 let Inst{11-9} = 0b101; 1938 let Inst{8} = 0; // Single precision 1939 let Inst{6} = op6; 1940 let Inst{4} = op4; 1941} 1942 1943// Single precision, binary, not predicated 1944class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1945 InstrItinClass itin, string asm, list<dag> pattern> 1946 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1947 VFPBinaryFrm, itin, asm, "", pattern> 1948{ 1949 // Instruction operands. 1950 bits<5> Sd; 1951 bits<5> Sn; 1952 bits<5> Sm; 1953 1954 let Inst{31-28} = 0b1111; 1955 1956 // Encode instruction operands. 1957 let Inst{3-0} = Sm{4-1}; 1958 let Inst{5} = Sm{0}; 1959 let Inst{19-16} = Sn{4-1}; 1960 let Inst{7} = Sn{0}; 1961 let Inst{15-12} = Sd{4-1}; 1962 let Inst{22} = Sd{0}; 1963 1964 let Inst{27-23} = opcod1; 1965 let Inst{21-20} = opcod2; 1966 let Inst{11-9} = 0b101; 1967 let Inst{8} = 0; // Single precision 1968 let Inst{6} = opcod3; 1969 let Inst{4} = 0; 1970} 1971 1972// Single precision binary, if no NEON. Same as ASbI except not available if 1973// NEON is enabled. 1974class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1975 dag iops, InstrItinClass itin, string opc, string asm, 1976 list<dag> pattern> 1977 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> { 1978 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1979 1980 // Instruction operands. 1981 bits<5> Sd; 1982 bits<5> Sn; 1983 bits<5> Sm; 1984 1985 // Encode instruction operands. 1986 let Inst{3-0} = Sm{4-1}; 1987 let Inst{5} = Sm{0}; 1988 let Inst{19-16} = Sn{4-1}; 1989 let Inst{7} = Sn{0}; 1990 let Inst{15-12} = Sd{4-1}; 1991 let Inst{22} = Sd{0}; 1992} 1993 1994// Half precision, unary, predicated 1995class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1996 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1997 string asm, list<dag> pattern> 1998 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1999 list<Predicate> Predicates = [HasFullFP16]; 2000 2001 // Instruction operands. 2002 bits<5> Sd; 2003 bits<5> Sm; 2004 2005 // Encode instruction operands. 2006 let Inst{3-0} = Sm{4-1}; 2007 let Inst{5} = Sm{0}; 2008 let Inst{15-12} = Sd{4-1}; 2009 let Inst{22} = Sd{0}; 2010 2011 let Inst{27-23} = opcod1; 2012 let Inst{21-20} = opcod2; 2013 let Inst{19-16} = opcod3; 2014 let Inst{11-8} = 0b1001; // Half precision 2015 let Inst{7-6} = opcod4; 2016 let Inst{4} = opcod5; 2017 2018 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2019} 2020 2021// Half precision, unary, non-predicated 2022class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 2023 bit opcod5, dag oops, dag iops, InstrItinClass itin, 2024 string asm, list<dag> pattern> 2025 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 2026 VFPUnaryFrm, itin, asm, "", pattern> { 2027 list<Predicate> Predicates = [HasFullFP16]; 2028 2029 // Instruction operands. 2030 bits<5> Sd; 2031 bits<5> Sm; 2032 2033 let Inst{31-28} = 0b1111; 2034 2035 // Encode instruction operands. 2036 let Inst{3-0} = Sm{4-1}; 2037 let Inst{5} = Sm{0}; 2038 let Inst{15-12} = Sd{4-1}; 2039 let Inst{22} = Sd{0}; 2040 2041 let Inst{27-23} = opcod1; 2042 let Inst{21-20} = opcod2; 2043 let Inst{19-16} = opcod3; 2044 let Inst{11-8} = 0b1001; // Half precision 2045 let Inst{7-6} = opcod4; 2046 let Inst{4} = opcod5; 2047 2048 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2049} 2050 2051// Half precision, binary 2052class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 2053 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2054 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 2055 list<Predicate> Predicates = [HasFullFP16]; 2056 2057 // Instruction operands. 2058 bits<5> Sd; 2059 bits<5> Sn; 2060 bits<5> Sm; 2061 2062 // Encode instruction operands. 2063 let Inst{3-0} = Sm{4-1}; 2064 let Inst{5} = Sm{0}; 2065 let Inst{19-16} = Sn{4-1}; 2066 let Inst{7} = Sn{0}; 2067 let Inst{15-12} = Sd{4-1}; 2068 let Inst{22} = Sd{0}; 2069 2070 let Inst{27-23} = opcod1; 2071 let Inst{21-20} = opcod2; 2072 let Inst{11-8} = 0b1001; // Half precision 2073 let Inst{6} = op6; 2074 let Inst{4} = op4; 2075 2076 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2077} 2078 2079// Half precision, binary, not predicated 2080class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 2081 InstrItinClass itin, string asm, list<dag> pattern> 2082 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 2083 VFPBinaryFrm, itin, asm, "", pattern> { 2084 list<Predicate> Predicates = [HasFullFP16]; 2085 2086 // Instruction operands. 2087 bits<5> Sd; 2088 bits<5> Sn; 2089 bits<5> Sm; 2090 2091 let Inst{31-28} = 0b1111; 2092 2093 // Encode instruction operands. 2094 let Inst{3-0} = Sm{4-1}; 2095 let Inst{5} = Sm{0}; 2096 let Inst{19-16} = Sn{4-1}; 2097 let Inst{7} = Sn{0}; 2098 let Inst{15-12} = Sd{4-1}; 2099 let Inst{22} = Sd{0}; 2100 2101 let Inst{27-23} = opcod1; 2102 let Inst{21-20} = opcod2; 2103 let Inst{11-8} = 0b1001; // Half precision 2104 let Inst{6} = opcod3; 2105 let Inst{4} = 0; 2106 2107 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2108} 2109 2110// VFP conversion instructions 2111class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 2112 dag oops, dag iops, InstrItinClass itin, string opc, string asm, 2113 list<dag> pattern> 2114 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> { 2115 let Inst{27-23} = opcod1; 2116 let Inst{21-20} = opcod2; 2117 let Inst{19-16} = opcod3; 2118 let Inst{11-8} = opcod4; 2119 let Inst{6} = 1; 2120 let Inst{4} = 0; 2121} 2122 2123// VFP conversion between floating-point and fixed-point 2124class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, 2125 dag oops, dag iops, InstrItinClass itin, string opc, string asm, 2126 list<dag> pattern> 2127 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> { 2128 bits<5> fbits; 2129 // size (fixed-point number): sx == 0 ? 16 : 32 2130 let Inst{7} = op5; // sx 2131 let Inst{5} = fbits{0}; 2132 let Inst{3-0} = fbits{4-1}; 2133} 2134 2135// VFP conversion instructions, if no NEON 2136class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 2137 dag oops, dag iops, InstrItinClass itin, 2138 string opc, string asm, list<dag> pattern> 2139 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 2140 pattern> { 2141 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 2142} 2143 2144class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 2145 InstrItinClass itin, 2146 string opc, string asm, list<dag> pattern> 2147 : VFPAI<oops, iops, f, itin, opc, asm, pattern> { 2148 let Inst{27-20} = opcod1; 2149 let Inst{11-8} = opcod2; 2150 let Inst{4} = 1; 2151} 2152 2153class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2154 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2155 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>; 2156 2157class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2158 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2159 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>; 2160 2161class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2162 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2163 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>; 2164 2165class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2166 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2167 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 2168 2169//===----------------------------------------------------------------------===// 2170 2171//===----------------------------------------------------------------------===// 2172// ARM NEON Instruction templates. 2173// 2174 2175class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2176 InstrItinClass itin, string opc, string dt, string asm, string cstr, 2177 list<dag> pattern> 2178 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2179 let OutOperandList = oops; 2180 let InOperandList = !con(iops, (ins pred:$p)); 2181 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2182 let Pattern = pattern; 2183 list<Predicate> Predicates = [HasNEON]; 2184 let DecoderNamespace = "NEON"; 2185} 2186 2187// Same as NeonI except it does not have a "data type" specifier. 2188class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2189 InstrItinClass itin, string opc, string asm, string cstr, 2190 list<dag> pattern> 2191 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2192 let OutOperandList = oops; 2193 let InOperandList = !con(iops, (ins pred:$p)); 2194 let AsmString = !strconcat(opc, "${p}", "\t", asm); 2195 let Pattern = pattern; 2196 list<Predicate> Predicates = [HasNEON]; 2197 let DecoderNamespace = "NEON"; 2198} 2199 2200// Same as NeonI except it is not predicated 2201class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2202 InstrItinClass itin, string opc, string dt, string asm, string cstr, 2203 list<dag> pattern> 2204 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2205 let OutOperandList = oops; 2206 let InOperandList = iops; 2207 let AsmString = !strconcat(opc, ".", dt, "\t", asm); 2208 let Pattern = pattern; 2209 list<Predicate> Predicates = [HasNEON]; 2210 let DecoderNamespace = "NEON"; 2211 2212 let Inst{31-28} = 0b1111; 2213} 2214 2215class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 2216 dag oops, dag iops, InstrItinClass itin, 2217 string opc, string dt, string asm, string cstr, list<dag> pattern> 2218 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm, 2219 cstr, pattern> { 2220 let Inst{31-24} = 0b11110100; 2221 let Inst{23} = op23; 2222 let Inst{21-20} = op21_20; 2223 let Inst{11-8} = op11_8; 2224 let Inst{7-4} = op7_4; 2225 2226 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; 2227 let DecoderNamespace = "NEONLoadStore"; 2228 2229 bits<5> Vd; 2230 bits<6> Rn; 2231 bits<4> Rm; 2232 2233 let Inst{22} = Vd{4}; 2234 let Inst{15-12} = Vd{3-0}; 2235 let Inst{19-16} = Rn{3-0}; 2236 let Inst{3-0} = Rm{3-0}; 2237} 2238 2239class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 2240 dag oops, dag iops, InstrItinClass itin, 2241 string opc, string dt, string asm, string cstr, list<dag> pattern> 2242 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc, 2243 dt, asm, cstr, pattern> { 2244 bits<3> lane; 2245} 2246 2247class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr> 2248 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 2249 itin> { 2250 let OutOperandList = oops; 2251 let InOperandList = !con(iops, (ins pred:$p)); 2252 list<Predicate> Predicates = [HasNEON]; 2253} 2254 2255class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr, 2256 list<dag> pattern> 2257 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 2258 itin> { 2259 let OutOperandList = oops; 2260 let InOperandList = !con(iops, (ins pred:$p)); 2261 let Pattern = pattern; 2262 list<Predicate> Predicates = [HasNEON]; 2263} 2264 2265class NDataI<dag oops, dag iops, Format f, InstrItinClass itin, 2266 string opc, string dt, string asm, string cstr, list<dag> pattern> 2267 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr, 2268 pattern> { 2269 let Inst{31-25} = 0b1111001; 2270 let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 2271 let DecoderNamespace = "NEONData"; 2272} 2273 2274class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin, 2275 string opc, string asm, string cstr, list<dag> pattern> 2276 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm, 2277 cstr, pattern> { 2278 let Inst{31-25} = 0b1111001; 2279 let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 2280 let DecoderNamespace = "NEONData"; 2281} 2282 2283// NEON "one register and a modified immediate" format. 2284class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 2285 bit op5, bit op4, 2286 dag oops, dag iops, InstrItinClass itin, 2287 string opc, string dt, string asm, string cstr, 2288 list<dag> pattern> 2289 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> { 2290 let Inst{23} = op23; 2291 let Inst{21-19} = op21_19; 2292 let Inst{11-8} = op11_8; 2293 let Inst{7} = op7; 2294 let Inst{6} = op6; 2295 let Inst{5} = op5; 2296 let Inst{4} = op4; 2297 2298 // Instruction operands. 2299 bits<5> Vd; 2300 bits<13> SIMM; 2301 2302 let Inst{15-12} = Vd{3-0}; 2303 let Inst{22} = Vd{4}; 2304 let Inst{24} = SIMM{7}; 2305 let Inst{18-16} = SIMM{6-4}; 2306 let Inst{3-0} = SIMM{3-0}; 2307 let DecoderMethod = "DecodeVMOVModImmInstruction"; 2308} 2309 2310// NEON 2 vector register format. 2311class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2312 bits<5> op11_7, bit op6, bit op4, 2313 dag oops, dag iops, InstrItinClass itin, 2314 string opc, string dt, string asm, string cstr, list<dag> pattern> 2315 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> { 2316 let Inst{24-23} = op24_23; 2317 let Inst{21-20} = op21_20; 2318 let Inst{19-18} = op19_18; 2319 let Inst{17-16} = op17_16; 2320 let Inst{11-7} = op11_7; 2321 let Inst{6} = op6; 2322 let Inst{4} = op4; 2323 2324 // Instruction operands. 2325 bits<5> Vd; 2326 bits<5> Vm; 2327 2328 let Inst{15-12} = Vd{3-0}; 2329 let Inst{22} = Vd{4}; 2330 let Inst{3-0} = Vm{3-0}; 2331 let Inst{5} = Vm{4}; 2332} 2333 2334// Same as N2V but not predicated. 2335class N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 2336 dag oops, dag iops, InstrItinClass itin, string OpcodeStr, 2337 string Dt, list<dag> pattern> 2338 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin, 2339 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> { 2340 bits<5> Vd; 2341 bits<5> Vm; 2342 2343 // Encode instruction operands 2344 let Inst{22} = Vd{4}; 2345 let Inst{15-12} = Vd{3-0}; 2346 let Inst{5} = Vm{4}; 2347 let Inst{3-0} = Vm{3-0}; 2348 2349 // Encode constant bits 2350 let Inst{27-23} = 0b00111; 2351 let Inst{21-20} = 0b11; 2352 let Inst{19-18} = op19_18; 2353 let Inst{17-16} = op17_16; 2354 let Inst{11} = 0; 2355 let Inst{10-8} = op10_8; 2356 let Inst{7} = op7; 2357 let Inst{6} = op6; 2358 let Inst{4} = 0; 2359 2360 let DecoderNamespace = "NEON"; 2361} 2362 2363// Same as N2V except it doesn't have a datatype suffix. 2364class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2365 bits<5> op11_7, bit op6, bit op4, 2366 dag oops, dag iops, InstrItinClass itin, 2367 string opc, string asm, string cstr, list<dag> pattern> 2368 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> { 2369 let Inst{24-23} = op24_23; 2370 let Inst{21-20} = op21_20; 2371 let Inst{19-18} = op19_18; 2372 let Inst{17-16} = op17_16; 2373 let Inst{11-7} = op11_7; 2374 let Inst{6} = op6; 2375 let Inst{4} = op4; 2376 2377 // Instruction operands. 2378 bits<5> Vd; 2379 bits<5> Vm; 2380 2381 let Inst{15-12} = Vd{3-0}; 2382 let Inst{22} = Vd{4}; 2383 let Inst{3-0} = Vm{3-0}; 2384 let Inst{5} = Vm{4}; 2385} 2386 2387// NEON 2 vector register with immediate. 2388class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2389 dag oops, dag iops, Format f, InstrItinClass itin, 2390 string opc, string dt, string asm, string cstr, list<dag> pattern> 2391 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2392 let Inst{24} = op24; 2393 let Inst{23} = op23; 2394 let Inst{11-8} = op11_8; 2395 let Inst{7} = op7; 2396 let Inst{6} = op6; 2397 let Inst{4} = op4; 2398 2399 // Instruction operands. 2400 bits<5> Vd; 2401 bits<5> Vm; 2402 bits<6> SIMM; 2403 2404 let Inst{15-12} = Vd{3-0}; 2405 let Inst{22} = Vd{4}; 2406 let Inst{3-0} = Vm{3-0}; 2407 let Inst{5} = Vm{4}; 2408 let Inst{21-16} = SIMM{5-0}; 2409} 2410 2411// NEON 3 vector register format. 2412 2413class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2414 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2415 string opc, string dt, string asm, string cstr, 2416 list<dag> pattern> 2417 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2418 let Inst{24} = op24; 2419 let Inst{23} = op23; 2420 let Inst{21-20} = op21_20; 2421 let Inst{11-8} = op11_8; 2422 let Inst{6} = op6; 2423 let Inst{4} = op4; 2424} 2425 2426class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 2427 dag oops, dag iops, Format f, InstrItinClass itin, 2428 string opc, string dt, string asm, string cstr, list<dag> pattern> 2429 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2430 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2431 // Instruction operands. 2432 bits<5> Vd; 2433 bits<5> Vn; 2434 bits<5> Vm; 2435 2436 let Inst{15-12} = Vd{3-0}; 2437 let Inst{22} = Vd{4}; 2438 let Inst{19-16} = Vn{3-0}; 2439 let Inst{7} = Vn{4}; 2440 let Inst{3-0} = Vm{3-0}; 2441 let Inst{5} = Vm{4}; 2442} 2443 2444class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2445 bit op4, dag oops, dag iops,Format f, InstrItinClass itin, 2446 string OpcodeStr, string Dt, list<dag> pattern> 2447 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr, 2448 Dt, "$Vd, $Vn, $Vm", "", pattern> { 2449 bits<5> Vd; 2450 bits<5> Vn; 2451 bits<5> Vm; 2452 2453 // Encode instruction operands 2454 let Inst{22} = Vd{4}; 2455 let Inst{15-12} = Vd{3-0}; 2456 let Inst{19-16} = Vn{3-0}; 2457 let Inst{7} = Vn{4}; 2458 let Inst{5} = Vm{4}; 2459 let Inst{3-0} = Vm{3-0}; 2460 2461 // Encode constant bits 2462 let Inst{27-23} = op27_23; 2463 let Inst{21-20} = op21_20; 2464 let Inst{11-8} = op11_8; 2465 let Inst{6} = op6; 2466 let Inst{4} = op4; 2467} 2468 2469class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2470 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2471 string opc, string dt, string asm, string cstr, 2472 list<dag> pattern> 2473 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2474 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2475 2476 // Instruction operands. 2477 bits<5> Vd; 2478 bits<5> Vn; 2479 bits<5> Vm; 2480 bit lane; 2481 2482 let Inst{15-12} = Vd{3-0}; 2483 let Inst{22} = Vd{4}; 2484 let Inst{19-16} = Vn{3-0}; 2485 let Inst{7} = Vn{4}; 2486 let Inst{3-0} = Vm{3-0}; 2487 let Inst{5} = lane; 2488} 2489 2490class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2491 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2492 string opc, string dt, string asm, string cstr, 2493 list<dag> pattern> 2494 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2495 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2496 2497 // Instruction operands. 2498 bits<5> Vd; 2499 bits<5> Vn; 2500 bits<5> Vm; 2501 bits<2> lane; 2502 2503 let Inst{15-12} = Vd{3-0}; 2504 let Inst{22} = Vd{4}; 2505 let Inst{19-16} = Vn{3-0}; 2506 let Inst{7} = Vn{4}; 2507 let Inst{2-0} = Vm{2-0}; 2508 let Inst{5} = lane{1}; 2509 let Inst{3} = lane{0}; 2510} 2511 2512// Same as N3V except it doesn't have a data type suffix. 2513class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2514 bit op4, 2515 dag oops, dag iops, Format f, InstrItinClass itin, 2516 string opc, string asm, string cstr, list<dag> pattern> 2517 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> { 2518 let Inst{24} = op24; 2519 let Inst{23} = op23; 2520 let Inst{21-20} = op21_20; 2521 let Inst{11-8} = op11_8; 2522 let Inst{6} = op6; 2523 let Inst{4} = op4; 2524 2525 // Instruction operands. 2526 bits<5> Vd; 2527 bits<5> Vn; 2528 bits<5> Vm; 2529 2530 let Inst{15-12} = Vd{3-0}; 2531 let Inst{22} = Vd{4}; 2532 let Inst{19-16} = Vn{3-0}; 2533 let Inst{7} = Vn{4}; 2534 let Inst{3-0} = Vm{3-0}; 2535 let Inst{5} = Vm{4}; 2536} 2537 2538// NEON VMOVs between scalar and core registers. 2539class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2540 dag oops, dag iops, Format f, InstrItinClass itin, 2541 string opc, string dt, string asm, list<dag> pattern> 2542 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain, 2543 "", itin> { 2544 let Inst{27-20} = opcod1; 2545 let Inst{11-8} = opcod2; 2546 let Inst{6-5} = opcod3; 2547 let Inst{4} = 1; 2548 // A8.6.303, A8.6.328, A8.6.329 2549 let Inst{3-0} = 0b0000; 2550 2551 let OutOperandList = oops; 2552 let InOperandList = !con(iops, (ins pred:$p)); 2553 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2554 let Pattern = pattern; 2555 list<Predicate> Predicates = [HasNEON]; 2556 2557 let PostEncoderMethod = "NEONThumb2DupPostEncoder"; 2558 let DecoderNamespace = "NEONDup"; 2559 2560 bits<5> V; 2561 bits<4> R; 2562 bits<4> p; 2563 bits<4> lane; 2564 2565 let Inst{31-28} = p{3-0}; 2566 let Inst{7} = V{4}; 2567 let Inst{19-16} = V{3-0}; 2568 let Inst{15-12} = R{3-0}; 2569} 2570class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2571 dag oops, dag iops, InstrItinClass itin, 2572 string opc, string dt, string asm, list<dag> pattern> 2573 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin, 2574 opc, dt, asm, pattern>; 2575class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2576 dag oops, dag iops, InstrItinClass itin, 2577 string opc, string dt, string asm, list<dag> pattern> 2578 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin, 2579 opc, dt, asm, pattern>; 2580class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2581 dag oops, dag iops, InstrItinClass itin, 2582 string opc, string dt, string asm, list<dag> pattern> 2583 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin, 2584 opc, dt, asm, pattern>; 2585 2586// Vector Duplicate Lane (from scalar to all elements) 2587class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops, 2588 InstrItinClass itin, string opc, string dt, string asm, 2589 list<dag> pattern> 2590 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> { 2591 let Inst{24-23} = 0b11; 2592 let Inst{21-20} = 0b11; 2593 let Inst{19-16} = op19_16; 2594 let Inst{11-7} = 0b11000; 2595 let Inst{6} = op6; 2596 let Inst{4} = 0; 2597 2598 bits<5> Vd; 2599 bits<5> Vm; 2600 2601 let Inst{22} = Vd{4}; 2602 let Inst{15-12} = Vd{3-0}; 2603 let Inst{5} = Vm{4}; 2604 let Inst{3-0} = Vm{3-0}; 2605} 2606 2607// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 2608// for single-precision FP. 2609class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 2610 list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 2611} 2612 2613// VFP/NEON Instruction aliases for type suffices. 2614// Note: When EmitPriority == 1, the alias will be used for printing 2615class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> : 2616 InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasFPRegs]>; 2617 2618// Note: When EmitPriority == 1, the alias will be used for printing 2619multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 2620 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 2621 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 2622 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 2623 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 2624} 2625 2626// Note: When EmitPriority == 1, the alias will be used for printing 2627multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 2628 let Predicates = [HasNEON] in { 2629 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 2630 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 2631 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 2632 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 2633} 2634} 2635 2636// The same alias classes using AsmPseudo instead, for the more complex 2637// stuff in NEON that InstAlias can't quite handle. 2638// Note that we can't use anonymous defm references here like we can 2639// above, as we care about the ultimate instruction enum names generated, unlike 2640// for instalias defs. 2641class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> : 2642 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>; 2643 2644// Extension of NEON 3-vector data processing instructions in coprocessor 8 2645// encoding space, introduced in ARMv8.3-A. 2646class N3VCP8<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 2647 dag oops, dag iops, InstrItinClass itin, 2648 string opc, string dt, string asm, string cstr, list<dag> pattern> 2649 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 2650 dt, asm, cstr, pattern> { 2651 bits<5> Vd; 2652 bits<5> Vn; 2653 bits<5> Vm; 2654 2655 let DecoderNamespace = "VFPV8"; 2656 // These have the same encodings in ARM and Thumb2 2657 let PostEncoderMethod = ""; 2658 2659 let Inst{31-25} = 0b1111110; 2660 let Inst{24-23} = op24_23; 2661 let Inst{22} = Vd{4}; 2662 let Inst{21-20} = op21_20; 2663 let Inst{19-16} = Vn{3-0}; 2664 let Inst{15-12} = Vd{3-0}; 2665 let Inst{11-8} = 0b1000; 2666 let Inst{7} = Vn{4}; 2667 let Inst{6} = op6; 2668 let Inst{5} = Vm{4}; 2669 let Inst{4} = op4; 2670 let Inst{3-0} = Vm{3-0}; 2671} 2672 2673// Extension of NEON 2-vector-and-scalar data processing instructions in 2674// coprocessor 8 encoding space, introduced in ARMv8.3-A. 2675class N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4, 2676 dag oops, dag iops, InstrItinClass itin, 2677 string opc, string dt, string asm, string cstr, list<dag> pattern> 2678 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 2679 dt, asm, cstr, pattern> { 2680 bits<5> Vd; 2681 bits<5> Vn; 2682 bits<5> Vm; 2683 2684 let DecoderNamespace = "VFPV8"; 2685 // These have the same encodings in ARM and Thumb2 2686 let PostEncoderMethod = ""; 2687 2688 let Inst{31-24} = 0b11111110; 2689 let Inst{23} = op23; 2690 let Inst{22} = Vd{4}; 2691 let Inst{21-20} = op21_20; 2692 let Inst{19-16} = Vn{3-0}; 2693 let Inst{15-12} = Vd{3-0}; 2694 let Inst{11-8} = 0b1000; 2695 let Inst{7} = Vn{4}; 2696 let Inst{6} = op6; 2697 // Bit 5 set by sub-classes 2698 let Inst{4} = op4; 2699 let Inst{3-0} = Vm{3-0}; 2700} 2701 2702// In Armv8.2-A, some NEON instructions are added that encode Vn and Vm 2703// differently: 2704// if Q == ‘1’ then UInt(N:Vn) else UInt(Vn:N); 2705// if Q == ‘1’ then UInt(M:Vm) else UInt(Vm:M); 2706// Class N3VCP8 above describes the Q=1 case, and this class the Q=0 case. 2707class N3VCP8Q0<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 2708 dag oops, dag iops, InstrItinClass itin, 2709 string opc, string dt, string asm, string cstr, list<dag> pattern> 2710 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, dt, asm, cstr, pattern> { 2711 bits<5> Vd; 2712 bits<5> Vn; 2713 bits<5> Vm; 2714 2715 let DecoderNamespace = "VFPV8"; 2716 // These have the same encodings in ARM and Thumb2 2717 let PostEncoderMethod = ""; 2718 2719 let Inst{31-25} = 0b1111110; 2720 let Inst{24-23} = op24_23; 2721 let Inst{22} = Vd{4}; 2722 let Inst{21-20} = op21_20; 2723 let Inst{19-16} = Vn{4-1}; 2724 let Inst{15-12} = Vd{3-0}; 2725 let Inst{11-8} = 0b1000; 2726 let Inst{7} = Vn{0}; 2727 let Inst{6} = op6; 2728 let Inst{5} = Vm{0}; 2729 let Inst{4} = op4; 2730 let Inst{3-0} = Vm{4-1}; 2731} 2732 2733// Operand types for complex instructions 2734class ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag> 2735 : AsmOperandClass { 2736 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 2737 let DiagnosticString = "complex rotation must be " # Diag; 2738 let Name = "ComplexRotation" # Type; 2739} 2740def complexrotateop : Operand<i32> { 2741 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">; 2742 let PrintMethod = "printComplexRotationOp<90, 0>"; 2743} 2744def complexrotateopodd : Operand<i32> { 2745 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">; 2746 let PrintMethod = "printComplexRotationOp<180, 90>"; 2747} 2748 2749def MveSaturateOperand : AsmOperandClass { 2750 let PredicateMethod = "isMveSaturateOp"; 2751 let DiagnosticString = "saturate operand must be 48 or 64"; 2752 let Name = "MveSaturate"; 2753} 2754def saturateop : Operand<i32> { 2755 let ParserMatchClass = MveSaturateOperand; 2756 let PrintMethod = "printMveSaturateOp"; 2757} 2758 2759// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM. 2760def : TokenAlias<".s8", ".i8">; 2761def : TokenAlias<".u8", ".i8">; 2762def : TokenAlias<".s16", ".i16">; 2763def : TokenAlias<".u16", ".i16">; 2764def : TokenAlias<".s32", ".i32">; 2765def : TokenAlias<".u32", ".i32">; 2766def : TokenAlias<".s64", ".i64">; 2767def : TokenAlias<".u64", ".i64">; 2768 2769def : TokenAlias<".i8", ".8">; 2770def : TokenAlias<".i16", ".16">; 2771def : TokenAlias<".i32", ".32">; 2772def : TokenAlias<".i64", ".64">; 2773 2774def : TokenAlias<".p8", ".8">; 2775def : TokenAlias<".p16", ".16">; 2776 2777def : TokenAlias<".f32", ".32">; 2778def : TokenAlias<".f64", ".64">; 2779def : TokenAlias<".f", ".f32">; 2780def : TokenAlias<".d", ".f64">; 2781