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