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