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