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