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