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