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 FP16Pat<dag pattern, dag result> : Pat<pattern, result> { 1132 list<Predicate> Predicates = [HasFP16]; 1133} 1134class FullFP16Pat<dag pattern, dag result> : Pat<pattern, result> { 1135 list<Predicate> Predicates = [HasFullFP16]; 1136} 1137//===----------------------------------------------------------------------===// 1138// Thumb Instruction Format Definitions. 1139// 1140 1141class ThumbI<dag oops, dag iops, AddrMode am, int sz, 1142 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1143 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1144 let OutOperandList = oops; 1145 let InOperandList = iops; 1146 let AsmString = asm; 1147 let Pattern = pattern; 1148 list<Predicate> Predicates = [IsThumb]; 1149} 1150 1151// TI - Thumb instruction. 1152class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 1153 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1154 1155// Two-address instructions 1156class TIt<dag oops, dag iops, InstrItinClass itin, string asm, 1157 list<dag> pattern> 1158 : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst", 1159 pattern>; 1160 1161// tBL, tBX 32-bit instructions 1162class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3, 1163 dag oops, dag iops, InstrItinClass itin, string asm, 1164 list<dag> pattern> 1165 : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>, 1166 Encoding { 1167 let Inst{31-27} = opcod1; 1168 let Inst{15-14} = opcod2; 1169 let Inst{12} = opcod3; 1170} 1171 1172// BR_JT instructions 1173class TJTI<dag oops, dag iops, InstrItinClass itin, string asm, 1174 list<dag> pattern> 1175 : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1176 1177// Thumb1 only 1178class Thumb1I<dag oops, dag iops, AddrMode am, int sz, 1179 InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1180 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1181 let OutOperandList = oops; 1182 let InOperandList = iops; 1183 let AsmString = asm; 1184 let Pattern = pattern; 1185 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1186} 1187 1188class T1I<dag oops, dag iops, InstrItinClass itin, 1189 string asm, list<dag> pattern> 1190 : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1191class T1Ix2<dag oops, dag iops, InstrItinClass itin, 1192 string asm, list<dag> pattern> 1193 : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1194 1195// Two-address instructions 1196class T1It<dag oops, dag iops, InstrItinClass itin, 1197 string asm, string cstr, list<dag> pattern> 1198 : Thumb1I<oops, iops, AddrModeNone, 2, itin, 1199 asm, cstr, pattern>; 1200 1201// Thumb1 instruction that can either be predicated or set CPSR. 1202class Thumb1sI<dag oops, dag iops, AddrMode am, int sz, 1203 InstrItinClass itin, 1204 string opc, string asm, string cstr, list<dag> pattern> 1205 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1206 let OutOperandList = !con(oops, (outs s_cc_out:$s)); 1207 let InOperandList = !con(iops, (ins pred:$p)); 1208 let AsmString = !strconcat(opc, "${s}${p}", asm); 1209 let Pattern = pattern; 1210 let thumbArithFlagSetting = 1; 1211 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1212 let DecoderNamespace = "ThumbSBit"; 1213} 1214 1215class T1sI<dag oops, dag iops, InstrItinClass itin, 1216 string opc, string asm, list<dag> pattern> 1217 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1218 1219// Two-address instructions 1220class T1sIt<dag oops, dag iops, InstrItinClass itin, 1221 string opc, string asm, list<dag> pattern> 1222 : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1223 "$Rn = $Rdn", pattern>; 1224 1225// Thumb1 instruction that can be predicated. 1226class Thumb1pI<dag oops, dag iops, AddrMode am, int sz, 1227 InstrItinClass itin, 1228 string opc, string asm, string cstr, list<dag> pattern> 1229 : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1230 let OutOperandList = oops; 1231 let InOperandList = !con(iops, (ins pred:$p)); 1232 let AsmString = !strconcat(opc, "${p}", asm); 1233 let Pattern = pattern; 1234 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1235} 1236 1237class T1pI<dag oops, dag iops, InstrItinClass itin, 1238 string opc, string asm, list<dag> pattern> 1239 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1240 1241// Two-address instructions 1242class T1pIt<dag oops, dag iops, InstrItinClass itin, 1243 string opc, string asm, list<dag> pattern> 1244 : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1245 "$Rn = $Rdn", pattern>; 1246 1247class T1pIs<dag oops, dag iops, 1248 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1249 : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>; 1250 1251class Encoding16 : Encoding { 1252 let Inst{31-16} = 0x0000; 1253} 1254 1255// A6.2 16-bit Thumb instruction encoding 1256class T1Encoding<bits<6> opcode> : Encoding16 { 1257 let Inst{15-10} = opcode; 1258} 1259 1260// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. 1261class T1General<bits<5> opcode> : Encoding16 { 1262 let Inst{15-14} = 0b00; 1263 let Inst{13-9} = opcode; 1264} 1265 1266// A6.2.2 Data-processing encoding. 1267class T1DataProcessing<bits<4> opcode> : Encoding16 { 1268 let Inst{15-10} = 0b010000; 1269 let Inst{9-6} = opcode; 1270} 1271 1272// A6.2.3 Special data instructions and branch and exchange encoding. 1273class T1Special<bits<4> opcode> : Encoding16 { 1274 let Inst{15-10} = 0b010001; 1275 let Inst{9-6} = opcode; 1276} 1277 1278// A6.2.4 Load/store single data item encoding. 1279class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 { 1280 let Inst{15-12} = opA; 1281 let Inst{11-9} = opB; 1282} 1283class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative 1284 1285class T1BranchCond<bits<4> opcode> : Encoding16 { 1286 let Inst{15-12} = opcode; 1287} 1288 1289// Helper classes to encode Thumb1 loads and stores. For immediates, the 1290// following bits are used for "opA" (see A6.2.4): 1291// 1292// 0b0110 => Immediate, 4 bytes 1293// 0b1000 => Immediate, 2 bytes 1294// 0b0111 => Immediate, 1 byte 1295class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am, 1296 InstrItinClass itin, string opc, string asm, 1297 list<dag> pattern> 1298 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1299 T1LoadStore<0b0101, opcode> { 1300 bits<3> Rt; 1301 bits<8> addr; 1302 let Inst{8-6} = addr{5-3}; // Rm 1303 let Inst{5-3} = addr{2-0}; // Rn 1304 let Inst{2-0} = Rt; 1305} 1306class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am, 1307 InstrItinClass itin, string opc, string asm, 1308 list<dag> pattern> 1309 : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1310 T1LoadStore<opA, {opB,?,?}> { 1311 bits<3> Rt; 1312 bits<8> addr; 1313 let Inst{10-6} = addr{7-3}; // imm5 1314 let Inst{5-3} = addr{2-0}; // Rn 1315 let Inst{2-0} = Rt; 1316} 1317 1318// A6.2.5 Miscellaneous 16-bit instructions encoding. 1319class T1Misc<bits<7> opcode> : Encoding16 { 1320 let Inst{15-12} = 0b1011; 1321 let Inst{11-5} = opcode; 1322} 1323 1324// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 1325class Thumb2I<dag oops, dag iops, AddrMode am, int sz, 1326 InstrItinClass itin, 1327 string opc, string asm, string cstr, list<dag> pattern> 1328 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1329 let OutOperandList = oops; 1330 let InOperandList = !con(iops, (ins pred:$p)); 1331 let AsmString = !strconcat(opc, "${p}", asm); 1332 let Pattern = pattern; 1333 list<Predicate> Predicates = [IsThumb2]; 1334 let DecoderNamespace = "Thumb2"; 1335} 1336 1337// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an 1338// input operand since by default it's a zero register. It will become an 1339// implicit def once it's "flipped". 1340// 1341// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 1342// more consistent. 1343class Thumb2sI<dag oops, dag iops, AddrMode am, int sz, 1344 InstrItinClass itin, 1345 string opc, string asm, string cstr, list<dag> pattern> 1346 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1347 bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 1348 let Inst{20} = s; 1349 1350 let OutOperandList = oops; 1351 let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 1352 let AsmString = !strconcat(opc, "${s}${p}", asm); 1353 let Pattern = pattern; 1354 list<Predicate> Predicates = [IsThumb2]; 1355 let DecoderNamespace = "Thumb2"; 1356} 1357 1358// Special cases 1359class Thumb2XI<dag oops, dag iops, AddrMode am, int sz, 1360 InstrItinClass itin, 1361 string asm, string cstr, list<dag> pattern> 1362 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1363 let OutOperandList = oops; 1364 let InOperandList = iops; 1365 let AsmString = asm; 1366 let Pattern = pattern; 1367 list<Predicate> Predicates = [IsThumb2]; 1368 let DecoderNamespace = "Thumb2"; 1369} 1370 1371class ThumbXI<dag oops, dag iops, AddrMode am, int sz, 1372 InstrItinClass itin, 1373 string asm, string cstr, list<dag> pattern> 1374 : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1375 let OutOperandList = oops; 1376 let InOperandList = iops; 1377 let AsmString = asm; 1378 let Pattern = pattern; 1379 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1380 let DecoderNamespace = "Thumb"; 1381} 1382 1383class T2I<dag oops, dag iops, InstrItinClass itin, 1384 string opc, string asm, list<dag> pattern> 1385 : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1386class T2Ii12<dag oops, dag iops, InstrItinClass itin, 1387 string opc, string asm, list<dag> pattern> 1388 : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>; 1389class T2Ii8<dag oops, dag iops, InstrItinClass itin, 1390 string opc, string asm, list<dag> pattern> 1391 : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>; 1392class T2Iso<dag oops, dag iops, InstrItinClass itin, 1393 string opc, string asm, list<dag> pattern> 1394 : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>; 1395class T2Ipc<dag oops, dag iops, InstrItinClass itin, 1396 string opc, string asm, list<dag> pattern> 1397 : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>; 1398class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin, 1399 string opc, string asm, string cstr, list<dag> pattern> 1400 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1401 pattern> { 1402 bits<4> Rt; 1403 bits<4> Rt2; 1404 bits<13> addr; 1405 let Inst{31-25} = 0b1110100; 1406 let Inst{24} = P; 1407 let Inst{23} = addr{8}; 1408 let Inst{22} = 1; 1409 let Inst{21} = W; 1410 let Inst{20} = isLoad; 1411 let Inst{19-16} = addr{12-9}; 1412 let Inst{15-12} = Rt{3-0}; 1413 let Inst{11-8} = Rt2{3-0}; 1414 let Inst{7-0} = addr{7-0}; 1415} 1416class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops, 1417 InstrItinClass itin, string opc, string asm, string cstr, 1418 list<dag> pattern> 1419 : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1420 pattern> { 1421 bits<4> Rt; 1422 bits<4> Rt2; 1423 bits<4> addr; 1424 bits<9> imm; 1425 let Inst{31-25} = 0b1110100; 1426 let Inst{24} = P; 1427 let Inst{23} = imm{8}; 1428 let Inst{22} = 1; 1429 let Inst{21} = W; 1430 let Inst{20} = isLoad; 1431 let Inst{19-16} = addr; 1432 let Inst{15-12} = Rt{3-0}; 1433 let Inst{11-8} = Rt2{3-0}; 1434 let Inst{7-0} = imm{7-0}; 1435} 1436 1437class T2sI<dag oops, dag iops, InstrItinClass itin, 1438 string opc, string asm, list<dag> pattern> 1439 : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1440 1441class T2XI<dag oops, dag iops, InstrItinClass itin, 1442 string asm, list<dag> pattern> 1443 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1444class T2JTI<dag oops, dag iops, InstrItinClass itin, 1445 string asm, list<dag> pattern> 1446 : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1447 1448// Move to/from coprocessor instructions 1449class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm, 1450 list<dag> pattern> 1451 : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> { 1452 let Inst{31-28} = opc; 1453} 1454 1455// Two-address instructions 1456class T2XIt<dag oops, dag iops, InstrItinClass itin, 1457 string asm, string cstr, list<dag> pattern> 1458 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>; 1459 1460// T2Ipreldst - Thumb2 pre-indexed load / store instructions. 1461class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre, 1462 dag oops, dag iops, 1463 AddrMode am, IndexMode im, InstrItinClass itin, 1464 string opc, string asm, string cstr, list<dag> pattern> 1465 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1466 let OutOperandList = oops; 1467 let InOperandList = !con(iops, (ins pred:$p)); 1468 let AsmString = !strconcat(opc, "${p}", asm); 1469 let Pattern = pattern; 1470 list<Predicate> Predicates = [IsThumb2]; 1471 let DecoderNamespace = "Thumb2"; 1472 1473 bits<4> Rt; 1474 bits<13> addr; 1475 let Inst{31-27} = 0b11111; 1476 let Inst{26-25} = 0b00; 1477 let Inst{24} = signed; 1478 let Inst{23} = 0; 1479 let Inst{22-21} = opcod; 1480 let Inst{20} = load; 1481 let Inst{19-16} = addr{12-9}; 1482 let Inst{15-12} = Rt{3-0}; 1483 let Inst{11} = 1; 1484 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1485 let Inst{10} = pre; // The P bit. 1486 let Inst{9} = addr{8}; // Sign bit 1487 let Inst{8} = 1; // The W bit. 1488 let Inst{7-0} = addr{7-0}; 1489 1490 let DecoderMethod = "DecodeT2LdStPre"; 1491} 1492 1493// T2Ipostldst - Thumb2 post-indexed load / store instructions. 1494class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, 1495 dag oops, dag iops, 1496 AddrMode am, IndexMode im, InstrItinClass itin, 1497 string opc, string asm, string cstr, list<dag> pattern> 1498 : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1499 let OutOperandList = oops; 1500 let InOperandList = !con(iops, (ins pred:$p)); 1501 let AsmString = !strconcat(opc, "${p}", asm); 1502 let Pattern = pattern; 1503 list<Predicate> Predicates = [IsThumb2]; 1504 let DecoderNamespace = "Thumb2"; 1505 1506 bits<4> Rt; 1507 bits<4> Rn; 1508 bits<9> offset; 1509 let Inst{31-27} = 0b11111; 1510 let Inst{26-25} = 0b00; 1511 let Inst{24} = signed; 1512 let Inst{23} = 0; 1513 let Inst{22-21} = opcod; 1514 let Inst{20} = load; 1515 let Inst{19-16} = Rn; 1516 let Inst{15-12} = Rt{3-0}; 1517 let Inst{11} = 1; 1518 // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1519 let Inst{10} = pre; // The P bit. 1520 let Inst{9} = offset{8}; // Sign bit 1521 let Inst{8} = 1; // The W bit. 1522 let Inst{7-0} = offset{7-0}; 1523 1524 let DecoderMethod = "DecodeT2LdStPre"; 1525} 1526 1527// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 1528class T1Pat<dag pattern, dag result> : Pat<pattern, result> { 1529 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1530} 1531 1532// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode. 1533class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> { 1534 list<Predicate> Predicates = [IsThumb2, HasV6T2]; 1535} 1536 1537// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 1538class T2Pat<dag pattern, dag result> : Pat<pattern, result> { 1539 list<Predicate> Predicates = [IsThumb2]; 1540} 1541 1542//===----------------------------------------------------------------------===// 1543 1544//===----------------------------------------------------------------------===// 1545// ARM VFP Instruction templates. 1546// 1547 1548// Almost all VFP instructions are predicable. 1549class VFPI<dag oops, dag iops, AddrMode am, int sz, 1550 IndexMode im, Format f, InstrItinClass itin, 1551 string opc, string asm, string cstr, list<dag> pattern> 1552 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1553 bits<4> p; 1554 let Inst{31-28} = p; 1555 let OutOperandList = oops; 1556 let InOperandList = !con(iops, (ins pred:$p)); 1557 let AsmString = !strconcat(opc, "${p}", asm); 1558 let Pattern = pattern; 1559 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1560 let DecoderNamespace = "VFP"; 1561 list<Predicate> Predicates = [HasVFP2]; 1562} 1563 1564// Special cases 1565class VFPXI<dag oops, dag iops, AddrMode am, int sz, 1566 IndexMode im, Format f, InstrItinClass itin, 1567 string asm, string cstr, list<dag> pattern> 1568 : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1569 bits<4> p; 1570 let Inst{31-28} = p; 1571 let OutOperandList = oops; 1572 let InOperandList = iops; 1573 let AsmString = asm; 1574 let Pattern = pattern; 1575 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1576 let DecoderNamespace = "VFP"; 1577 list<Predicate> Predicates = [HasVFP2]; 1578} 1579 1580class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 1581 string opc, string asm, list<dag> pattern> 1582 : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 1583 opc, asm, "", pattern> { 1584 let PostEncoderMethod = "VFPThumb2PostEncoder"; 1585} 1586 1587// ARM VFP addrmode5 loads and stores 1588class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1589 InstrItinClass itin, 1590 string opc, string asm, list<dag> pattern> 1591 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1592 VFPLdStFrm, itin, opc, asm, "", pattern> { 1593 // Instruction operands. 1594 bits<5> Dd; 1595 bits<13> addr; 1596 1597 // Encode instruction operands. 1598 let Inst{23} = addr{8}; // U (add = (U == '1')) 1599 let Inst{22} = Dd{4}; 1600 let Inst{19-16} = addr{12-9}; // Rn 1601 let Inst{15-12} = Dd{3-0}; 1602 let Inst{7-0} = addr{7-0}; // imm8 1603 1604 let Inst{27-24} = opcod1; 1605 let Inst{21-20} = opcod2; 1606 let Inst{11-9} = 0b101; 1607 let Inst{8} = 1; // Double precision 1608 1609 // Loads & stores operate on both NEON and VFP pipelines. 1610 let D = VFPNeonDomain; 1611} 1612 1613class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1614 InstrItinClass itin, 1615 string opc, string asm, list<dag> pattern> 1616 : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1617 VFPLdStFrm, itin, opc, asm, "", pattern> { 1618 // Instruction operands. 1619 bits<5> Sd; 1620 bits<13> addr; 1621 1622 // Encode instruction operands. 1623 let Inst{23} = addr{8}; // U (add = (U == '1')) 1624 let Inst{22} = Sd{0}; 1625 let Inst{19-16} = addr{12-9}; // Rn 1626 let Inst{15-12} = Sd{4-1}; 1627 let Inst{7-0} = addr{7-0}; // imm8 1628 1629 let Inst{27-24} = opcod1; 1630 let Inst{21-20} = opcod2; 1631 let Inst{11-9} = 0b101; 1632 let Inst{8} = 0; // Single precision 1633 1634 // Loads & stores operate on both NEON and VFP pipelines. 1635 let D = VFPNeonDomain; 1636} 1637 1638class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1639 InstrItinClass itin, 1640 string opc, string asm, list<dag> pattern> 1641 : VFPI<oops, iops, AddrMode5FP16, 4, IndexModeNone, 1642 VFPLdStFrm, itin, opc, asm, "", pattern> { 1643 list<Predicate> Predicates = [HasFullFP16]; 1644 1645 // Instruction operands. 1646 bits<5> Sd; 1647 bits<13> addr; 1648 1649 // Encode instruction operands. 1650 let Inst{23} = addr{8}; // U (add = (U == '1')) 1651 let Inst{22} = Sd{0}; 1652 let Inst{19-16} = addr{12-9}; // Rn 1653 let Inst{15-12} = Sd{4-1}; 1654 let Inst{7-0} = addr{7-0}; // imm8 1655 1656 let Inst{27-24} = opcod1; 1657 let Inst{21-20} = opcod2; 1658 let Inst{11-8} = 0b1001; // Half precision 1659 1660 // Loads & stores operate on both NEON and VFP pipelines. 1661 let D = VFPNeonDomain; 1662 1663 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 1664} 1665 1666// VFP Load / store multiple pseudo instructions. 1667class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, 1668 list<dag> pattern> 1669 : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain, 1670 cstr, itin> { 1671 let OutOperandList = oops; 1672 let InOperandList = !con(iops, (ins pred:$p)); 1673 let Pattern = pattern; 1674 list<Predicate> Predicates = [HasVFP2]; 1675} 1676 1677// Load / store multiple 1678 1679// Unknown precision 1680class AXXI4<dag oops, dag iops, IndexMode im, 1681 string asm, string cstr, list<dag> pattern> 1682 : VFPXI<oops, iops, AddrMode4, 4, im, 1683 VFPLdStFrm, NoItinerary, asm, cstr, pattern> { 1684 // Instruction operands. 1685 bits<4> Rn; 1686 bits<13> regs; 1687 1688 // Encode instruction operands. 1689 let Inst{19-16} = Rn; 1690 let Inst{22} = 0; 1691 let Inst{15-12} = regs{11-8}; 1692 let Inst{7-1} = regs{7-1}; 1693 1694 let Inst{27-25} = 0b110; 1695 let Inst{11-8} = 0b1011; 1696 let Inst{0} = 1; 1697} 1698 1699// Double precision 1700class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1701 string asm, string cstr, list<dag> pattern> 1702 : VFPXI<oops, iops, AddrMode4, 4, im, 1703 VFPLdStMulFrm, itin, asm, cstr, pattern> { 1704 // Instruction operands. 1705 bits<4> Rn; 1706 bits<13> regs; 1707 1708 // Encode instruction operands. 1709 let Inst{19-16} = Rn; 1710 let Inst{22} = regs{12}; 1711 let Inst{15-12} = regs{11-8}; 1712 let Inst{7-1} = regs{7-1}; 1713 1714 let Inst{27-25} = 0b110; 1715 let Inst{11-9} = 0b101; 1716 let Inst{8} = 1; // Double precision 1717 let Inst{0} = 0; 1718} 1719 1720// Single Precision 1721class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1722 string asm, string cstr, list<dag> pattern> 1723 : VFPXI<oops, iops, AddrMode4, 4, im, 1724 VFPLdStMulFrm, itin, asm, cstr, pattern> { 1725 // Instruction operands. 1726 bits<4> Rn; 1727 bits<13> regs; 1728 1729 // Encode instruction operands. 1730 let Inst{19-16} = Rn; 1731 let Inst{22} = regs{8}; 1732 let Inst{15-12} = regs{12-9}; 1733 let Inst{7-0} = regs{7-0}; 1734 1735 let Inst{27-25} = 0b110; 1736 let Inst{11-9} = 0b101; 1737 let Inst{8} = 0; // Single precision 1738} 1739 1740// Double precision, unary 1741class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1742 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1743 string asm, list<dag> pattern> 1744 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1745 // Instruction operands. 1746 bits<5> Dd; 1747 bits<5> Dm; 1748 1749 // Encode instruction operands. 1750 let Inst{3-0} = Dm{3-0}; 1751 let Inst{5} = Dm{4}; 1752 let Inst{15-12} = Dd{3-0}; 1753 let Inst{22} = Dd{4}; 1754 1755 let Inst{27-23} = opcod1; 1756 let Inst{21-20} = opcod2; 1757 let Inst{19-16} = opcod3; 1758 let Inst{11-9} = 0b101; 1759 let Inst{8} = 1; // Double precision 1760 let Inst{7-6} = opcod4; 1761 let Inst{4} = opcod5; 1762 1763 let Predicates = [HasVFP2, HasDPVFP]; 1764} 1765 1766// Double precision, unary, not-predicated 1767class ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1768 bit opcod5, dag oops, dag iops, InstrItinClass itin, 1769 string asm, list<dag> pattern> 1770 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> { 1771 // Instruction operands. 1772 bits<5> Dd; 1773 bits<5> Dm; 1774 1775 let Inst{31-28} = 0b1111; 1776 1777 // Encode instruction operands. 1778 let Inst{3-0} = Dm{3-0}; 1779 let Inst{5} = Dm{4}; 1780 let Inst{15-12} = Dd{3-0}; 1781 let Inst{22} = Dd{4}; 1782 1783 let Inst{27-23} = opcod1; 1784 let Inst{21-20} = opcod2; 1785 let Inst{19-16} = opcod3; 1786 let Inst{11-9} = 0b101; 1787 let Inst{8} = 1; // Double precision 1788 let Inst{7-6} = opcod4; 1789 let Inst{4} = opcod5; 1790} 1791 1792// Double precision, binary 1793class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1794 dag iops, InstrItinClass itin, string opc, string asm, 1795 list<dag> pattern> 1796 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1797 // Instruction operands. 1798 bits<5> Dd; 1799 bits<5> Dn; 1800 bits<5> Dm; 1801 1802 // Encode instruction operands. 1803 let Inst{3-0} = Dm{3-0}; 1804 let Inst{5} = Dm{4}; 1805 let Inst{19-16} = Dn{3-0}; 1806 let Inst{7} = Dn{4}; 1807 let Inst{15-12} = Dd{3-0}; 1808 let Inst{22} = Dd{4}; 1809 1810 let Inst{27-23} = opcod1; 1811 let Inst{21-20} = opcod2; 1812 let Inst{11-9} = 0b101; 1813 let Inst{8} = 1; // Double precision 1814 let Inst{6} = op6; 1815 let Inst{4} = op4; 1816 1817 let Predicates = [HasVFP2, HasDPVFP]; 1818} 1819 1820// FP, binary, not predicated 1821class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1822 InstrItinClass itin, string asm, list<dag> pattern> 1823 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin, 1824 asm, "", pattern> 1825{ 1826 // Instruction operands. 1827 bits<5> Dd; 1828 bits<5> Dn; 1829 bits<5> Dm; 1830 1831 let Inst{31-28} = 0b1111; 1832 1833 // Encode instruction operands. 1834 let Inst{3-0} = Dm{3-0}; 1835 let Inst{5} = Dm{4}; 1836 let Inst{19-16} = Dn{3-0}; 1837 let Inst{7} = Dn{4}; 1838 let Inst{15-12} = Dd{3-0}; 1839 let Inst{22} = Dd{4}; 1840 1841 let Inst{27-23} = opcod1; 1842 let Inst{21-20} = opcod2; 1843 let Inst{11-9} = 0b101; 1844 let Inst{8} = 1; // double precision 1845 let Inst{6} = opcod3; 1846 let Inst{4} = 0; 1847 1848 let Predicates = [HasVFP2, HasDPVFP]; 1849} 1850 1851// Single precision, unary, predicated 1852class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1853 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1854 string asm, list<dag> pattern> 1855 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1856 // Instruction operands. 1857 bits<5> Sd; 1858 bits<5> Sm; 1859 1860 // Encode instruction operands. 1861 let Inst{3-0} = Sm{4-1}; 1862 let Inst{5} = Sm{0}; 1863 let Inst{15-12} = Sd{4-1}; 1864 let Inst{22} = Sd{0}; 1865 1866 let Inst{27-23} = opcod1; 1867 let Inst{21-20} = opcod2; 1868 let Inst{19-16} = opcod3; 1869 let Inst{11-9} = 0b101; 1870 let Inst{8} = 0; // Single precision 1871 let Inst{7-6} = opcod4; 1872 let Inst{4} = opcod5; 1873} 1874 1875// Single precision, unary, non-predicated 1876class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1877 bit opcod5, dag oops, dag iops, InstrItinClass itin, 1878 string asm, list<dag> pattern> 1879 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1880 VFPUnaryFrm, itin, asm, "", pattern> { 1881 // Instruction operands. 1882 bits<5> Sd; 1883 bits<5> Sm; 1884 1885 let Inst{31-28} = 0b1111; 1886 1887 // Encode instruction operands. 1888 let Inst{3-0} = Sm{4-1}; 1889 let Inst{5} = Sm{0}; 1890 let Inst{15-12} = Sd{4-1}; 1891 let Inst{22} = Sd{0}; 1892 1893 let Inst{27-23} = opcod1; 1894 let Inst{21-20} = opcod2; 1895 let Inst{19-16} = opcod3; 1896 let Inst{11-9} = 0b101; 1897 let Inst{8} = 0; // Single precision 1898 let Inst{7-6} = opcod4; 1899 let Inst{4} = opcod5; 1900} 1901 1902// Single precision unary, if no NEON. Same as ASuI except not available if 1903// NEON is enabled. 1904class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1905 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1906 string asm, list<dag> pattern> 1907 : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm, 1908 pattern> { 1909 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1910} 1911 1912// Single precision, binary 1913class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 1914 InstrItinClass itin, string opc, string asm, list<dag> pattern> 1915 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1916 // Instruction operands. 1917 bits<5> Sd; 1918 bits<5> Sn; 1919 bits<5> Sm; 1920 1921 // Encode instruction operands. 1922 let Inst{3-0} = Sm{4-1}; 1923 let Inst{5} = Sm{0}; 1924 let Inst{19-16} = Sn{4-1}; 1925 let Inst{7} = Sn{0}; 1926 let Inst{15-12} = Sd{4-1}; 1927 let Inst{22} = Sd{0}; 1928 1929 let Inst{27-23} = opcod1; 1930 let Inst{21-20} = opcod2; 1931 let Inst{11-9} = 0b101; 1932 let Inst{8} = 0; // Single precision 1933 let Inst{6} = op6; 1934 let Inst{4} = op4; 1935} 1936 1937// Single precision, binary, not predicated 1938class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1939 InstrItinClass itin, string asm, list<dag> pattern> 1940 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1941 VFPBinaryFrm, itin, asm, "", pattern> 1942{ 1943 // Instruction operands. 1944 bits<5> Sd; 1945 bits<5> Sn; 1946 bits<5> Sm; 1947 1948 let Inst{31-28} = 0b1111; 1949 1950 // Encode instruction operands. 1951 let Inst{3-0} = Sm{4-1}; 1952 let Inst{5} = Sm{0}; 1953 let Inst{19-16} = Sn{4-1}; 1954 let Inst{7} = Sn{0}; 1955 let Inst{15-12} = Sd{4-1}; 1956 let Inst{22} = Sd{0}; 1957 1958 let Inst{27-23} = opcod1; 1959 let Inst{21-20} = opcod2; 1960 let Inst{11-9} = 0b101; 1961 let Inst{8} = 0; // Single precision 1962 let Inst{6} = opcod3; 1963 let Inst{4} = 0; 1964} 1965 1966// Single precision binary, if no NEON. Same as ASbI except not available if 1967// NEON is enabled. 1968class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1969 dag iops, InstrItinClass itin, string opc, string asm, 1970 list<dag> pattern> 1971 : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> { 1972 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1973 1974 // Instruction operands. 1975 bits<5> Sd; 1976 bits<5> Sn; 1977 bits<5> Sm; 1978 1979 // Encode instruction operands. 1980 let Inst{3-0} = Sm{4-1}; 1981 let Inst{5} = Sm{0}; 1982 let Inst{19-16} = Sn{4-1}; 1983 let Inst{7} = Sn{0}; 1984 let Inst{15-12} = Sd{4-1}; 1985 let Inst{22} = Sd{0}; 1986} 1987 1988// Half precision, unary, predicated 1989class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1990 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1991 string asm, list<dag> pattern> 1992 : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1993 list<Predicate> Predicates = [HasFullFP16]; 1994 1995 // Instruction operands. 1996 bits<5> Sd; 1997 bits<5> Sm; 1998 1999 // Encode instruction operands. 2000 let Inst{3-0} = Sm{4-1}; 2001 let Inst{5} = Sm{0}; 2002 let Inst{15-12} = Sd{4-1}; 2003 let Inst{22} = Sd{0}; 2004 2005 let Inst{27-23} = opcod1; 2006 let Inst{21-20} = opcod2; 2007 let Inst{19-16} = opcod3; 2008 let Inst{11-8} = 0b1001; // Half precision 2009 let Inst{7-6} = opcod4; 2010 let Inst{4} = opcod5; 2011 2012 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2013} 2014 2015// Half precision, unary, non-predicated 2016class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 2017 bit opcod5, dag oops, dag iops, InstrItinClass itin, 2018 string asm, list<dag> pattern> 2019 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 2020 VFPUnaryFrm, itin, asm, "", pattern> { 2021 list<Predicate> Predicates = [HasFullFP16]; 2022 2023 // Instruction operands. 2024 bits<5> Sd; 2025 bits<5> Sm; 2026 2027 let Inst{31-28} = 0b1111; 2028 2029 // Encode instruction operands. 2030 let Inst{3-0} = Sm{4-1}; 2031 let Inst{5} = Sm{0}; 2032 let Inst{15-12} = Sd{4-1}; 2033 let Inst{22} = Sd{0}; 2034 2035 let Inst{27-23} = opcod1; 2036 let Inst{21-20} = opcod2; 2037 let Inst{19-16} = opcod3; 2038 let Inst{11-8} = 0b1001; // Half precision 2039 let Inst{7-6} = opcod4; 2040 let Inst{4} = opcod5; 2041 2042 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2043} 2044 2045// Half precision, binary 2046class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 2047 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2048 : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 2049 list<Predicate> Predicates = [HasFullFP16]; 2050 2051 // Instruction operands. 2052 bits<5> Sd; 2053 bits<5> Sn; 2054 bits<5> Sm; 2055 2056 // Encode instruction operands. 2057 let Inst{3-0} = Sm{4-1}; 2058 let Inst{5} = Sm{0}; 2059 let Inst{19-16} = Sn{4-1}; 2060 let Inst{7} = Sn{0}; 2061 let Inst{15-12} = Sd{4-1}; 2062 let Inst{22} = Sd{0}; 2063 2064 let Inst{27-23} = opcod1; 2065 let Inst{21-20} = opcod2; 2066 let Inst{11-8} = 0b1001; // Half precision 2067 let Inst{6} = op6; 2068 let Inst{4} = op4; 2069 2070 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2071} 2072 2073// Half precision, binary, not predicated 2074class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 2075 InstrItinClass itin, string asm, list<dag> pattern> 2076 : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 2077 VFPBinaryFrm, itin, asm, "", pattern> { 2078 list<Predicate> Predicates = [HasFullFP16]; 2079 2080 // Instruction operands. 2081 bits<5> Sd; 2082 bits<5> Sn; 2083 bits<5> Sm; 2084 2085 let Inst{31-28} = 0b1111; 2086 2087 // Encode instruction operands. 2088 let Inst{3-0} = Sm{4-1}; 2089 let Inst{5} = Sm{0}; 2090 let Inst{19-16} = Sn{4-1}; 2091 let Inst{7} = Sn{0}; 2092 let Inst{15-12} = Sd{4-1}; 2093 let Inst{22} = Sd{0}; 2094 2095 let Inst{27-23} = opcod1; 2096 let Inst{21-20} = opcod2; 2097 let Inst{11-8} = 0b1001; // Half precision 2098 let Inst{6} = opcod3; 2099 let Inst{4} = 0; 2100 2101 let isUnpredicable = 1; // FP16 instructions cannot in general be conditional 2102} 2103 2104// VFP conversion instructions 2105class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 2106 dag oops, dag iops, InstrItinClass itin, string opc, string asm, 2107 list<dag> pattern> 2108 : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> { 2109 let Inst{27-23} = opcod1; 2110 let Inst{21-20} = opcod2; 2111 let Inst{19-16} = opcod3; 2112 let Inst{11-8} = opcod4; 2113 let Inst{6} = 1; 2114 let Inst{4} = 0; 2115} 2116 2117// VFP conversion between floating-point and fixed-point 2118class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, 2119 dag oops, dag iops, InstrItinClass itin, string opc, string asm, 2120 list<dag> pattern> 2121 : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> { 2122 bits<5> fbits; 2123 // size (fixed-point number): sx == 0 ? 16 : 32 2124 let Inst{7} = op5; // sx 2125 let Inst{5} = fbits{0}; 2126 let Inst{3-0} = fbits{4-1}; 2127} 2128 2129// VFP conversion instructions, if no NEON 2130class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 2131 dag oops, dag iops, InstrItinClass itin, 2132 string opc, string asm, list<dag> pattern> 2133 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 2134 pattern> { 2135 list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 2136} 2137 2138class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 2139 InstrItinClass itin, 2140 string opc, string asm, list<dag> pattern> 2141 : VFPAI<oops, iops, f, itin, opc, asm, pattern> { 2142 let Inst{27-20} = opcod1; 2143 let Inst{11-8} = opcod2; 2144 let Inst{4} = 1; 2145} 2146 2147class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2148 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2149 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>; 2150 2151class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2152 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2153 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>; 2154 2155class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2156 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2157 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>; 2158 2159class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 2160 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2161 : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 2162 2163//===----------------------------------------------------------------------===// 2164 2165//===----------------------------------------------------------------------===// 2166// ARM NEON Instruction templates. 2167// 2168 2169class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2170 InstrItinClass itin, string opc, string dt, string asm, string cstr, 2171 list<dag> pattern> 2172 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2173 let OutOperandList = oops; 2174 let InOperandList = !con(iops, (ins pred:$p)); 2175 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2176 let Pattern = pattern; 2177 list<Predicate> Predicates = [HasNEON]; 2178 let DecoderNamespace = "NEON"; 2179} 2180 2181// Same as NeonI except it does not have a "data type" specifier. 2182class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2183 InstrItinClass itin, string opc, string asm, string cstr, 2184 list<dag> pattern> 2185 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2186 let OutOperandList = oops; 2187 let InOperandList = !con(iops, (ins pred:$p)); 2188 let AsmString = !strconcat(opc, "${p}", "\t", asm); 2189 let Pattern = pattern; 2190 list<Predicate> Predicates = [HasNEON]; 2191 let DecoderNamespace = "NEON"; 2192} 2193 2194// Same as NeonI except it is not predicated 2195class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 2196 InstrItinClass itin, string opc, string dt, string asm, string cstr, 2197 list<dag> pattern> 2198 : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 2199 let OutOperandList = oops; 2200 let InOperandList = iops; 2201 let AsmString = !strconcat(opc, ".", dt, "\t", asm); 2202 let Pattern = pattern; 2203 list<Predicate> Predicates = [HasNEON]; 2204 let DecoderNamespace = "NEON"; 2205 2206 let Inst{31-28} = 0b1111; 2207} 2208 2209class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 2210 dag oops, dag iops, InstrItinClass itin, 2211 string opc, string dt, string asm, string cstr, list<dag> pattern> 2212 : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm, 2213 cstr, pattern> { 2214 let Inst{31-24} = 0b11110100; 2215 let Inst{23} = op23; 2216 let Inst{21-20} = op21_20; 2217 let Inst{11-8} = op11_8; 2218 let Inst{7-4} = op7_4; 2219 2220 let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; 2221 let DecoderNamespace = "NEONLoadStore"; 2222 2223 bits<5> Vd; 2224 bits<6> Rn; 2225 bits<4> Rm; 2226 2227 let Inst{22} = Vd{4}; 2228 let Inst{15-12} = Vd{3-0}; 2229 let Inst{19-16} = Rn{3-0}; 2230 let Inst{3-0} = Rm{3-0}; 2231} 2232 2233class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 2234 dag oops, dag iops, InstrItinClass itin, 2235 string opc, string dt, string asm, string cstr, list<dag> pattern> 2236 : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc, 2237 dt, asm, cstr, pattern> { 2238 bits<3> lane; 2239} 2240 2241class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr> 2242 : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 2243 itin> { 2244 let OutOperandList = oops; 2245 let InOperandList = !con(iops, (ins pred:$p)); 2246 list<Predicate> Predicates = [HasNEON]; 2247} 2248 2249class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr, 2250 list<dag> pattern> 2251 : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 2252 itin> { 2253 let OutOperandList = oops; 2254 let InOperandList = !con(iops, (ins pred:$p)); 2255 let Pattern = pattern; 2256 list<Predicate> Predicates = [HasNEON]; 2257} 2258 2259class NDataI<dag oops, dag iops, Format f, InstrItinClass itin, 2260 string opc, string dt, string asm, string cstr, list<dag> pattern> 2261 : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr, 2262 pattern> { 2263 let Inst{31-25} = 0b1111001; 2264 let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 2265 let DecoderNamespace = "NEONData"; 2266} 2267 2268class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin, 2269 string opc, string asm, string cstr, list<dag> pattern> 2270 : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm, 2271 cstr, pattern> { 2272 let Inst{31-25} = 0b1111001; 2273 let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 2274 let DecoderNamespace = "NEONData"; 2275} 2276 2277// NEON "one register and a modified immediate" format. 2278class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 2279 bit op5, bit op4, 2280 dag oops, dag iops, InstrItinClass itin, 2281 string opc, string dt, string asm, string cstr, 2282 list<dag> pattern> 2283 : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> { 2284 let Inst{23} = op23; 2285 let Inst{21-19} = op21_19; 2286 let Inst{11-8} = op11_8; 2287 let Inst{7} = op7; 2288 let Inst{6} = op6; 2289 let Inst{5} = op5; 2290 let Inst{4} = op4; 2291 2292 // Instruction operands. 2293 bits<5> Vd; 2294 bits<13> SIMM; 2295 2296 let Inst{15-12} = Vd{3-0}; 2297 let Inst{22} = Vd{4}; 2298 let Inst{24} = SIMM{7}; 2299 let Inst{18-16} = SIMM{6-4}; 2300 let Inst{3-0} = SIMM{3-0}; 2301 let DecoderMethod = "DecodeVMOVModImmInstruction"; 2302} 2303 2304// NEON 2 vector register format. 2305class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2306 bits<5> op11_7, bit op6, bit op4, 2307 dag oops, dag iops, InstrItinClass itin, 2308 string opc, string dt, string asm, string cstr, list<dag> pattern> 2309 : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> { 2310 let Inst{24-23} = op24_23; 2311 let Inst{21-20} = op21_20; 2312 let Inst{19-18} = op19_18; 2313 let Inst{17-16} = op17_16; 2314 let Inst{11-7} = op11_7; 2315 let Inst{6} = op6; 2316 let Inst{4} = op4; 2317 2318 // Instruction operands. 2319 bits<5> Vd; 2320 bits<5> Vm; 2321 2322 let Inst{15-12} = Vd{3-0}; 2323 let Inst{22} = Vd{4}; 2324 let Inst{3-0} = Vm{3-0}; 2325 let Inst{5} = Vm{4}; 2326} 2327 2328// Same as N2V but not predicated. 2329class N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 2330 dag oops, dag iops, InstrItinClass itin, string OpcodeStr, 2331 string Dt, list<dag> pattern> 2332 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin, 2333 OpcodeStr, Dt, "$Vd, $Vm", "", pattern> { 2334 bits<5> Vd; 2335 bits<5> Vm; 2336 2337 // Encode instruction operands 2338 let Inst{22} = Vd{4}; 2339 let Inst{15-12} = Vd{3-0}; 2340 let Inst{5} = Vm{4}; 2341 let Inst{3-0} = Vm{3-0}; 2342 2343 // Encode constant bits 2344 let Inst{27-23} = 0b00111; 2345 let Inst{21-20} = 0b11; 2346 let Inst{19-18} = op19_18; 2347 let Inst{17-16} = op17_16; 2348 let Inst{11} = 0; 2349 let Inst{10-8} = op10_8; 2350 let Inst{7} = op7; 2351 let Inst{6} = op6; 2352 let Inst{4} = 0; 2353 2354 let DecoderNamespace = "NEON"; 2355} 2356 2357// Same as N2V except it doesn't have a datatype suffix. 2358class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2359 bits<5> op11_7, bit op6, bit op4, 2360 dag oops, dag iops, InstrItinClass itin, 2361 string opc, string asm, string cstr, list<dag> pattern> 2362 : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> { 2363 let Inst{24-23} = op24_23; 2364 let Inst{21-20} = op21_20; 2365 let Inst{19-18} = op19_18; 2366 let Inst{17-16} = op17_16; 2367 let Inst{11-7} = op11_7; 2368 let Inst{6} = op6; 2369 let Inst{4} = op4; 2370 2371 // Instruction operands. 2372 bits<5> Vd; 2373 bits<5> Vm; 2374 2375 let Inst{15-12} = Vd{3-0}; 2376 let Inst{22} = Vd{4}; 2377 let Inst{3-0} = Vm{3-0}; 2378 let Inst{5} = Vm{4}; 2379} 2380 2381// NEON 2 vector register with immediate. 2382class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2383 dag oops, dag iops, Format f, InstrItinClass itin, 2384 string opc, string dt, string asm, string cstr, list<dag> pattern> 2385 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2386 let Inst{24} = op24; 2387 let Inst{23} = op23; 2388 let Inst{11-8} = op11_8; 2389 let Inst{7} = op7; 2390 let Inst{6} = op6; 2391 let Inst{4} = op4; 2392 2393 // Instruction operands. 2394 bits<5> Vd; 2395 bits<5> Vm; 2396 bits<6> SIMM; 2397 2398 let Inst{15-12} = Vd{3-0}; 2399 let Inst{22} = Vd{4}; 2400 let Inst{3-0} = Vm{3-0}; 2401 let Inst{5} = Vm{4}; 2402 let Inst{21-16} = SIMM{5-0}; 2403} 2404 2405// NEON 3 vector register format. 2406 2407class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2408 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2409 string opc, string dt, string asm, string cstr, 2410 list<dag> pattern> 2411 : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2412 let Inst{24} = op24; 2413 let Inst{23} = op23; 2414 let Inst{21-20} = op21_20; 2415 let Inst{11-8} = op11_8; 2416 let Inst{6} = op6; 2417 let Inst{4} = op4; 2418} 2419 2420class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 2421 dag oops, dag iops, Format f, InstrItinClass itin, 2422 string opc, string dt, string asm, string cstr, list<dag> pattern> 2423 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2424 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2425 // Instruction operands. 2426 bits<5> Vd; 2427 bits<5> Vn; 2428 bits<5> Vm; 2429 2430 let Inst{15-12} = Vd{3-0}; 2431 let Inst{22} = Vd{4}; 2432 let Inst{19-16} = Vn{3-0}; 2433 let Inst{7} = Vn{4}; 2434 let Inst{3-0} = Vm{3-0}; 2435 let Inst{5} = Vm{4}; 2436} 2437 2438class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2439 bit op4, dag oops, dag iops,Format f, InstrItinClass itin, 2440 string OpcodeStr, string Dt, list<dag> pattern> 2441 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr, 2442 Dt, "$Vd, $Vn, $Vm", "", pattern> { 2443 bits<5> Vd; 2444 bits<5> Vn; 2445 bits<5> Vm; 2446 2447 // Encode instruction operands 2448 let Inst{22} = Vd{4}; 2449 let Inst{15-12} = Vd{3-0}; 2450 let Inst{19-16} = Vn{3-0}; 2451 let Inst{7} = Vn{4}; 2452 let Inst{5} = Vm{4}; 2453 let Inst{3-0} = Vm{3-0}; 2454 2455 // Encode constant bits 2456 let Inst{27-23} = op27_23; 2457 let Inst{21-20} = op21_20; 2458 let Inst{11-8} = op11_8; 2459 let Inst{6} = op6; 2460 let Inst{4} = op4; 2461} 2462 2463class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2464 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2465 string opc, string dt, string asm, string cstr, 2466 list<dag> pattern> 2467 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2468 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2469 2470 // Instruction operands. 2471 bits<5> Vd; 2472 bits<5> Vn; 2473 bits<5> Vm; 2474 bit lane; 2475 2476 let Inst{15-12} = Vd{3-0}; 2477 let Inst{22} = Vd{4}; 2478 let Inst{19-16} = Vn{3-0}; 2479 let Inst{7} = Vn{4}; 2480 let Inst{3-0} = Vm{3-0}; 2481 let Inst{5} = lane; 2482} 2483 2484class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2485 bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2486 string opc, string dt, string asm, string cstr, 2487 list<dag> pattern> 2488 : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2489 oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2490 2491 // Instruction operands. 2492 bits<5> Vd; 2493 bits<5> Vn; 2494 bits<5> Vm; 2495 bits<2> lane; 2496 2497 let Inst{15-12} = Vd{3-0}; 2498 let Inst{22} = Vd{4}; 2499 let Inst{19-16} = Vn{3-0}; 2500 let Inst{7} = Vn{4}; 2501 let Inst{2-0} = Vm{2-0}; 2502 let Inst{5} = lane{1}; 2503 let Inst{3} = lane{0}; 2504} 2505 2506// Same as N3V except it doesn't have a data type suffix. 2507class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2508 bit op4, 2509 dag oops, dag iops, Format f, InstrItinClass itin, 2510 string opc, string asm, string cstr, list<dag> pattern> 2511 : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> { 2512 let Inst{24} = op24; 2513 let Inst{23} = op23; 2514 let Inst{21-20} = op21_20; 2515 let Inst{11-8} = op11_8; 2516 let Inst{6} = op6; 2517 let Inst{4} = op4; 2518 2519 // Instruction operands. 2520 bits<5> Vd; 2521 bits<5> Vn; 2522 bits<5> Vm; 2523 2524 let Inst{15-12} = Vd{3-0}; 2525 let Inst{22} = Vd{4}; 2526 let Inst{19-16} = Vn{3-0}; 2527 let Inst{7} = Vn{4}; 2528 let Inst{3-0} = Vm{3-0}; 2529 let Inst{5} = Vm{4}; 2530} 2531 2532// NEON VMOVs between scalar and core registers. 2533class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2534 dag oops, dag iops, Format f, InstrItinClass itin, 2535 string opc, string dt, string asm, list<dag> pattern> 2536 : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain, 2537 "", itin> { 2538 let Inst{27-20} = opcod1; 2539 let Inst{11-8} = opcod2; 2540 let Inst{6-5} = opcod3; 2541 let Inst{4} = 1; 2542 // A8.6.303, A8.6.328, A8.6.329 2543 let Inst{3-0} = 0b0000; 2544 2545 let OutOperandList = oops; 2546 let InOperandList = !con(iops, (ins pred:$p)); 2547 let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2548 let Pattern = pattern; 2549 list<Predicate> Predicates = [HasNEON]; 2550 2551 let PostEncoderMethod = "NEONThumb2DupPostEncoder"; 2552 let DecoderNamespace = "NEONDup"; 2553 2554 bits<5> V; 2555 bits<4> R; 2556 bits<4> p; 2557 bits<4> lane; 2558 2559 let Inst{31-28} = p{3-0}; 2560 let Inst{7} = V{4}; 2561 let Inst{19-16} = V{3-0}; 2562 let Inst{15-12} = R{3-0}; 2563} 2564class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2565 dag oops, dag iops, InstrItinClass itin, 2566 string opc, string dt, string asm, list<dag> pattern> 2567 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin, 2568 opc, dt, asm, pattern>; 2569class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2570 dag oops, dag iops, InstrItinClass itin, 2571 string opc, string dt, string asm, list<dag> pattern> 2572 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin, 2573 opc, dt, asm, pattern>; 2574class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2575 dag oops, dag iops, InstrItinClass itin, 2576 string opc, string dt, string asm, list<dag> pattern> 2577 : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin, 2578 opc, dt, asm, pattern>; 2579 2580// Vector Duplicate Lane (from scalar to all elements) 2581class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops, 2582 InstrItinClass itin, string opc, string dt, string asm, 2583 list<dag> pattern> 2584 : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> { 2585 let Inst{24-23} = 0b11; 2586 let Inst{21-20} = 0b11; 2587 let Inst{19-16} = op19_16; 2588 let Inst{11-7} = 0b11000; 2589 let Inst{6} = op6; 2590 let Inst{4} = 0; 2591 2592 bits<5> Vd; 2593 bits<5> Vm; 2594 2595 let Inst{22} = Vd{4}; 2596 let Inst{15-12} = Vd{3-0}; 2597 let Inst{5} = Vm{4}; 2598 let Inst{3-0} = Vm{3-0}; 2599} 2600 2601// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 2602// for single-precision FP. 2603class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 2604 list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 2605} 2606 2607// VFP/NEON Instruction aliases for type suffices. 2608// Note: When EmitPriority == 1, the alias will be used for printing 2609class VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result, bit EmitPriority = 0> : 2610 InstAlias<!strconcat(opc, dt, "\t", asm), Result, EmitPriority>, Requires<[HasFPRegs]>; 2611 2612// Note: When EmitPriority == 1, the alias will be used for printing 2613multiclass VFPDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 2614 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 2615 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 2616 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 2617 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 2618} 2619 2620// Note: When EmitPriority == 1, the alias will be used for printing 2621multiclass NEONDTAnyInstAlias<string opc, string asm, dag Result, bit EmitPriority = 0> { 2622 let Predicates = [HasNEON] in { 2623 def : VFPDataTypeInstAlias<opc, ".8", asm, Result, EmitPriority>; 2624 def : VFPDataTypeInstAlias<opc, ".16", asm, Result, EmitPriority>; 2625 def : VFPDataTypeInstAlias<opc, ".32", asm, Result, EmitPriority>; 2626 def : VFPDataTypeInstAlias<opc, ".64", asm, Result, EmitPriority>; 2627} 2628} 2629 2630// The same alias classes using AsmPseudo instead, for the more complex 2631// stuff in NEON that InstAlias can't quite handle. 2632// Note that we can't use anonymous defm references here like we can 2633// above, as we care about the ultimate instruction enum names generated, unlike 2634// for instalias defs. 2635class NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> : 2636 AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>; 2637 2638// Extension of NEON 3-vector data processing instructions in coprocessor 8 2639// encoding space, introduced in ARMv8.3-A. 2640class N3VCP8<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 2641 dag oops, dag iops, InstrItinClass itin, 2642 string opc, string dt, string asm, string cstr, list<dag> pattern> 2643 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 2644 dt, asm, cstr, pattern> { 2645 bits<5> Vd; 2646 bits<5> Vn; 2647 bits<5> Vm; 2648 2649 let DecoderNamespace = "VFPV8"; 2650 // These have the same encodings in ARM and Thumb2 2651 let PostEncoderMethod = ""; 2652 2653 let Inst{31-25} = 0b1111110; 2654 let Inst{24-23} = op24_23; 2655 let Inst{22} = Vd{4}; 2656 let Inst{21-20} = op21_20; 2657 let Inst{19-16} = Vn{3-0}; 2658 let Inst{15-12} = Vd{3-0}; 2659 let Inst{11-8} = 0b1000; 2660 let Inst{7} = Vn{4}; 2661 let Inst{6} = op6; 2662 let Inst{5} = Vm{4}; 2663 let Inst{4} = op4; 2664 let Inst{3-0} = Vm{3-0}; 2665} 2666 2667// Extension of NEON 2-vector-and-scalar data processing instructions in 2668// coprocessor 8 encoding space, introduced in ARMv8.3-A. 2669class N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4, 2670 dag oops, dag iops, InstrItinClass itin, 2671 string opc, string dt, string asm, string cstr, list<dag> pattern> 2672 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, 2673 dt, asm, cstr, pattern> { 2674 bits<5> Vd; 2675 bits<5> Vn; 2676 bits<5> Vm; 2677 2678 let DecoderNamespace = "VFPV8"; 2679 // These have the same encodings in ARM and Thumb2 2680 let PostEncoderMethod = ""; 2681 2682 let Inst{31-24} = 0b11111110; 2683 let Inst{23} = op23; 2684 let Inst{22} = Vd{4}; 2685 let Inst{21-20} = op21_20; 2686 let Inst{19-16} = Vn{3-0}; 2687 let Inst{15-12} = Vd{3-0}; 2688 let Inst{11-8} = 0b1000; 2689 let Inst{7} = Vn{4}; 2690 let Inst{6} = op6; 2691 // Bit 5 set by sub-classes 2692 let Inst{4} = op4; 2693 let Inst{3-0} = Vm{3-0}; 2694} 2695 2696// In Armv8.2-A, some NEON instructions are added that encode Vn and Vm 2697// differently: 2698// if Q == ‘1’ then UInt(N:Vn) else UInt(Vn:N); 2699// if Q == ‘1’ then UInt(M:Vm) else UInt(Vm:M); 2700// Class N3VCP8 above describes the Q=1 case, and this class the Q=0 case. 2701class N3VCP8Q0<bits<2> op24_23, bits<2> op21_20, bit op6, bit op4, 2702 dag oops, dag iops, InstrItinClass itin, 2703 string opc, string dt, string asm, string cstr, list<dag> pattern> 2704 : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N3RegCplxFrm, itin, opc, dt, asm, cstr, pattern> { 2705 bits<5> Vd; 2706 bits<5> Vn; 2707 bits<5> Vm; 2708 2709 let DecoderNamespace = "VFPV8"; 2710 // These have the same encodings in ARM and Thumb2 2711 let PostEncoderMethod = ""; 2712 2713 let Inst{31-25} = 0b1111110; 2714 let Inst{24-23} = op24_23; 2715 let Inst{22} = Vd{4}; 2716 let Inst{21-20} = op21_20; 2717 let Inst{19-16} = Vn{4-1}; 2718 let Inst{15-12} = Vd{3-0}; 2719 let Inst{11-8} = 0b1000; 2720 let Inst{7} = Vn{0}; 2721 let Inst{6} = op6; 2722 let Inst{5} = Vm{0}; 2723 let Inst{4} = op4; 2724 let Inst{3-0} = Vm{4-1}; 2725} 2726 2727// Operand types for complex instructions 2728class ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag> 2729 : AsmOperandClass { 2730 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 2731 let DiagnosticString = "complex rotation must be " # Diag; 2732 let Name = "ComplexRotation" # Type; 2733} 2734def complexrotateop : Operand<i32> { 2735 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">; 2736 let PrintMethod = "printComplexRotationOp<90, 0>"; 2737} 2738def complexrotateopodd : Operand<i32> { 2739 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">; 2740 let PrintMethod = "printComplexRotationOp<180, 90>"; 2741} 2742 2743def MveSaturateOperand : AsmOperandClass { 2744 let PredicateMethod = "isMveSaturateOp"; 2745 let DiagnosticString = "saturate operand must be 48 or 64"; 2746 let Name = "MveSaturate"; 2747} 2748def saturateop : Operand<i32> { 2749 let ParserMatchClass = MveSaturateOperand; 2750 let PrintMethod = "printMveSaturateOp"; 2751} 2752 2753// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM. 2754def : TokenAlias<".s8", ".i8">; 2755def : TokenAlias<".u8", ".i8">; 2756def : TokenAlias<".s16", ".i16">; 2757def : TokenAlias<".u16", ".i16">; 2758def : TokenAlias<".s32", ".i32">; 2759def : TokenAlias<".u32", ".i32">; 2760def : TokenAlias<".s64", ".i64">; 2761def : TokenAlias<".u64", ".i64">; 2762 2763def : TokenAlias<".i8", ".8">; 2764def : TokenAlias<".i16", ".16">; 2765def : TokenAlias<".i32", ".32">; 2766def : TokenAlias<".i64", ".64">; 2767 2768def : TokenAlias<".p8", ".8">; 2769def : TokenAlias<".p16", ".16">; 2770 2771def : TokenAlias<".f32", ".32">; 2772def : TokenAlias<".f64", ".64">; 2773def : TokenAlias<".f", ".f32">; 2774def : TokenAlias<".d", ".f64">; 2775