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