1234353Sdim//===-- ARMInstrFormats.td - ARM Instruction Formats -------*- tablegen -*-===// 2206083Srdivacky// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7206083Srdivacky// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed 10193323Sed//===----------------------------------------------------------------------===// 11193323Sed// 12193323Sed// ARM Instruction Format Definitions. 13193323Sed// 14193323Sed 15193323Sed// Format specifies the encoding used by the instruction. This is part of the 16193323Sed// ad-hoc solution used to emit machine instruction encodings by our machine 17193323Sed// code emitter. 18205407Srdivackyclass Format<bits<6> val> { 19205407Srdivacky bits<6> Value = val; 20193323Sed} 21193323Sed 22193323Seddef Pseudo : Format<0>; 23193323Seddef MulFrm : Format<1>; 24193323Seddef BrFrm : Format<2>; 25193323Seddef BrMiscFrm : Format<3>; 26193323Sed 27193323Seddef DPFrm : Format<4>; 28226633Sdimdef DPSoRegRegFrm : Format<5>; 29193323Sed 30193323Seddef LdFrm : Format<6>; 31193323Seddef StFrm : Format<7>; 32193323Seddef LdMiscFrm : Format<8>; 33193323Seddef StMiscFrm : Format<9>; 34193323Seddef LdStMulFrm : Format<10>; 35193323Sed 36205407Srdivackydef LdStExFrm : Format<11>; 37200581Srdivacky 38205407Srdivackydef ArithMiscFrm : Format<12>; 39212904Sdimdef SatFrm : Format<13>; 40212904Sdimdef ExtFrm : Format<14>; 41193323Sed 42212904Sdimdef VFPUnaryFrm : Format<15>; 43212904Sdimdef VFPBinaryFrm : Format<16>; 44212904Sdimdef VFPConv1Frm : Format<17>; 45212904Sdimdef VFPConv2Frm : Format<18>; 46212904Sdimdef VFPConv3Frm : Format<19>; 47212904Sdimdef VFPConv4Frm : Format<20>; 48212904Sdimdef VFPConv5Frm : Format<21>; 49212904Sdimdef VFPLdStFrm : Format<22>; 50212904Sdimdef VFPLdStMulFrm : Format<23>; 51212904Sdimdef VFPMiscFrm : Format<24>; 52193323Sed 53212904Sdimdef ThumbFrm : Format<25>; 54212904Sdimdef MiscFrm : Format<26>; 55193323Sed 56212904Sdimdef NGetLnFrm : Format<27>; 57212904Sdimdef NSetLnFrm : Format<28>; 58212904Sdimdef NDupFrm : Format<29>; 59212904Sdimdef NLdStFrm : Format<30>; 60212904Sdimdef N1RegModImmFrm: Format<31>; 61212904Sdimdef N2RegFrm : Format<32>; 62212904Sdimdef NVCVTFrm : Format<33>; 63212904Sdimdef NVDupLnFrm : Format<34>; 64212904Sdimdef N2RegVShLFrm : Format<35>; 65212904Sdimdef N2RegVShRFrm : Format<36>; 66212904Sdimdef N3RegFrm : Format<37>; 67212904Sdimdef N3RegVShFrm : Format<38>; 68212904Sdimdef NVExtFrm : Format<39>; 69212904Sdimdef NVMulSLFrm : Format<40>; 70212904Sdimdef NVTBLFrm : Format<41>; 71226633Sdimdef DPSoRegImmFrm : Format<42>; 72194710Sed 73198090Srdivacky// Misc flags. 74198090Srdivacky 75218893Sdim// The instruction has an Rn register operand. 76198090Srdivacky// UnaryDP - Indicates this is a unary data processing instruction, i.e. 77198090Srdivacky// it doesn't have a Rn operand. 78198090Srdivackyclass UnaryDP { bit isUnaryDataProc = 1; } 79193323Sed 80198090Srdivacky// Xform16Bit - Indicates this Thumb2 instruction may be transformed into 81198090Srdivacky// a 16-bit Thumb instruction if certain conditions are met. 82198090Srdivackyclass Xform16Bit { bit canXformTo16Bit = 1; } 83198090Srdivacky 84193323Sed//===----------------------------------------------------------------------===// 85205407Srdivacky// ARM Instruction flags. These need to match ARMBaseInstrInfo.h. 86195340Sed// 87193323Sed 88218893Sdim// FIXME: Once the JIT is MC-ized, these can go away. 89195340Sed// Addressing mode. 90218893Sdimclass AddrMode<bits<5> val> { 91218893Sdim bits<5> Value = val; 92195340Sed} 93212904Sdimdef AddrModeNone : AddrMode<0>; 94212904Sdimdef AddrMode1 : AddrMode<1>; 95212904Sdimdef AddrMode2 : AddrMode<2>; 96212904Sdimdef AddrMode3 : AddrMode<3>; 97212904Sdimdef AddrMode4 : AddrMode<4>; 98212904Sdimdef AddrMode5 : AddrMode<5>; 99212904Sdimdef AddrMode6 : AddrMode<6>; 100212904Sdimdef AddrModeT1_1 : AddrMode<7>; 101212904Sdimdef AddrModeT1_2 : AddrMode<8>; 102212904Sdimdef AddrModeT1_4 : AddrMode<9>; 103212904Sdimdef AddrModeT1_s : AddrMode<10>; 104212904Sdimdef AddrModeT2_i12 : AddrMode<11>; 105212904Sdimdef AddrModeT2_i8 : AddrMode<12>; 106212904Sdimdef AddrModeT2_so : AddrMode<13>; 107212904Sdimdef AddrModeT2_pc : AddrMode<14>; 108195340Seddef AddrModeT2_i8s4 : AddrMode<15>; 109218893Sdimdef AddrMode_i12 : AddrMode<16>; 110195340Sed 111195340Sed// Load / store index mode. 112195340Sedclass IndexMode<bits<2> val> { 113195340Sed bits<2> Value = val; 114195340Sed} 115195340Seddef IndexModeNone : IndexMode<0>; 116195340Seddef IndexModePre : IndexMode<1>; 117195340Seddef IndexModePost : IndexMode<2>; 118205218Srdivackydef IndexModeUpd : IndexMode<3>; 119195340Sed 120198892Srdivacky// Instruction execution domain. 121219077Sdimclass Domain<bits<3> val> { 122219077Sdim bits<3> Value = val; 123198892Srdivacky} 124198892Srdivackydef GenericDomain : Domain<0>; 125198892Srdivackydef VFPDomain : Domain<1>; // Instructions in VFP domain only 126198892Srdivackydef NeonDomain : Domain<2>; // Instructions in Neon domain only 127198892Srdivackydef VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains 128219077Sdimdef VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8 129198892Srdivacky 130195340Sed//===----------------------------------------------------------------------===// 131198090Srdivacky// ARM special operands. 132198090Srdivacky// 133198090Srdivacky 134226633Sdim// ARM imod and iflag operands, used only by the CPS instruction. 135226633Sdimdef imod_op : Operand<i32> { 136226633Sdim let PrintMethod = "printCPSIMod"; 137212904Sdim} 138212904Sdim 139218893Sdimdef ProcIFlagsOperand : AsmOperandClass { 140218893Sdim let Name = "ProcIFlags"; 141226633Sdim let ParserMethod = "parseProcIFlagsOperand"; 142218893Sdim} 143218893Sdimdef iflags_op : Operand<i32> { 144218893Sdim let PrintMethod = "printCPSIFlag"; 145218893Sdim let ParserMatchClass = ProcIFlagsOperand; 146218893Sdim} 147218893Sdim 148198090Srdivacky// ARM Predicate operand. Default to 14 = always (AL). Second part is CC 149198090Srdivacky// register whose default is 0 (no register). 150226633Sdimdef CondCodeOperand : AsmOperandClass { let Name = "CondCode"; } 151226633Sdimdef pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), 152198090Srdivacky (ops (i32 14), (i32 zero_reg))> { 153198090Srdivacky let PrintMethod = "printPredicateOperand"; 154212904Sdim let ParserMatchClass = CondCodeOperand; 155226633Sdim let DecoderMethod = "DecodePredicateOperand"; 156198090Srdivacky} 157198090Srdivacky 158263508Sdim// Selectable predicate operand for CMOV instructions. We can't use a normal 159263508Sdim// predicate because the default values interfere with instruction selection. In 160263508Sdim// all other respects it is identical though: pseudo-instruction expansion 161263508Sdim// relies on the MachineOperands being compatible. 162263508Sdimdef cmovpred : Operand<i32>, PredicateOp, 163263508Sdim ComplexPattern<i32, 2, "SelectCMOVPred"> { 164263508Sdim let MIOperandInfo = (ops i32imm, i32imm); 165263508Sdim let PrintMethod = "printPredicateOperand"; 166263508Sdim} 167263508Sdim 168198090Srdivacky// Conditional code result for instructions whose 's' bit is set, e.g. subs. 169226633Sdimdef CCOutOperand : AsmOperandClass { let Name = "CCOut"; } 170198090Srdivackydef cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> { 171218893Sdim let EncoderMethod = "getCCOutOpValue"; 172198090Srdivacky let PrintMethod = "printSBitModifierOperand"; 173218893Sdim let ParserMatchClass = CCOutOperand; 174226633Sdim let DecoderMethod = "DecodeCCOutOperand"; 175198090Srdivacky} 176198090Srdivacky 177198090Srdivacky// Same as cc_out except it defaults to setting CPSR. 178198090Srdivackydef s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> { 179218893Sdim let EncoderMethod = "getCCOutOpValue"; 180198090Srdivacky let PrintMethod = "printSBitModifierOperand"; 181218893Sdim let ParserMatchClass = CCOutOperand; 182226633Sdim let DecoderMethod = "DecodeCCOutOperand"; 183198090Srdivacky} 184198090Srdivacky 185205218Srdivacky// ARM special operands for disassembly only. 186205218Srdivacky// 187234353Sdimdef SetEndAsmOperand : ImmAsmOperand { 188226633Sdim let Name = "SetEndImm"; 189226633Sdim let ParserMethod = "parseSetEndImm"; 190226633Sdim} 191218893Sdimdef setend_op : Operand<i32> { 192218893Sdim let PrintMethod = "printSetendOperand"; 193226633Sdim let ParserMatchClass = SetEndAsmOperand; 194218893Sdim} 195205218Srdivacky 196226633Sdimdef MSRMaskOperand : AsmOperandClass { 197226633Sdim let Name = "MSRMask"; 198226633Sdim let ParserMethod = "parseMSRMaskOperand"; 199226633Sdim} 200205218Srdivackydef msr_mask : Operand<i32> { 201205218Srdivacky let PrintMethod = "printMSRMaskOperand"; 202226633Sdim let DecoderMethod = "DecodeMSRMask"; 203218893Sdim let ParserMatchClass = MSRMaskOperand; 204205218Srdivacky} 205205218Srdivacky 206221345Sdim// Shift Right Immediate - A shift right immediate is encoded differently from 207221345Sdim// other shift immediates. The imm6 field is encoded like so: 208221345Sdim// 209221345Sdim// Offset Encoding 210221345Sdim// 8 imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0> 211221345Sdim// 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0> 212221345Sdim// 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0> 213221345Sdim// 64 64 - <imm> is encoded in imm6<5:0> 214234353Sdimdef shr_imm8_asm_operand : ImmAsmOperand { let Name = "ShrImm8"; } 215221345Sdimdef shr_imm8 : Operand<i32> { 216221345Sdim let EncoderMethod = "getShiftRight8Imm"; 217226633Sdim let DecoderMethod = "DecodeShiftRight8Imm"; 218234353Sdim let ParserMatchClass = shr_imm8_asm_operand; 219205218Srdivacky} 220234353Sdimdef shr_imm16_asm_operand : ImmAsmOperand { let Name = "ShrImm16"; } 221221345Sdimdef shr_imm16 : Operand<i32> { 222221345Sdim let EncoderMethod = "getShiftRight16Imm"; 223226633Sdim let DecoderMethod = "DecodeShiftRight16Imm"; 224234353Sdim let ParserMatchClass = shr_imm16_asm_operand; 225221345Sdim} 226234353Sdimdef shr_imm32_asm_operand : ImmAsmOperand { let Name = "ShrImm32"; } 227221345Sdimdef shr_imm32 : Operand<i32> { 228221345Sdim let EncoderMethod = "getShiftRight32Imm"; 229226633Sdim let DecoderMethod = "DecodeShiftRight32Imm"; 230234353Sdim let ParserMatchClass = shr_imm32_asm_operand; 231221345Sdim} 232234353Sdimdef shr_imm64_asm_operand : ImmAsmOperand { let Name = "ShrImm64"; } 233221345Sdimdef shr_imm64 : Operand<i32> { 234221345Sdim let EncoderMethod = "getShiftRight64Imm"; 235226633Sdim let DecoderMethod = "DecodeShiftRight64Imm"; 236234353Sdim let ParserMatchClass = shr_imm64_asm_operand; 237221345Sdim} 238205218Srdivacky 239198090Srdivacky//===----------------------------------------------------------------------===// 240226633Sdim// ARM Assembler alias templates. 241226633Sdim// 242226633Sdimclass ARMInstAlias<string Asm, dag Result, bit Emit = 0b1> 243226633Sdim : InstAlias<Asm, Result, Emit>, Requires<[IsARM]>; 244226633Sdimclass tInstAlias<string Asm, dag Result, bit Emit = 0b1> 245226633Sdim : InstAlias<Asm, Result, Emit>, Requires<[IsThumb]>; 246226633Sdimclass t2InstAlias<string Asm, dag Result, bit Emit = 0b1> 247226633Sdim : InstAlias<Asm, Result, Emit>, Requires<[IsThumb2]>; 248226633Sdimclass VFP2InstAlias<string Asm, dag Result, bit Emit = 0b1> 249226633Sdim : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2]>; 250263508Sdimclass VFP2DPInstAlias<string Asm, dag Result, bit Emit = 0b1> 251263508Sdim : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2,HasDPVFP]>; 252226633Sdimclass VFP3InstAlias<string Asm, dag Result, bit Emit = 0b1> 253226633Sdim : InstAlias<Asm, Result, Emit>, Requires<[HasVFP3]>; 254234353Sdimclass NEONInstAlias<string Asm, dag Result, bit Emit = 0b1> 255234353Sdim : InstAlias<Asm, Result, Emit>, Requires<[HasNEON]>; 256226633Sdim 257234353Sdim 258234353Sdimclass VFP2MnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 259234353Sdim Requires<[HasVFP2]>; 260234353Sdimclass NEONMnemonicAlias<string src, string dst> : MnemonicAlias<src, dst>, 261234353Sdim Requires<[HasNEON]>; 262234353Sdim 263226633Sdim//===----------------------------------------------------------------------===// 264193323Sed// ARM Instruction templates. 265193323Sed// 266193323Sed 267226633Sdim 268224145Sdimclass InstTemplate<AddrMode am, int sz, IndexMode im, 269201360Srdivacky Format f, Domain d, string cstr, InstrItinClass itin> 270193323Sed : Instruction { 271193323Sed let Namespace = "ARM"; 272193323Sed 273193323Sed AddrMode AM = am; 274224145Sdim int Size = sz; 275193323Sed IndexMode IM = im; 276193323Sed bits<2> IndexModeBits = IM.Value; 277193323Sed Format F = f; 278205407Srdivacky bits<6> Form = F.Value; 279198892Srdivacky Domain D = d; 280193323Sed bit isUnaryDataProc = 0; 281198090Srdivacky bit canXformTo16Bit = 0; 282226633Sdim // The instruction is a 16-bit flag setting Thumb instruction. Used 283226633Sdim // by the parser to determine whether to require the 'S' suffix on the 284226633Sdim // mnemonic (when not in an IT block) or preclude it (when in an IT block). 285226633Sdim bit thumbArithFlagSetting = 0; 286206083Srdivacky 287218893Sdim // If this is a pseudo instruction, mark it isCodeGenOnly. 288218893Sdim let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo"); 289218893Sdim 290226633Sdim // The layout of TSFlags should be kept in sync with ARMBaseInfo.h. 291218893Sdim let TSFlags{4-0} = AM.Value; 292224145Sdim let TSFlags{6-5} = IndexModeBits; 293224145Sdim let TSFlags{12-7} = Form; 294224145Sdim let TSFlags{13} = isUnaryDataProc; 295224145Sdim let TSFlags{14} = canXformTo16Bit; 296224145Sdim let TSFlags{17-15} = D.Value; 297226633Sdim let TSFlags{18} = thumbArithFlagSetting; 298206274Srdivacky 299193323Sed let Constraints = cstr; 300198090Srdivacky let Itinerary = itin; 301193323Sed} 302193323Sed 303201360Srdivackyclass Encoding { 304201360Srdivacky field bits<32> Inst; 305234353Sdim // Mask of bits that cause an encoding to be UNPREDICTABLE. 306234353Sdim // If a bit is set, then if the corresponding bit in the 307234353Sdim // target encoding differs from its value in the "Inst" field, 308234353Sdim // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 309234353Sdim field bits<32> Unpredictable = 0; 310234353Sdim // SoftFail is the generic name for this field, but we alias it so 311234353Sdim // as to make it more obvious what it means in ARM-land. 312234353Sdim field bits<32> SoftFail = Unpredictable; 313201360Srdivacky} 314201360Srdivacky 315224145Sdimclass InstARM<AddrMode am, int sz, IndexMode im, 316201360Srdivacky Format f, Domain d, string cstr, InstrItinClass itin> 317226633Sdim : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding { 318226633Sdim let DecoderNamespace = "ARM"; 319226633Sdim} 320201360Srdivacky 321201360Srdivacky// This Encoding-less class is used by Thumb1 to specify the encoding bits later 322201360Srdivacky// on by adding flavors to specific instructions. 323224145Sdimclass InstThumb<AddrMode am, int sz, IndexMode im, 324201360Srdivacky Format f, Domain d, string cstr, InstrItinClass itin> 325226633Sdim : InstTemplate<am, sz, im, f, d, cstr, itin> { 326226633Sdim let DecoderNamespace = "Thumb"; 327226633Sdim} 328201360Srdivacky 329234353Sdim// Pseudo-instructions for alternate assembly syntax (never used by codegen). 330234353Sdim// These are aliases that require C++ handling to convert to the target 331234353Sdim// instruction, while InstAliases can be handled directly by tblgen. 332234353Sdimclass AsmPseudoInst<string asm, dag iops> 333234353Sdim : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, 334234353Sdim "", NoItinerary> { 335234353Sdim let OutOperandList = (outs); 336234353Sdim let InOperandList = iops; 337234353Sdim let Pattern = []; 338234353Sdim let isCodeGenOnly = 0; // So we get asm matcher for it. 339234353Sdim let AsmString = asm; 340234353Sdim let isPseudo = 1; 341234353Sdim} 342234353Sdim 343234353Sdimclass ARMAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, 344234353Sdim Requires<[IsARM]>; 345234353Sdimclass tAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, 346234353Sdim Requires<[IsThumb]>; 347234353Sdimclass t2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, 348234353Sdim Requires<[IsThumb2]>; 349234353Sdimclass VFP2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, 350234353Sdim Requires<[HasVFP2]>; 351234353Sdimclass NEONAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, 352234353Sdim Requires<[HasNEON]>; 353234353Sdim 354234353Sdim// Pseudo instructions for the code generator. 355218893Sdimclass PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern> 356224145Sdim : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, 357224145Sdim GenericDomain, "", itin> { 358193323Sed let OutOperandList = oops; 359193323Sed let InOperandList = iops; 360193323Sed let Pattern = pattern; 361221345Sdim let isCodeGenOnly = 1; 362224145Sdim let isPseudo = 1; 363193323Sed} 364193323Sed 365218893Sdim// PseudoInst that's ARM-mode only. 366224145Sdimclass ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 367218893Sdim list<dag> pattern> 368218893Sdim : PseudoInst<oops, iops, itin, pattern> { 369224145Sdim let Size = sz; 370218893Sdim list<Predicate> Predicates = [IsARM]; 371218893Sdim} 372218893Sdim 373218893Sdim// PseudoInst that's Thumb-mode only. 374224145Sdimclass tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 375218893Sdim list<dag> pattern> 376218893Sdim : PseudoInst<oops, iops, itin, pattern> { 377224145Sdim let Size = sz; 378218893Sdim list<Predicate> Predicates = [IsThumb]; 379218893Sdim} 380218893Sdim 381218893Sdim// PseudoInst that's Thumb2-mode only. 382224145Sdimclass t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin, 383218893Sdim list<dag> pattern> 384218893Sdim : PseudoInst<oops, iops, itin, pattern> { 385224145Sdim let Size = sz; 386218893Sdim list<Predicate> Predicates = [IsThumb2]; 387218893Sdim} 388224145Sdim 389224145Sdimclass ARMPseudoExpand<dag oops, dag iops, int sz, 390224145Sdim InstrItinClass itin, list<dag> pattern, 391224145Sdim dag Result> 392224145Sdim : ARMPseudoInst<oops, iops, sz, itin, pattern>, 393224145Sdim PseudoInstExpansion<Result>; 394224145Sdim 395224145Sdimclass tPseudoExpand<dag oops, dag iops, int sz, 396224145Sdim InstrItinClass itin, list<dag> pattern, 397224145Sdim dag Result> 398224145Sdim : tPseudoInst<oops, iops, sz, itin, pattern>, 399224145Sdim PseudoInstExpansion<Result>; 400224145Sdim 401224145Sdimclass t2PseudoExpand<dag oops, dag iops, int sz, 402224145Sdim InstrItinClass itin, list<dag> pattern, 403224145Sdim dag Result> 404224145Sdim : t2PseudoInst<oops, iops, sz, itin, pattern>, 405224145Sdim PseudoInstExpansion<Result>; 406224145Sdim 407193323Sed// Almost all ARM instructions are predicable. 408224145Sdimclass I<dag oops, dag iops, AddrMode am, int sz, 409206083Srdivacky IndexMode im, Format f, InstrItinClass itin, 410198090Srdivacky string opc, string asm, string cstr, 411193323Sed list<dag> pattern> 412198892Srdivacky : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 413218893Sdim bits<4> p; 414218893Sdim let Inst{31-28} = p; 415193323Sed let OutOperandList = oops; 416205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 417218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 418193323Sed let Pattern = pattern; 419193323Sed list<Predicate> Predicates = [IsARM]; 420193323Sed} 421212904Sdim 422200581Srdivacky// A few are not predicable 423224145Sdimclass InoP<dag oops, dag iops, AddrMode am, int sz, 424206083Srdivacky IndexMode im, Format f, InstrItinClass itin, 425206083Srdivacky string opc, string asm, string cstr, 426206083Srdivacky list<dag> pattern> 427200581Srdivacky : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 428200581Srdivacky let OutOperandList = oops; 429200581Srdivacky let InOperandList = iops; 430208599Srdivacky let AsmString = !strconcat(opc, asm); 431200581Srdivacky let Pattern = pattern; 432200581Srdivacky let isPredicable = 0; 433200581Srdivacky list<Predicate> Predicates = [IsARM]; 434200581Srdivacky} 435193323Sed 436212904Sdim// Same as I except it can optionally modify CPSR. Note it's modeled as an input 437212904Sdim// operand since by default it's a zero register. It will become an implicit def 438212904Sdim// once it's "flipped". 439224145Sdimclass sI<dag oops, dag iops, AddrMode am, int sz, 440198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 441198090Srdivacky string opc, string asm, string cstr, 442193323Sed list<dag> pattern> 443198892Srdivacky : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 444218893Sdim bits<4> p; // Predicate operand 445218893Sdim bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 446218893Sdim let Inst{31-28} = p; 447218893Sdim let Inst{20} = s; 448218893Sdim 449193323Sed let OutOperandList = oops; 450205407Srdivacky let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 451218893Sdim let AsmString = !strconcat(opc, "${s}${p}", asm); 452193323Sed let Pattern = pattern; 453193323Sed list<Predicate> Predicates = [IsARM]; 454193323Sed} 455193323Sed 456193323Sed// Special cases 457224145Sdimclass XI<dag oops, dag iops, AddrMode am, int sz, 458198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 459198090Srdivacky string asm, string cstr, list<dag> pattern> 460198892Srdivacky : InstARM<am, sz, im, f, GenericDomain, cstr, itin> { 461193323Sed let OutOperandList = oops; 462193323Sed let InOperandList = iops; 463208599Srdivacky let AsmString = asm; 464193323Sed let Pattern = pattern; 465193323Sed list<Predicate> Predicates = [IsARM]; 466193323Sed} 467193323Sed 468198090Srdivackyclass AI<dag oops, dag iops, Format f, InstrItinClass itin, 469198090Srdivacky string opc, string asm, list<dag> pattern> 470224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 471198090Srdivacky opc, asm, "", pattern>; 472198090Srdivackyclass AsI<dag oops, dag iops, Format f, InstrItinClass itin, 473198090Srdivacky string opc, string asm, list<dag> pattern> 474224145Sdim : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 475198090Srdivacky opc, asm, "", pattern>; 476198090Srdivackyclass AXI<dag oops, dag iops, Format f, InstrItinClass itin, 477193323Sed string asm, list<dag> pattern> 478224145Sdim : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 479193323Sed asm, "", pattern>; 480200581Srdivackyclass AInoP<dag oops, dag iops, Format f, InstrItinClass itin, 481206083Srdivacky string opc, string asm, list<dag> pattern> 482224145Sdim : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 483206083Srdivacky opc, asm, "", pattern>; 484193323Sed 485193323Sed// Ctrl flow instructions 486198090Srdivackyclass ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 487198090Srdivacky string opc, string asm, list<dag> pattern> 488224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 489198090Srdivacky opc, asm, "", pattern> { 490193323Sed let Inst{27-24} = opcod; 491193323Sed} 492198090Srdivackyclass ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 493198090Srdivacky string asm, list<dag> pattern> 494224145Sdim : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 495198090Srdivacky asm, "", pattern> { 496193323Sed let Inst{27-24} = opcod; 497193323Sed} 498193323Sed 499193323Sed// BR_JT instructions 500198090Srdivackyclass JTI<dag oops, dag iops, InstrItinClass itin, 501198090Srdivacky string asm, list<dag> pattern> 502224145Sdim : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin, 503193323Sed asm, "", pattern>; 504193323Sed 505263508Sdimclass AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 506200581Srdivacky string opc, string asm, list<dag> pattern> 507224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 508200581Srdivacky opc, asm, "", pattern> { 509218893Sdim bits<4> Rt; 510226633Sdim bits<4> addr; 511200581Srdivacky let Inst{27-23} = 0b00011; 512200581Srdivacky let Inst{22-21} = opcod; 513212904Sdim let Inst{20} = 1; 514226633Sdim let Inst{19-16} = addr; 515218893Sdim let Inst{15-12} = Rt; 516263508Sdim let Inst{11-10} = 0b11; 517263508Sdim let Inst{9-8} = opcod2; 518263508Sdim let Inst{7-0} = 0b10011111; 519200581Srdivacky} 520263508Sdimclass AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 521200581Srdivacky string opc, string asm, list<dag> pattern> 522224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 523200581Srdivacky opc, asm, "", pattern> { 524218893Sdim bits<4> Rt; 525221345Sdim bits<4> addr; 526200581Srdivacky let Inst{27-23} = 0b00011; 527200581Srdivacky let Inst{22-21} = opcod; 528212904Sdim let Inst{20} = 0; 529221345Sdim let Inst{19-16} = addr; 530263508Sdim let Inst{11-10} = 0b11; 531263508Sdim let Inst{9-8} = opcod2; 532263508Sdim let Inst{7-4} = 0b1001; 533218893Sdim let Inst{3-0} = Rt; 534200581Srdivacky} 535263508Sdim// Atomic load/store instructions 536263508Sdimclass AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 537263508Sdim string opc, string asm, list<dag> pattern> 538263508Sdim : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>; 539263508Sdim 540263508Sdimclass AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 541263508Sdim string opc, string asm, list<dag> pattern> 542263508Sdim : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> { 543263508Sdim bits<4> Rd; 544263508Sdim let Inst{15-12} = Rd; 545263508Sdim} 546263508Sdim 547263508Sdim// Exclusive load/store instructions 548263508Sdim 549263508Sdimclass AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 550263508Sdim string opc, string asm, list<dag> pattern> 551263508Sdim : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 552263508Sdim Requires<[IsARM, HasV8]>; 553263508Sdim 554263508Sdimclass AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 555263508Sdim string opc, string asm, list<dag> pattern> 556263508Sdim : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 557263508Sdim Requires<[IsARM, HasV8]> { 558263508Sdim bits<4> Rd; 559263508Sdim let Inst{15-12} = Rd; 560263508Sdim} 561263508Sdim 562218893Sdimclass AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> 563226633Sdim : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> { 564218893Sdim bits<4> Rt; 565218893Sdim bits<4> Rt2; 566226633Sdim bits<4> addr; 567218893Sdim let Inst{27-23} = 0b00010; 568218893Sdim let Inst{22} = b; 569218893Sdim let Inst{21-20} = 0b00; 570226633Sdim let Inst{19-16} = addr; 571218893Sdim let Inst{15-12} = Rt; 572218893Sdim let Inst{11-4} = 0b00001001; 573218893Sdim let Inst{3-0} = Rt2; 574234353Sdim 575234982Sdim let Unpredictable{11-8} = 0b1111; 576234353Sdim let DecoderMethod = "DecodeSwap"; 577218893Sdim} 578263508Sdim// Acquire/Release load/store instructions 579263508Sdimclass AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 580263508Sdim string opc, string asm, list<dag> pattern> 581263508Sdim : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 582263508Sdim Requires<[IsARM, HasV8]>; 583200581Srdivacky 584263508Sdimclass AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 585263508Sdim string opc, string asm, list<dag> pattern> 586263508Sdim : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 587263508Sdim Requires<[IsARM, HasV8]> { 588263508Sdim let Inst{15-12} = 0b1111; 589263508Sdim} 590263508Sdim 591193323Sed// addrmode1 instructions 592198090Srdivackyclass AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 593198090Srdivacky string opc, string asm, list<dag> pattern> 594224145Sdim : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 595198090Srdivacky opc, asm, "", pattern> { 596193323Sed let Inst{24-21} = opcod; 597212904Sdim let Inst{27-26} = 0b00; 598193323Sed} 599198090Srdivackyclass AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 600198090Srdivacky string opc, string asm, list<dag> pattern> 601224145Sdim : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 602198090Srdivacky opc, asm, "", pattern> { 603193323Sed let Inst{24-21} = opcod; 604212904Sdim let Inst{27-26} = 0b00; 605193323Sed} 606198090Srdivackyclass AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 607198090Srdivacky string asm, list<dag> pattern> 608224145Sdim : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 609198090Srdivacky asm, "", pattern> { 610193323Sed let Inst{24-21} = opcod; 611212904Sdim let Inst{27-26} = 0b00; 612193323Sed} 613193323Sed 614193323Sed// loads 615193323Sed 616218893Sdim// LDR/LDRB/STR/STRB/... 617218893Sdimclass AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am, 618218893Sdim Format f, InstrItinClass itin, string opc, string asm, 619218893Sdim list<dag> pattern> 620224145Sdim : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm, 621218893Sdim "", pattern> { 622218893Sdim let Inst{27-25} = op; 623218893Sdim let Inst{24} = 1; // 24 == P 624218893Sdim // 23 == U 625218893Sdim let Inst{22} = isByte; 626218893Sdim let Inst{21} = 0; // 21 == W 627218893Sdim let Inst{20} = isLd; 628193323Sed} 629218893Sdim// Indexed load/stores 630218893Sdimclass AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops, 631218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 632218893Sdim string asm, string cstr, list<dag> pattern> 633224145Sdim : I<oops, iops, AddrMode2, 4, im, f, itin, 634198090Srdivacky opc, asm, cstr, pattern> { 635218893Sdim bits<4> Rt; 636212904Sdim let Inst{27-26} = 0b01; 637218893Sdim let Inst{24} = isPre; // P bit 638218893Sdim let Inst{22} = isByte; // B bit 639218893Sdim let Inst{21} = isPre; // W bit 640218893Sdim let Inst{20} = isLd; // L bit 641218893Sdim let Inst{15-12} = Rt; 642193323Sed} 643226633Sdimclass AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops, 644218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 645218893Sdim string asm, string cstr, list<dag> pattern> 646218893Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 647218893Sdim pattern> { 648218893Sdim // AM2 store w/ two operands: (GPR, am2offset) 649218893Sdim // {12} isAdd 650218893Sdim // {11-0} imm12/Rm 651218893Sdim bits<14> offset; 652218893Sdim bits<4> Rn; 653226633Sdim let Inst{25} = 1; 654218893Sdim let Inst{23} = offset{12}; 655218893Sdim let Inst{19-16} = Rn; 656226633Sdim let Inst{11-5} = offset{11-5}; 657226633Sdim let Inst{4} = 0; 658226633Sdim let Inst{3-0} = offset{3-0}; 659226633Sdim} 660226633Sdim 661226633Sdimclass AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops, 662226633Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 663226633Sdim string asm, string cstr, list<dag> pattern> 664226633Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 665226633Sdim pattern> { 666226633Sdim // AM2 store w/ two operands: (GPR, am2offset) 667226633Sdim // {12} isAdd 668226633Sdim // {11-0} imm12/Rm 669226633Sdim bits<14> offset; 670226633Sdim bits<4> Rn; 671226633Sdim let Inst{25} = 0; 672226633Sdim let Inst{23} = offset{12}; 673226633Sdim let Inst{19-16} = Rn; 674218893Sdim let Inst{11-0} = offset{11-0}; 675193323Sed} 676226633Sdim 677226633Sdim 678221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB 679221345Sdim// but for now use this class for STRT and STRBT. 680221345Sdimclass AI2stridxT<bit isByte, bit isPre, dag oops, dag iops, 681221345Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 682221345Sdim string asm, string cstr, list<dag> pattern> 683221345Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 684221345Sdim pattern> { 685221345Sdim // AM2 store w/ two operands: (GPR, am2offset) 686221345Sdim // {17-14} Rn 687221345Sdim // {13} 1 == Rm, 0 == imm12 688221345Sdim // {12} isAdd 689221345Sdim // {11-0} imm12/Rm 690221345Sdim bits<18> addr; 691221345Sdim let Inst{25} = addr{13}; 692221345Sdim let Inst{23} = addr{12}; 693221345Sdim let Inst{19-16} = addr{17-14}; 694221345Sdim let Inst{11-0} = addr{11-0}; 695221345Sdim} 696193323Sed 697193323Sed// addrmode3 instructions 698218893Sdimclass AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f, 699218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 700224145Sdim : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 701198090Srdivacky opc, asm, "", pattern> { 702218893Sdim bits<14> addr; 703218893Sdim bits<4> Rt; 704198090Srdivacky let Inst{27-25} = 0b000; 705218893Sdim let Inst{24} = 1; // P bit 706218893Sdim let Inst{23} = addr{8}; // U bit 707218893Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 708218893Sdim let Inst{21} = 0; // W bit 709218893Sdim let Inst{20} = op20; // L bit 710218893Sdim let Inst{19-16} = addr{12-9}; // Rn 711218893Sdim let Inst{15-12} = Rt; // Rt 712218893Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 713218893Sdim let Inst{7-4} = op; 714218893Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 715226633Sdim 716226633Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 717193323Sed} 718218893Sdim 719226633Sdimclass AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops, 720218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 721218893Sdim string asm, string cstr, list<dag> pattern> 722224145Sdim : I<oops, iops, AddrMode3, 4, im, f, itin, 723218893Sdim opc, asm, cstr, pattern> { 724218893Sdim bits<4> Rt; 725198090Srdivacky let Inst{27-25} = 0b000; 726218893Sdim let Inst{24} = isPre; // P bit 727218893Sdim let Inst{21} = isPre; // W bit 728218893Sdim let Inst{20} = op20; // L bit 729218893Sdim let Inst{15-12} = Rt; // Rt 730218893Sdim let Inst{7-4} = op; 731193323Sed} 732221345Sdim 733221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB 734221345Sdim// but for now use this class for LDRSBT, LDRHT, LDSHT. 735226633Sdimclass AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops, 736221345Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 737221345Sdim string asm, string cstr, list<dag> pattern> 738226633Sdim : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> { 739221345Sdim // {13} 1 == imm8, 0 == Rm 740221345Sdim // {12-9} Rn 741221345Sdim // {8} isAdd 742221345Sdim // {7-4} imm7_4/zero 743221345Sdim // {3-0} imm3_0/Rm 744226633Sdim bits<4> addr; 745221345Sdim bits<4> Rt; 746221345Sdim let Inst{27-25} = 0b000; 747226633Sdim let Inst{24} = 0; // P bit 748226633Sdim let Inst{21} = 1; 749226633Sdim let Inst{20} = isLoad; // L bit 750226633Sdim let Inst{19-16} = addr; // Rn 751221345Sdim let Inst{15-12} = Rt; // Rt 752221345Sdim let Inst{7-4} = op; 753221345Sdim} 754221345Sdim 755193323Sed// stores 756218893Sdimclass AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin, 757198090Srdivacky string opc, string asm, list<dag> pattern> 758224145Sdim : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 759198090Srdivacky opc, asm, "", pattern> { 760218893Sdim bits<14> addr; 761218893Sdim bits<4> Rt; 762198090Srdivacky let Inst{27-25} = 0b000; 763218893Sdim let Inst{24} = 1; // P bit 764218893Sdim let Inst{23} = addr{8}; // U bit 765218893Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 766218893Sdim let Inst{21} = 0; // W bit 767218893Sdim let Inst{20} = 0; // L bit 768218893Sdim let Inst{19-16} = addr{12-9}; // Rn 769218893Sdim let Inst{15-12} = Rt; // Rt 770218893Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 771218893Sdim let Inst{7-4} = op; 772218893Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 773226633Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 774193323Sed} 775193323Sed 776193323Sed// addrmode4 instructions 777218893Sdimclass AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, 778218893Sdim string asm, string cstr, list<dag> pattern> 779224145Sdim : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> { 780218893Sdim bits<4> p; 781218893Sdim bits<16> regs; 782218893Sdim bits<4> Rn; 783218893Sdim let Inst{31-28} = p; 784193323Sed let Inst{27-25} = 0b100; 785193323Sed let Inst{22} = 0; // S bit 786218893Sdim let Inst{19-16} = Rn; 787218893Sdim let Inst{15-0} = regs; 788193323Sed} 789193323Sed 790193323Sed// Unsigned multiply, multiply-accumulate instructions. 791198090Srdivackyclass AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 792198090Srdivacky string opc, string asm, list<dag> pattern> 793224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 794198090Srdivacky opc, asm, "", pattern> { 795193323Sed let Inst{7-4} = 0b1001; 796193323Sed let Inst{20} = 0; // S bit 797193323Sed let Inst{27-21} = opcod; 798193323Sed} 799198090Srdivackyclass AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 800198090Srdivacky string opc, string asm, list<dag> pattern> 801224145Sdim : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 802198090Srdivacky opc, asm, "", pattern> { 803193323Sed let Inst{7-4} = 0b1001; 804193323Sed let Inst{27-21} = opcod; 805193323Sed} 806193323Sed 807193323Sed// Most significant word multiply 808218893Sdimclass AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 809218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 810224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 811198090Srdivacky opc, asm, "", pattern> { 812218893Sdim bits<4> Rd; 813218893Sdim bits<4> Rn; 814218893Sdim bits<4> Rm; 815218893Sdim let Inst{7-4} = opc7_4; 816193323Sed let Inst{20} = 1; 817193323Sed let Inst{27-21} = opcod; 818218893Sdim let Inst{19-16} = Rd; 819218893Sdim let Inst{11-8} = Rm; 820218893Sdim let Inst{3-0} = Rn; 821193323Sed} 822218893Sdim// MSW multiple w/ Ra operand 823218893Sdimclass AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 824218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 825218893Sdim : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> { 826218893Sdim bits<4> Ra; 827218893Sdim let Inst{15-12} = Ra; 828218893Sdim} 829193323Sed 830193323Sed// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y> 831218893Sdimclass AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 832218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 833224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 834198090Srdivacky opc, asm, "", pattern> { 835218893Sdim bits<4> Rn; 836218893Sdim bits<4> Rm; 837193323Sed let Inst{4} = 0; 838193323Sed let Inst{7} = 1; 839193323Sed let Inst{20} = 0; 840193323Sed let Inst{27-21} = opcod; 841218893Sdim let Inst{6-5} = bit6_5; 842218893Sdim let Inst{11-8} = Rm; 843218893Sdim let Inst{3-0} = Rn; 844193323Sed} 845218893Sdimclass AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 846218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 847218893Sdim : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 848218893Sdim bits<4> Rd; 849218893Sdim let Inst{19-16} = Rd; 850218893Sdim} 851193323Sed 852218893Sdim// AMulxyI with Ra operand 853218893Sdimclass AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 854218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 855218893Sdim : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 856218893Sdim bits<4> Ra; 857218893Sdim let Inst{15-12} = Ra; 858218893Sdim} 859218893Sdim// SMLAL* 860218893Sdimclass AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 861218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 862218893Sdim : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 863218893Sdim bits<4> RdLo; 864218893Sdim bits<4> RdHi; 865218893Sdim let Inst{19-16} = RdHi; 866218893Sdim let Inst{15-12} = RdLo; 867218893Sdim} 868218893Sdim 869193323Sed// Extend instructions. 870198090Srdivackyclass AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 871198090Srdivacky string opc, string asm, list<dag> pattern> 872224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin, 873198090Srdivacky opc, asm, "", pattern> { 874218893Sdim // All AExtI instructions have Rd and Rm register operands. 875218893Sdim bits<4> Rd; 876218893Sdim bits<4> Rm; 877218893Sdim let Inst{15-12} = Rd; 878218893Sdim let Inst{3-0} = Rm; 879193323Sed let Inst{7-4} = 0b0111; 880218893Sdim let Inst{9-8} = 0b00; 881193323Sed let Inst{27-20} = opcod; 882239462Sdim 883239462Sdim let Unpredictable{9-8} = 0b11; 884193323Sed} 885193323Sed 886193323Sed// Misc Arithmetic instructions. 887218893Sdimclass AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops, 888218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 889224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 890198090Srdivacky opc, asm, "", pattern> { 891218893Sdim bits<4> Rd; 892218893Sdim bits<4> Rm; 893193323Sed let Inst{27-20} = opcod; 894218893Sdim let Inst{19-16} = 0b1111; 895218893Sdim let Inst{15-12} = Rd; 896218893Sdim let Inst{11-8} = 0b1111; 897218893Sdim let Inst{7-4} = opc7_4; 898218893Sdim let Inst{3-0} = Rm; 899193323Sed} 900193323Sed 901243830Sdim// Division instructions. 902243830Sdimclass ADivA1I<bits<3> opcod, dag oops, dag iops, 903243830Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 904243830Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 905243830Sdim opc, asm, "", pattern> { 906243830Sdim bits<4> Rd; 907243830Sdim bits<4> Rn; 908243830Sdim bits<4> Rm; 909243830Sdim let Inst{27-23} = 0b01110; 910243830Sdim let Inst{22-20} = opcod; 911243830Sdim let Inst{19-16} = Rd; 912243830Sdim let Inst{15-12} = 0b1111; 913243830Sdim let Inst{11-8} = Rm; 914243830Sdim let Inst{7-4} = 0b0001; 915243830Sdim let Inst{3-0} = Rn; 916243830Sdim} 917243830Sdim 918218893Sdim// PKH instructions 919234353Sdimdef PKHLSLAsmOperand : ImmAsmOperand { 920226633Sdim let Name = "PKHLSLImm"; 921226633Sdim let ParserMethod = "parsePKHLSLImm"; 922226633Sdim} 923226633Sdimdef pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{ 924226633Sdim let PrintMethod = "printPKHLSLShiftImm"; 925226633Sdim let ParserMatchClass = PKHLSLAsmOperand; 926226633Sdim} 927226633Sdimdef PKHASRAsmOperand : AsmOperandClass { 928226633Sdim let Name = "PKHASRImm"; 929226633Sdim let ParserMethod = "parsePKHASRImm"; 930226633Sdim} 931226633Sdimdef pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{ 932226633Sdim let PrintMethod = "printPKHASRShiftImm"; 933226633Sdim let ParserMatchClass = PKHASRAsmOperand; 934226633Sdim} 935226633Sdim 936218893Sdimclass APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin, 937218893Sdim string opc, string asm, list<dag> pattern> 938224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 939218893Sdim opc, asm, "", pattern> { 940218893Sdim bits<4> Rd; 941218893Sdim bits<4> Rn; 942218893Sdim bits<4> Rm; 943226633Sdim bits<5> sh; 944218893Sdim let Inst{27-20} = opcod; 945218893Sdim let Inst{19-16} = Rn; 946218893Sdim let Inst{15-12} = Rd; 947226633Sdim let Inst{11-7} = sh; 948218893Sdim let Inst{6} = tb; 949218893Sdim let Inst{5-4} = 0b01; 950218893Sdim let Inst{3-0} = Rm; 951218893Sdim} 952218893Sdim 953193323Sed//===----------------------------------------------------------------------===// 954193323Sed 955193323Sed// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode. 956193323Sedclass ARMPat<dag pattern, dag result> : Pat<pattern, result> { 957193323Sed list<Predicate> Predicates = [IsARM]; 958193323Sed} 959223017Sdimclass ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> { 960223017Sdim list<Predicate> Predicates = [IsARM, HasV5T]; 961223017Sdim} 962193323Sedclass ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> { 963193323Sed list<Predicate> Predicates = [IsARM, HasV5TE]; 964193323Sed} 965243830Sdim// ARMV5MOPat - Same as ARMV5TEPat with UseMulOps. 966243830Sdimclass ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> { 967243830Sdim list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps]; 968243830Sdim} 969193323Sedclass ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> { 970193323Sed list<Predicate> Predicates = [IsARM, HasV6]; 971193323Sed} 972193323Sed 973193323Sed//===----------------------------------------------------------------------===// 974193323Sed// Thumb Instruction Format Definitions. 975193323Sed// 976193323Sed 977224145Sdimclass ThumbI<dag oops, dag iops, AddrMode am, int sz, 978198090Srdivacky InstrItinClass itin, string asm, string cstr, list<dag> pattern> 979201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 980198090Srdivacky let OutOperandList = oops; 981198090Srdivacky let InOperandList = iops; 982208599Srdivacky let AsmString = asm; 983193323Sed let Pattern = pattern; 984193323Sed list<Predicate> Predicates = [IsThumb]; 985193323Sed} 986193323Sed 987218893Sdim// TI - Thumb instruction. 988198090Srdivackyclass TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 989224145Sdim : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 990193323Sed 991198090Srdivacky// Two-address instructions 992206083Srdivackyclass TIt<dag oops, dag iops, InstrItinClass itin, string asm, 993206083Srdivacky list<dag> pattern> 994224145Sdim : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst", 995206083Srdivacky pattern>; 996193323Sed 997201360Srdivacky// tBL, tBX 32-bit instructions 998201360Srdivackyclass TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3, 999206083Srdivacky dag oops, dag iops, InstrItinClass itin, string asm, 1000206083Srdivacky list<dag> pattern> 1001224145Sdim : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>, 1002206083Srdivacky Encoding { 1003201360Srdivacky let Inst{31-27} = opcod1; 1004201360Srdivacky let Inst{15-14} = opcod2; 1005212904Sdim let Inst{12} = opcod3; 1006201360Srdivacky} 1007198090Srdivacky 1008193323Sed// BR_JT instructions 1009206083Srdivackyclass TJTI<dag oops, dag iops, InstrItinClass itin, string asm, 1010206083Srdivacky list<dag> pattern> 1011224145Sdim : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1012193323Sed 1013198090Srdivacky// Thumb1 only 1014224145Sdimclass Thumb1I<dag oops, dag iops, AddrMode am, int sz, 1015198090Srdivacky InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1016201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1017198090Srdivacky let OutOperandList = oops; 1018198090Srdivacky let InOperandList = iops; 1019208599Srdivacky let AsmString = asm; 1020198090Srdivacky let Pattern = pattern; 1021218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1022194710Sed} 1023193323Sed 1024198090Srdivackyclass T1I<dag oops, dag iops, InstrItinClass itin, 1025198090Srdivacky string asm, list<dag> pattern> 1026224145Sdim : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1027198090Srdivackyclass T1Ix2<dag oops, dag iops, InstrItinClass itin, 1028198090Srdivacky string asm, list<dag> pattern> 1029224145Sdim : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1030194710Sed 1031198090Srdivacky// Two-address instructions 1032198090Srdivackyclass T1It<dag oops, dag iops, InstrItinClass itin, 1033205218Srdivacky string asm, string cstr, list<dag> pattern> 1034224145Sdim : Thumb1I<oops, iops, AddrModeNone, 2, itin, 1035205218Srdivacky asm, cstr, pattern>; 1036198090Srdivacky 1037198090Srdivacky// Thumb1 instruction that can either be predicated or set CPSR. 1038224145Sdimclass Thumb1sI<dag oops, dag iops, AddrMode am, int sz, 1039198090Srdivacky InstrItinClass itin, 1040198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1041201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1042205407Srdivacky let OutOperandList = !con(oops, (outs s_cc_out:$s)); 1043205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1044218893Sdim let AsmString = !strconcat(opc, "${s}${p}", asm); 1045194754Sed let Pattern = pattern; 1046226633Sdim let thumbArithFlagSetting = 1; 1047218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1048226633Sdim let DecoderNamespace = "ThumbSBit"; 1049195098Sed} 1050195098Sed 1051198090Srdivackyclass T1sI<dag oops, dag iops, InstrItinClass itin, 1052198090Srdivacky string opc, string asm, list<dag> pattern> 1053224145Sdim : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1054195098Sed 1055195098Sed// Two-address instructions 1056198090Srdivackyclass T1sIt<dag oops, dag iops, InstrItinClass itin, 1057198090Srdivacky string opc, string asm, list<dag> pattern> 1058224145Sdim : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1059218893Sdim "$Rn = $Rdn", pattern>; 1060195098Sed 1061198090Srdivacky// Thumb1 instruction that can be predicated. 1062224145Sdimclass Thumb1pI<dag oops, dag iops, AddrMode am, int sz, 1063198090Srdivacky InstrItinClass itin, 1064198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1065201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1066198090Srdivacky let OutOperandList = oops; 1067205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1068218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1069198090Srdivacky let Pattern = pattern; 1070218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1071195098Sed} 1072195098Sed 1073198090Srdivackyclass T1pI<dag oops, dag iops, InstrItinClass itin, 1074198090Srdivacky string opc, string asm, list<dag> pattern> 1075224145Sdim : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1076198090Srdivacky 1077198090Srdivacky// Two-address instructions 1078198090Srdivackyclass T1pIt<dag oops, dag iops, InstrItinClass itin, 1079198090Srdivacky string opc, string asm, list<dag> pattern> 1080224145Sdim : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1081218893Sdim "$Rn = $Rdn", pattern>; 1082198090Srdivacky 1083206083Srdivackyclass T1pIs<dag oops, dag iops, 1084198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1085224145Sdim : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>; 1086198090Srdivacky 1087201360Srdivackyclass Encoding16 : Encoding { 1088201360Srdivacky let Inst{31-16} = 0x0000; 1089201360Srdivacky} 1090201360Srdivacky 1091201360Srdivacky// A6.2 16-bit Thumb instruction encoding 1092201360Srdivackyclass T1Encoding<bits<6> opcode> : Encoding16 { 1093201360Srdivacky let Inst{15-10} = opcode; 1094201360Srdivacky} 1095201360Srdivacky 1096201360Srdivacky// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. 1097201360Srdivackyclass T1General<bits<5> opcode> : Encoding16 { 1098201360Srdivacky let Inst{15-14} = 0b00; 1099201360Srdivacky let Inst{13-9} = opcode; 1100201360Srdivacky} 1101201360Srdivacky 1102201360Srdivacky// A6.2.2 Data-processing encoding. 1103201360Srdivackyclass T1DataProcessing<bits<4> opcode> : Encoding16 { 1104201360Srdivacky let Inst{15-10} = 0b010000; 1105201360Srdivacky let Inst{9-6} = opcode; 1106201360Srdivacky} 1107201360Srdivacky 1108201360Srdivacky// A6.2.3 Special data instructions and branch and exchange encoding. 1109201360Srdivackyclass T1Special<bits<4> opcode> : Encoding16 { 1110201360Srdivacky let Inst{15-10} = 0b010001; 1111218893Sdim let Inst{9-6} = opcode; 1112201360Srdivacky} 1113201360Srdivacky 1114201360Srdivacky// A6.2.4 Load/store single data item encoding. 1115201360Srdivackyclass T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 { 1116201360Srdivacky let Inst{15-12} = opA; 1117212904Sdim let Inst{11-9} = opB; 1118201360Srdivacky} 1119212904Sdimclass T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative 1120201360Srdivacky 1121223017Sdimclass T1BranchCond<bits<4> opcode> : Encoding16 { 1122223017Sdim let Inst{15-12} = opcode; 1123223017Sdim} 1124223017Sdim 1125218893Sdim// Helper classes to encode Thumb1 loads and stores. For immediates, the 1126218893Sdim// following bits are used for "opA" (see A6.2.4): 1127218893Sdim// 1128218893Sdim// 0b0110 => Immediate, 4 bytes 1129218893Sdim// 0b1000 => Immediate, 2 bytes 1130218893Sdim// 0b0111 => Immediate, 1 byte 1131218893Sdimclass T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am, 1132218893Sdim InstrItinClass itin, string opc, string asm, 1133218893Sdim list<dag> pattern> 1134224145Sdim : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1135218893Sdim T1LoadStore<0b0101, opcode> { 1136218893Sdim bits<3> Rt; 1137218893Sdim bits<8> addr; 1138218893Sdim let Inst{8-6} = addr{5-3}; // Rm 1139218893Sdim let Inst{5-3} = addr{2-0}; // Rn 1140218893Sdim let Inst{2-0} = Rt; 1141218893Sdim} 1142218893Sdimclass T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am, 1143218893Sdim InstrItinClass itin, string opc, string asm, 1144218893Sdim list<dag> pattern> 1145224145Sdim : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1146218893Sdim T1LoadStore<opA, {opB,?,?}> { 1147218893Sdim bits<3> Rt; 1148218893Sdim bits<8> addr; 1149218893Sdim let Inst{10-6} = addr{7-3}; // imm5 1150218893Sdim let Inst{5-3} = addr{2-0}; // Rn 1151218893Sdim let Inst{2-0} = Rt; 1152218893Sdim} 1153218893Sdim 1154201360Srdivacky// A6.2.5 Miscellaneous 16-bit instructions encoding. 1155201360Srdivackyclass T1Misc<bits<7> opcode> : Encoding16 { 1156201360Srdivacky let Inst{15-12} = 0b1011; 1157201360Srdivacky let Inst{11-5} = opcode; 1158201360Srdivacky} 1159201360Srdivacky 1160195098Sed// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 1161224145Sdimclass Thumb2I<dag oops, dag iops, AddrMode am, int sz, 1162198090Srdivacky InstrItinClass itin, 1163195098Sed string opc, string asm, string cstr, list<dag> pattern> 1164198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1165195098Sed let OutOperandList = oops; 1166205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1167218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1168195098Sed let Pattern = pattern; 1169195340Sed list<Predicate> Predicates = [IsThumb2]; 1170226633Sdim let DecoderNamespace = "Thumb2"; 1171194754Sed} 1172194754Sed 1173212904Sdim// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an 1174212904Sdim// input operand since by default it's a zero register. It will become an 1175212904Sdim// implicit def once it's "flipped". 1176218893Sdim// 1177195098Sed// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 1178195098Sed// more consistent. 1179224145Sdimclass Thumb2sI<dag oops, dag iops, AddrMode am, int sz, 1180198090Srdivacky InstrItinClass itin, 1181195098Sed string opc, string asm, string cstr, list<dag> pattern> 1182198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1183218893Sdim bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 1184218893Sdim let Inst{20} = s; 1185218893Sdim 1186195098Sed let OutOperandList = oops; 1187205407Srdivacky let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 1188218893Sdim let AsmString = !strconcat(opc, "${s}${p}", asm); 1189195098Sed let Pattern = pattern; 1190195340Sed list<Predicate> Predicates = [IsThumb2]; 1191226633Sdim let DecoderNamespace = "Thumb2"; 1192195098Sed} 1193194754Sed 1194195098Sed// Special cases 1195224145Sdimclass Thumb2XI<dag oops, dag iops, AddrMode am, int sz, 1196198090Srdivacky InstrItinClass itin, 1197195098Sed string asm, string cstr, list<dag> pattern> 1198198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1199195098Sed let OutOperandList = oops; 1200195098Sed let InOperandList = iops; 1201208599Srdivacky let AsmString = asm; 1202195098Sed let Pattern = pattern; 1203195340Sed list<Predicate> Predicates = [IsThumb2]; 1204226633Sdim let DecoderNamespace = "Thumb2"; 1205194754Sed} 1206194754Sed 1207224145Sdimclass ThumbXI<dag oops, dag iops, AddrMode am, int sz, 1208206083Srdivacky InstrItinClass itin, 1209206083Srdivacky string asm, string cstr, list<dag> pattern> 1210200581Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1211200581Srdivacky let OutOperandList = oops; 1212200581Srdivacky let InOperandList = iops; 1213208599Srdivacky let AsmString = asm; 1214200581Srdivacky let Pattern = pattern; 1215218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1216226633Sdim let DecoderNamespace = "Thumb"; 1217200581Srdivacky} 1218200581Srdivacky 1219198090Srdivackyclass T2I<dag oops, dag iops, InstrItinClass itin, 1220198090Srdivacky string opc, string asm, list<dag> pattern> 1221224145Sdim : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1222198090Srdivackyclass T2Ii12<dag oops, dag iops, InstrItinClass itin, 1223198090Srdivacky string opc, string asm, list<dag> pattern> 1224224145Sdim : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>; 1225198090Srdivackyclass T2Ii8<dag oops, dag iops, InstrItinClass itin, 1226198090Srdivacky string opc, string asm, list<dag> pattern> 1227224145Sdim : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>; 1228198090Srdivackyclass T2Iso<dag oops, dag iops, InstrItinClass itin, 1229198090Srdivacky string opc, string asm, list<dag> pattern> 1230224145Sdim : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>; 1231198090Srdivackyclass T2Ipc<dag oops, dag iops, InstrItinClass itin, 1232198090Srdivacky string opc, string asm, list<dag> pattern> 1233224145Sdim : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>; 1234218893Sdimclass T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin, 1235226633Sdim string opc, string asm, string cstr, list<dag> pattern> 1236226633Sdim : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1237201360Srdivacky pattern> { 1238218893Sdim bits<4> Rt; 1239218893Sdim bits<4> Rt2; 1240218893Sdim bits<13> addr; 1241218893Sdim let Inst{31-25} = 0b1110100; 1242212904Sdim let Inst{24} = P; 1243218893Sdim let Inst{23} = addr{8}; 1244212904Sdim let Inst{22} = 1; 1245212904Sdim let Inst{21} = W; 1246218893Sdim let Inst{20} = isLoad; 1247218893Sdim let Inst{19-16} = addr{12-9}; 1248218893Sdim let Inst{15-12} = Rt{3-0}; 1249218893Sdim let Inst{11-8} = Rt2{3-0}; 1250218893Sdim let Inst{7-0} = addr{7-0}; 1251201360Srdivacky} 1252226633Sdimclass T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops, 1253226633Sdim InstrItinClass itin, string opc, string asm, string cstr, 1254226633Sdim list<dag> pattern> 1255226633Sdim : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1256226633Sdim pattern> { 1257226633Sdim bits<4> Rt; 1258226633Sdim bits<4> Rt2; 1259226633Sdim bits<4> addr; 1260226633Sdim bits<9> imm; 1261226633Sdim let Inst{31-25} = 0b1110100; 1262226633Sdim let Inst{24} = P; 1263226633Sdim let Inst{23} = imm{8}; 1264226633Sdim let Inst{22} = 1; 1265226633Sdim let Inst{21} = W; 1266226633Sdim let Inst{20} = isLoad; 1267226633Sdim let Inst{19-16} = addr; 1268226633Sdim let Inst{15-12} = Rt{3-0}; 1269226633Sdim let Inst{11-8} = Rt2{3-0}; 1270226633Sdim let Inst{7-0} = imm{7-0}; 1271226633Sdim} 1272195098Sed 1273198090Srdivackyclass T2sI<dag oops, dag iops, InstrItinClass itin, 1274198090Srdivacky string opc, string asm, list<dag> pattern> 1275224145Sdim : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1276195098Sed 1277198090Srdivackyclass T2XI<dag oops, dag iops, InstrItinClass itin, 1278198090Srdivacky string asm, list<dag> pattern> 1279224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1280198090Srdivackyclass T2JTI<dag oops, dag iops, InstrItinClass itin, 1281198090Srdivacky string asm, list<dag> pattern> 1282224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1283195098Sed 1284218893Sdim// Move to/from coprocessor instructions 1285263508Sdimclass T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm, 1286263508Sdim list<dag> pattern> 1287263508Sdim : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> { 1288224145Sdim let Inst{31-28} = opc; 1289218893Sdim} 1290198090Srdivacky 1291205218Srdivacky// Two-address instructions 1292205218Srdivackyclass T2XIt<dag oops, dag iops, InstrItinClass itin, 1293205218Srdivacky string asm, string cstr, list<dag> pattern> 1294224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>; 1295198090Srdivacky 1296226633Sdim// T2Ipreldst - Thumb2 pre-indexed load / store instructions. 1297226633Sdimclass T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre, 1298201360Srdivacky dag oops, dag iops, 1299201360Srdivacky AddrMode am, IndexMode im, InstrItinClass itin, 1300195340Sed string opc, string asm, string cstr, list<dag> pattern> 1301224145Sdim : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1302195340Sed let OutOperandList = oops; 1303205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1304218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1305195340Sed let Pattern = pattern; 1306195340Sed list<Predicate> Predicates = [IsThumb2]; 1307226633Sdim let DecoderNamespace = "Thumb2"; 1308226633Sdim 1309226633Sdim bits<4> Rt; 1310226633Sdim bits<13> addr; 1311201360Srdivacky let Inst{31-27} = 0b11111; 1312201360Srdivacky let Inst{26-25} = 0b00; 1313212904Sdim let Inst{24} = signed; 1314212904Sdim let Inst{23} = 0; 1315201360Srdivacky let Inst{22-21} = opcod; 1316212904Sdim let Inst{20} = load; 1317226633Sdim let Inst{19-16} = addr{12-9}; 1318226633Sdim let Inst{15-12} = Rt{3-0}; 1319212904Sdim let Inst{11} = 1; 1320201360Srdivacky // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1321212904Sdim let Inst{10} = pre; // The P bit. 1322226633Sdim let Inst{9} = addr{8}; // Sign bit 1323212904Sdim let Inst{8} = 1; // The W bit. 1324226633Sdim let Inst{7-0} = addr{7-0}; 1325195340Sed 1326226633Sdim let DecoderMethod = "DecodeT2LdStPre"; 1327226633Sdim} 1328218893Sdim 1329226633Sdim// T2Ipostldst - Thumb2 post-indexed load / store instructions. 1330226633Sdimclass T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, 1331226633Sdim dag oops, dag iops, 1332226633Sdim AddrMode am, IndexMode im, InstrItinClass itin, 1333226633Sdim string opc, string asm, string cstr, list<dag> pattern> 1334226633Sdim : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1335226633Sdim let OutOperandList = oops; 1336226633Sdim let InOperandList = !con(iops, (ins pred:$p)); 1337226633Sdim let AsmString = !strconcat(opc, "${p}", asm); 1338226633Sdim let Pattern = pattern; 1339226633Sdim list<Predicate> Predicates = [IsThumb2]; 1340226633Sdim let DecoderNamespace = "Thumb2"; 1341226633Sdim 1342218893Sdim bits<4> Rt; 1343218893Sdim bits<4> Rn; 1344226633Sdim bits<9> offset; 1345226633Sdim let Inst{31-27} = 0b11111; 1346226633Sdim let Inst{26-25} = 0b00; 1347226633Sdim let Inst{24} = signed; 1348226633Sdim let Inst{23} = 0; 1349226633Sdim let Inst{22-21} = opcod; 1350226633Sdim let Inst{20} = load; 1351226633Sdim let Inst{19-16} = Rn; 1352218893Sdim let Inst{15-12} = Rt{3-0}; 1353226633Sdim let Inst{11} = 1; 1354226633Sdim // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1355226633Sdim let Inst{10} = pre; // The P bit. 1356226633Sdim let Inst{9} = offset{8}; // Sign bit 1357226633Sdim let Inst{8} = 1; // The W bit. 1358226633Sdim let Inst{7-0} = offset{7-0}; 1359226633Sdim 1360226633Sdim let DecoderMethod = "DecodeT2LdStPre"; 1361204642Srdivacky} 1362204642Srdivacky 1363198090Srdivacky// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. 1364198090Srdivackyclass Tv5Pat<dag pattern, dag result> : Pat<pattern, result> { 1365218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T]; 1366198090Srdivacky} 1367195340Sed 1368198090Srdivacky// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 1369198090Srdivackyclass T1Pat<dag pattern, dag result> : Pat<pattern, result> { 1370218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1371198090Srdivacky} 1372198090Srdivacky 1373223017Sdim// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode. 1374223017Sdimclass T2v6Pat<dag pattern, dag result> : Pat<pattern, result> { 1375223017Sdim list<Predicate> Predicates = [IsThumb2, HasV6T2]; 1376223017Sdim} 1377223017Sdim 1378195098Sed// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 1379195098Sedclass T2Pat<dag pattern, dag result> : Pat<pattern, result> { 1380195340Sed list<Predicate> Predicates = [IsThumb2]; 1381195098Sed} 1382195098Sed 1383193323Sed//===----------------------------------------------------------------------===// 1384193323Sed 1385193323Sed//===----------------------------------------------------------------------===// 1386193323Sed// ARM VFP Instruction templates. 1387193323Sed// 1388193323Sed 1389198090Srdivacky// Almost all VFP instructions are predicable. 1390224145Sdimclass VFPI<dag oops, dag iops, AddrMode am, int sz, 1391198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 1392198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1393198892Srdivacky : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1394218893Sdim bits<4> p; 1395218893Sdim let Inst{31-28} = p; 1396198090Srdivacky let OutOperandList = oops; 1397205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1398218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1399198090Srdivacky let Pattern = pattern; 1400218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1401226633Sdim let DecoderNamespace = "VFP"; 1402198090Srdivacky list<Predicate> Predicates = [HasVFP2]; 1403198090Srdivacky} 1404198090Srdivacky 1405198090Srdivacky// Special cases 1406224145Sdimclass VFPXI<dag oops, dag iops, AddrMode am, int sz, 1407198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 1408198090Srdivacky string asm, string cstr, list<dag> pattern> 1409198892Srdivacky : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1410218893Sdim bits<4> p; 1411218893Sdim let Inst{31-28} = p; 1412198090Srdivacky let OutOperandList = oops; 1413198090Srdivacky let InOperandList = iops; 1414208599Srdivacky let AsmString = asm; 1415198090Srdivacky let Pattern = pattern; 1416218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1417226633Sdim let DecoderNamespace = "VFP"; 1418198090Srdivacky list<Predicate> Predicates = [HasVFP2]; 1419198090Srdivacky} 1420198090Srdivacky 1421198090Srdivackyclass VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 1422198090Srdivacky string opc, string asm, list<dag> pattern> 1423224145Sdim : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 1424218893Sdim opc, asm, "", pattern> { 1425218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1426218893Sdim} 1427198090Srdivacky 1428193323Sed// ARM VFP addrmode5 loads and stores 1429193323Sedclass ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1430198090Srdivacky InstrItinClass itin, 1431193323Sed string opc, string asm, list<dag> pattern> 1432224145Sdim : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1433206083Srdivacky VFPLdStFrm, itin, opc, asm, "", pattern> { 1434218893Sdim // Instruction operands. 1435218893Sdim bits<5> Dd; 1436218893Sdim bits<13> addr; 1437218893Sdim 1438218893Sdim // Encode instruction operands. 1439218893Sdim let Inst{23} = addr{8}; // U (add = (U == '1')) 1440218893Sdim let Inst{22} = Dd{4}; 1441218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1442218893Sdim let Inst{15-12} = Dd{3-0}; 1443218893Sdim let Inst{7-0} = addr{7-0}; // imm8 1444218893Sdim 1445193323Sed let Inst{27-24} = opcod1; 1446193323Sed let Inst{21-20} = opcod2; 1447218893Sdim let Inst{11-9} = 0b101; 1448218893Sdim let Inst{8} = 1; // Double precision 1449198892Srdivacky 1450218893Sdim // Loads & stores operate on both NEON and VFP pipelines. 1451206274Srdivacky let D = VFPNeonDomain; 1452193323Sed} 1453193323Sed 1454193323Sedclass ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1455198090Srdivacky InstrItinClass itin, 1456193323Sed string opc, string asm, list<dag> pattern> 1457224145Sdim : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1458206083Srdivacky VFPLdStFrm, itin, opc, asm, "", pattern> { 1459218893Sdim // Instruction operands. 1460218893Sdim bits<5> Sd; 1461218893Sdim bits<13> addr; 1462218893Sdim 1463218893Sdim // Encode instruction operands. 1464218893Sdim let Inst{23} = addr{8}; // U (add = (U == '1')) 1465218893Sdim let Inst{22} = Sd{0}; 1466218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1467218893Sdim let Inst{15-12} = Sd{4-1}; 1468218893Sdim let Inst{7-0} = addr{7-0}; // imm8 1469218893Sdim 1470193323Sed let Inst{27-24} = opcod1; 1471193323Sed let Inst{21-20} = opcod2; 1472218893Sdim let Inst{11-9} = 0b101; 1473218893Sdim let Inst{8} = 0; // Single precision 1474218893Sdim 1475218893Sdim // Loads & stores operate on both NEON and VFP pipelines. 1476218893Sdim let D = VFPNeonDomain; 1477193323Sed} 1478193323Sed 1479218893Sdim// VFP Load / store multiple pseudo instructions. 1480218893Sdimclass PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, 1481218893Sdim list<dag> pattern> 1482224145Sdim : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain, 1483218893Sdim cstr, itin> { 1484218893Sdim let OutOperandList = oops; 1485218893Sdim let InOperandList = !con(iops, (ins pred:$p)); 1486218893Sdim let Pattern = pattern; 1487218893Sdim list<Predicate> Predicates = [HasVFP2]; 1488218893Sdim} 1489218893Sdim 1490193323Sed// Load / store multiple 1491263508Sdim 1492263508Sdim// Unknown precision 1493263508Sdimclass AXXI4<dag oops, dag iops, IndexMode im, 1494263508Sdim string asm, string cstr, list<dag> pattern> 1495263508Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1496263508Sdim VFPLdStFrm, NoItinerary, asm, cstr, pattern> { 1497263508Sdim // Instruction operands. 1498263508Sdim bits<4> Rn; 1499263508Sdim bits<13> regs; 1500263508Sdim 1501263508Sdim // Encode instruction operands. 1502263508Sdim let Inst{19-16} = Rn; 1503263508Sdim let Inst{22} = 0; 1504263508Sdim let Inst{15-12} = regs{11-8}; 1505263508Sdim let Inst{7-1} = regs{7-1}; 1506263508Sdim 1507263508Sdim let Inst{27-25} = 0b110; 1508263508Sdim let Inst{11-8} = 0b1011; 1509263508Sdim let Inst{0} = 1; 1510263508Sdim} 1511263508Sdim 1512263508Sdim// Double precision 1513212904Sdimclass AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1514205218Srdivacky string asm, string cstr, list<dag> pattern> 1515224145Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1516206083Srdivacky VFPLdStMulFrm, itin, asm, cstr, pattern> { 1517218893Sdim // Instruction operands. 1518218893Sdim bits<4> Rn; 1519218893Sdim bits<13> regs; 1520218893Sdim 1521218893Sdim // Encode instruction operands. 1522218893Sdim let Inst{19-16} = Rn; 1523218893Sdim let Inst{22} = regs{12}; 1524218893Sdim let Inst{15-12} = regs{11-8}; 1525263508Sdim let Inst{7-1} = regs{7-1}; 1526218893Sdim 1527193323Sed let Inst{27-25} = 0b110; 1528218893Sdim let Inst{11-9} = 0b101; 1529218893Sdim let Inst{8} = 1; // Double precision 1530263508Sdim let Inst{0} = 0; 1531193323Sed} 1532193323Sed 1533263508Sdim// Single Precision 1534212904Sdimclass AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1535205218Srdivacky string asm, string cstr, list<dag> pattern> 1536224145Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1537206083Srdivacky VFPLdStMulFrm, itin, asm, cstr, pattern> { 1538218893Sdim // Instruction operands. 1539218893Sdim bits<4> Rn; 1540218893Sdim bits<13> regs; 1541218893Sdim 1542218893Sdim // Encode instruction operands. 1543218893Sdim let Inst{19-16} = Rn; 1544218893Sdim let Inst{22} = regs{8}; 1545218893Sdim let Inst{15-12} = regs{12-9}; 1546218893Sdim let Inst{7-0} = regs{7-0}; 1547218893Sdim 1548193323Sed let Inst{27-25} = 0b110; 1549218893Sdim let Inst{11-9} = 0b101; 1550218893Sdim let Inst{8} = 0; // Single precision 1551193323Sed} 1552193323Sed 1553193323Sed// Double precision, unary 1554203954Srdivackyclass ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1555203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1556203954Srdivacky string asm, list<dag> pattern> 1557198090Srdivacky : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1558218893Sdim // Instruction operands. 1559218893Sdim bits<5> Dd; 1560218893Sdim bits<5> Dm; 1561218893Sdim 1562218893Sdim // Encode instruction operands. 1563218893Sdim let Inst{3-0} = Dm{3-0}; 1564218893Sdim let Inst{5} = Dm{4}; 1565218893Sdim let Inst{15-12} = Dd{3-0}; 1566218893Sdim let Inst{22} = Dd{4}; 1567218893Sdim 1568203954Srdivacky let Inst{27-23} = opcod1; 1569203954Srdivacky let Inst{21-20} = opcod2; 1570203954Srdivacky let Inst{19-16} = opcod3; 1571218893Sdim let Inst{11-9} = 0b101; 1572218893Sdim let Inst{8} = 1; // Double precision 1573203954Srdivacky let Inst{7-6} = opcod4; 1574203954Srdivacky let Inst{4} = opcod5; 1575263508Sdim 1576263508Sdim let Predicates = [HasVFP2, HasDPVFP]; 1577193323Sed} 1578193323Sed 1579263508Sdim// Double precision, unary, not-predicated 1580263508Sdimclass ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1581263508Sdim bit opcod5, dag oops, dag iops, InstrItinClass itin, 1582263508Sdim string asm, list<dag> pattern> 1583263508Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> { 1584263508Sdim // Instruction operands. 1585263508Sdim bits<5> Dd; 1586263508Sdim bits<5> Dm; 1587263508Sdim 1588263508Sdim let Inst{31-28} = 0b1111; 1589263508Sdim 1590263508Sdim // Encode instruction operands. 1591263508Sdim let Inst{3-0} = Dm{3-0}; 1592263508Sdim let Inst{5} = Dm{4}; 1593263508Sdim let Inst{15-12} = Dd{3-0}; 1594263508Sdim let Inst{22} = Dd{4}; 1595263508Sdim 1596263508Sdim let Inst{27-23} = opcod1; 1597263508Sdim let Inst{21-20} = opcod2; 1598263508Sdim let Inst{19-16} = opcod3; 1599263508Sdim let Inst{11-9} = 0b101; 1600263508Sdim let Inst{8} = 1; // Double precision 1601263508Sdim let Inst{7-6} = opcod4; 1602263508Sdim let Inst{4} = opcod5; 1603263508Sdim} 1604263508Sdim 1605193323Sed// Double precision, binary 1606203954Srdivackyclass ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1607206083Srdivacky dag iops, InstrItinClass itin, string opc, string asm, 1608206083Srdivacky list<dag> pattern> 1609198090Srdivacky : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1610218893Sdim // Instruction operands. 1611218893Sdim bits<5> Dd; 1612218893Sdim bits<5> Dn; 1613218893Sdim bits<5> Dm; 1614193323Sed 1615218893Sdim // Encode instruction operands. 1616218893Sdim let Inst{3-0} = Dm{3-0}; 1617218893Sdim let Inst{5} = Dm{4}; 1618218893Sdim let Inst{19-16} = Dn{3-0}; 1619218893Sdim let Inst{7} = Dn{4}; 1620218893Sdim let Inst{15-12} = Dd{3-0}; 1621218893Sdim let Inst{22} = Dd{4}; 1622218893Sdim 1623206083Srdivacky let Inst{27-23} = opcod1; 1624206083Srdivacky let Inst{21-20} = opcod2; 1625218893Sdim let Inst{11-9} = 0b101; 1626218893Sdim let Inst{8} = 1; // Double precision 1627212904Sdim let Inst{6} = op6; 1628212904Sdim let Inst{4} = op4; 1629263508Sdim 1630263508Sdim let Predicates = [HasVFP2, HasDPVFP]; 1631206083Srdivacky} 1632206083Srdivacky 1633263508Sdim// FP, binary, not predicated 1634263508Sdimclass ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1635263508Sdim InstrItinClass itin, string asm, list<dag> pattern> 1636263508Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin, 1637263508Sdim asm, "", pattern> 1638263508Sdim{ 1639263508Sdim // Instruction operands. 1640263508Sdim bits<5> Dd; 1641263508Sdim bits<5> Dn; 1642263508Sdim bits<5> Dm; 1643263508Sdim 1644263508Sdim let Inst{31-28} = 0b1111; 1645263508Sdim 1646263508Sdim // Encode instruction operands. 1647263508Sdim let Inst{3-0} = Dm{3-0}; 1648263508Sdim let Inst{5} = Dm{4}; 1649263508Sdim let Inst{19-16} = Dn{3-0}; 1650263508Sdim let Inst{7} = Dn{4}; 1651263508Sdim let Inst{15-12} = Dd{3-0}; 1652263508Sdim let Inst{22} = Dd{4}; 1653263508Sdim 1654263508Sdim let Inst{27-23} = opcod1; 1655263508Sdim let Inst{21-20} = opcod2; 1656263508Sdim let Inst{11-9} = 0b101; 1657263508Sdim let Inst{8} = 1; // double precision 1658263508Sdim let Inst{6} = opcod3; 1659263508Sdim let Inst{4} = 0; 1660263508Sdim 1661263508Sdim let Predicates = [HasVFP2, HasDPVFP]; 1662263508Sdim} 1663263508Sdim 1664263508Sdim// Single precision, unary, predicated 1665203954Srdivackyclass ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1666203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1667203954Srdivacky string asm, list<dag> pattern> 1668198090Srdivacky : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1669218893Sdim // Instruction operands. 1670218893Sdim bits<5> Sd; 1671218893Sdim bits<5> Sm; 1672218893Sdim 1673218893Sdim // Encode instruction operands. 1674218893Sdim let Inst{3-0} = Sm{4-1}; 1675218893Sdim let Inst{5} = Sm{0}; 1676218893Sdim let Inst{15-12} = Sd{4-1}; 1677218893Sdim let Inst{22} = Sd{0}; 1678218893Sdim 1679203954Srdivacky let Inst{27-23} = opcod1; 1680203954Srdivacky let Inst{21-20} = opcod2; 1681203954Srdivacky let Inst{19-16} = opcod3; 1682218893Sdim let Inst{11-9} = 0b101; 1683218893Sdim let Inst{8} = 0; // Single precision 1684203954Srdivacky let Inst{7-6} = opcod4; 1685203954Srdivacky let Inst{4} = opcod5; 1686193323Sed} 1687193323Sed 1688263508Sdim// Single precision, unary, non-predicated 1689263508Sdimclass ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1690263508Sdim bit opcod5, dag oops, dag iops, InstrItinClass itin, 1691263508Sdim string asm, list<dag> pattern> 1692263508Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1693263508Sdim VFPUnaryFrm, itin, asm, "", pattern> { 1694263508Sdim // Instruction operands. 1695263508Sdim bits<5> Sd; 1696263508Sdim bits<5> Sm; 1697263508Sdim 1698263508Sdim let Inst{31-28} = 0b1111; 1699263508Sdim 1700263508Sdim // Encode instruction operands. 1701263508Sdim let Inst{3-0} = Sm{4-1}; 1702263508Sdim let Inst{5} = Sm{0}; 1703263508Sdim let Inst{15-12} = Sd{4-1}; 1704263508Sdim let Inst{22} = Sd{0}; 1705263508Sdim 1706263508Sdim let Inst{27-23} = opcod1; 1707263508Sdim let Inst{21-20} = opcod2; 1708263508Sdim let Inst{19-16} = opcod3; 1709263508Sdim let Inst{11-9} = 0b101; 1710263508Sdim let Inst{8} = 0; // Single precision 1711263508Sdim let Inst{7-6} = opcod4; 1712263508Sdim let Inst{4} = opcod5; 1713263508Sdim} 1714263508Sdim 1715218893Sdim// Single precision unary, if no NEON. Same as ASuI except not available if 1716218893Sdim// NEON is enabled. 1717203954Srdivackyclass ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1718203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1719203954Srdivacky string asm, list<dag> pattern> 1720203954Srdivacky : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm, 1721203954Srdivacky pattern> { 1722198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1723198090Srdivacky} 1724198090Srdivacky 1725193323Sed// Single precision, binary 1726203954Srdivackyclass ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 1727203954Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1728198090Srdivacky : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1729218893Sdim // Instruction operands. 1730218893Sdim bits<5> Sd; 1731218893Sdim bits<5> Sn; 1732218893Sdim bits<5> Sm; 1733218893Sdim 1734218893Sdim // Encode instruction operands. 1735218893Sdim let Inst{3-0} = Sm{4-1}; 1736218893Sdim let Inst{5} = Sm{0}; 1737218893Sdim let Inst{19-16} = Sn{4-1}; 1738218893Sdim let Inst{7} = Sn{0}; 1739218893Sdim let Inst{15-12} = Sd{4-1}; 1740218893Sdim let Inst{22} = Sd{0}; 1741218893Sdim 1742203954Srdivacky let Inst{27-23} = opcod1; 1743203954Srdivacky let Inst{21-20} = opcod2; 1744218893Sdim let Inst{11-9} = 0b101; 1745218893Sdim let Inst{8} = 0; // Single precision 1746212904Sdim let Inst{6} = op6; 1747212904Sdim let Inst{4} = op4; 1748193323Sed} 1749193323Sed 1750263508Sdim// Single precision, binary, not predicated 1751263508Sdimclass ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1752263508Sdim InstrItinClass itin, string asm, list<dag> pattern> 1753263508Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1754263508Sdim VFPBinaryFrm, itin, asm, "", pattern> 1755263508Sdim{ 1756263508Sdim // Instruction operands. 1757263508Sdim bits<5> Sd; 1758263508Sdim bits<5> Sn; 1759263508Sdim bits<5> Sm; 1760263508Sdim 1761263508Sdim let Inst{31-28} = 0b1111; 1762263508Sdim 1763263508Sdim // Encode instruction operands. 1764263508Sdim let Inst{3-0} = Sm{4-1}; 1765263508Sdim let Inst{5} = Sm{0}; 1766263508Sdim let Inst{19-16} = Sn{4-1}; 1767263508Sdim let Inst{7} = Sn{0}; 1768263508Sdim let Inst{15-12} = Sd{4-1}; 1769263508Sdim let Inst{22} = Sd{0}; 1770263508Sdim 1771263508Sdim let Inst{27-23} = opcod1; 1772263508Sdim let Inst{21-20} = opcod2; 1773263508Sdim let Inst{11-9} = 0b101; 1774263508Sdim let Inst{8} = 0; // Single precision 1775263508Sdim let Inst{6} = opcod3; 1776263508Sdim let Inst{4} = 0; 1777263508Sdim} 1778263508Sdim 1779218893Sdim// Single precision binary, if no NEON. Same as ASbI except not available if 1780218893Sdim// NEON is enabled. 1781203954Srdivackyclass ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1782206083Srdivacky dag iops, InstrItinClass itin, string opc, string asm, 1783206083Srdivacky list<dag> pattern> 1784203954Srdivacky : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> { 1785198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1786218893Sdim 1787218893Sdim // Instruction operands. 1788218893Sdim bits<5> Sd; 1789218893Sdim bits<5> Sn; 1790218893Sdim bits<5> Sm; 1791218893Sdim 1792218893Sdim // Encode instruction operands. 1793218893Sdim let Inst{3-0} = Sm{4-1}; 1794218893Sdim let Inst{5} = Sm{0}; 1795218893Sdim let Inst{19-16} = Sn{4-1}; 1796218893Sdim let Inst{7} = Sn{0}; 1797218893Sdim let Inst{15-12} = Sd{4-1}; 1798218893Sdim let Inst{22} = Sd{0}; 1799198090Srdivacky} 1800198090Srdivacky 1801193323Sed// VFP conversion instructions 1802203954Srdivackyclass AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 1803203954Srdivacky dag oops, dag iops, InstrItinClass itin, string opc, string asm, 1804203954Srdivacky list<dag> pattern> 1805198090Srdivacky : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> { 1806203954Srdivacky let Inst{27-23} = opcod1; 1807203954Srdivacky let Inst{21-20} = opcod2; 1808203954Srdivacky let Inst{19-16} = opcod3; 1809203954Srdivacky let Inst{11-8} = opcod4; 1810193323Sed let Inst{6} = 1; 1811203954Srdivacky let Inst{4} = 0; 1812193323Sed} 1813193323Sed 1814203954Srdivacky// VFP conversion between floating-point and fixed-point 1815203954Srdivackyclass AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, 1816206083Srdivacky dag oops, dag iops, InstrItinClass itin, string opc, string asm, 1817206083Srdivacky list<dag> pattern> 1818203954Srdivacky : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> { 1819234353Sdim bits<5> fbits; 1820203954Srdivacky // size (fixed-point number): sx == 0 ? 16 : 32 1821203954Srdivacky let Inst{7} = op5; // sx 1822234353Sdim let Inst{5} = fbits{0}; 1823234353Sdim let Inst{3-0} = fbits{4-1}; 1824203954Srdivacky} 1825203954Srdivacky 1826198090Srdivacky// VFP conversion instructions, if no NEON 1827203954Srdivackyclass AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 1828198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1829198090Srdivacky string opc, string asm, list<dag> pattern> 1830203954Srdivacky : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1831203954Srdivacky pattern> { 1832198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1833198090Srdivacky} 1834198090Srdivacky 1835193323Sedclass AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 1836198090Srdivacky InstrItinClass itin, 1837198090Srdivacky string opc, string asm, list<dag> pattern> 1838198090Srdivacky : VFPAI<oops, iops, f, itin, opc, asm, pattern> { 1839193323Sed let Inst{27-20} = opcod1; 1840193323Sed let Inst{11-8} = opcod2; 1841193323Sed let Inst{4} = 1; 1842193323Sed} 1843193323Sed 1844198090Srdivackyclass AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1845198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1846198090Srdivacky : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>; 1847193323Sed 1848206083Srdivackyclass AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1849198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1850198090Srdivacky : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>; 1851193323Sed 1852198090Srdivackyclass AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1853198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1854198090Srdivacky : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>; 1855193323Sed 1856198090Srdivackyclass AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1857198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1858198090Srdivacky : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 1859193323Sed 1860193323Sed//===----------------------------------------------------------------------===// 1861193323Sed 1862194710Sed//===----------------------------------------------------------------------===// 1863194710Sed// ARM NEON Instruction templates. 1864194710Sed// 1865193323Sed 1866205407Srdivackyclass NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1867205407Srdivacky InstrItinClass itin, string opc, string dt, string asm, string cstr, 1868205407Srdivacky list<dag> pattern> 1869224145Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1870194710Sed let OutOperandList = oops; 1871205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1872218893Sdim let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 1873194710Sed let Pattern = pattern; 1874194710Sed list<Predicate> Predicates = [HasNEON]; 1875226633Sdim let DecoderNamespace = "NEON"; 1876193323Sed} 1877193323Sed 1878199989Srdivacky// Same as NeonI except it does not have a "data type" specifier. 1879206083Srdivackyclass NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1880206083Srdivacky InstrItinClass itin, string opc, string asm, string cstr, 1881206083Srdivacky list<dag> pattern> 1882224145Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1883199989Srdivacky let OutOperandList = oops; 1884205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1885218893Sdim let AsmString = !strconcat(opc, "${p}", "\t", asm); 1886199989Srdivacky let Pattern = pattern; 1887199989Srdivacky list<Predicate> Predicates = [HasNEON]; 1888226633Sdim let DecoderNamespace = "NEON"; 1889193323Sed} 1890194710Sed 1891263508Sdim// Same as NeonI except it is not predicated 1892263508Sdimclass NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1893263508Sdim InstrItinClass itin, string opc, string dt, string asm, string cstr, 1894263508Sdim list<dag> pattern> 1895263508Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1896263508Sdim let OutOperandList = oops; 1897263508Sdim let InOperandList = iops; 1898263508Sdim let AsmString = !strconcat(opc, ".", dt, "\t", asm); 1899263508Sdim let Pattern = pattern; 1900263508Sdim list<Predicate> Predicates = [HasNEON]; 1901263508Sdim let DecoderNamespace = "NEON"; 1902263508Sdim 1903263508Sdim let Inst{31-28} = 0b1111; 1904263508Sdim} 1905263508Sdim 1906198090Srdivackyclass NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 1907198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1908199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 1909205407Srdivacky : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm, 1910205407Srdivacky cstr, pattern> { 1911198090Srdivacky let Inst{31-24} = 0b11110100; 1912212904Sdim let Inst{23} = op23; 1913198396Srdivacky let Inst{21-20} = op21_20; 1914212904Sdim let Inst{11-8} = op11_8; 1915212904Sdim let Inst{7-4} = op7_4; 1916218893Sdim 1917218893Sdim let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; 1918226633Sdim let DecoderNamespace = "NEONLoadStore"; 1919218893Sdim 1920218893Sdim bits<5> Vd; 1921218893Sdim bits<6> Rn; 1922218893Sdim bits<4> Rm; 1923218893Sdim 1924218893Sdim let Inst{22} = Vd{4}; 1925218893Sdim let Inst{15-12} = Vd{3-0}; 1926218893Sdim let Inst{19-16} = Rn{3-0}; 1927218893Sdim let Inst{3-0} = Rm{3-0}; 1928198090Srdivacky} 1929198090Srdivacky 1930218893Sdimclass NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 1931218893Sdim dag oops, dag iops, InstrItinClass itin, 1932218893Sdim string opc, string dt, string asm, string cstr, list<dag> pattern> 1933218893Sdim : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc, 1934218893Sdim dt, asm, cstr, pattern> { 1935218893Sdim bits<3> lane; 1936218893Sdim} 1937218893Sdim 1938212904Sdimclass PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr> 1939224145Sdim : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 1940212904Sdim itin> { 1941212904Sdim let OutOperandList = oops; 1942212904Sdim let InOperandList = !con(iops, (ins pred:$p)); 1943212904Sdim list<Predicate> Predicates = [HasNEON]; 1944212904Sdim} 1945212904Sdim 1946218893Sdimclass PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr, 1947218893Sdim list<dag> pattern> 1948224145Sdim : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 1949218893Sdim itin> { 1950218893Sdim let OutOperandList = oops; 1951218893Sdim let InOperandList = !con(iops, (ins pred:$p)); 1952218893Sdim let Pattern = pattern; 1953218893Sdim list<Predicate> Predicates = [HasNEON]; 1954218893Sdim} 1955218893Sdim 1956206083Srdivackyclass NDataI<dag oops, dag iops, Format f, InstrItinClass itin, 1957199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 1958206083Srdivacky : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr, 1959206083Srdivacky pattern> { 1960194710Sed let Inst{31-25} = 0b1111001; 1961218893Sdim let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 1962226633Sdim let DecoderNamespace = "NEONData"; 1963194710Sed} 1964194710Sed 1965206083Srdivackyclass NDataXI<dag oops, dag iops, Format f, InstrItinClass itin, 1966206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1967206083Srdivacky : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm, 1968206083Srdivacky cstr, pattern> { 1969199989Srdivacky let Inst{31-25} = 0b1111001; 1970218893Sdim let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 1971226633Sdim let DecoderNamespace = "NEONData"; 1972199989Srdivacky} 1973199989Srdivacky 1974194710Sed// NEON "one register and a modified immediate" format. 1975194710Sedclass N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 1976194710Sed bit op5, bit op4, 1977198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1978206083Srdivacky string opc, string dt, string asm, string cstr, 1979206083Srdivacky list<dag> pattern> 1980206083Srdivacky : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> { 1981212904Sdim let Inst{23} = op23; 1982194710Sed let Inst{21-19} = op21_19; 1983212904Sdim let Inst{11-8} = op11_8; 1984212904Sdim let Inst{7} = op7; 1985212904Sdim let Inst{6} = op6; 1986212904Sdim let Inst{5} = op5; 1987212904Sdim let Inst{4} = op4; 1988218893Sdim 1989218893Sdim // Instruction operands. 1990218893Sdim bits<5> Vd; 1991218893Sdim bits<13> SIMM; 1992218893Sdim 1993218893Sdim let Inst{15-12} = Vd{3-0}; 1994218893Sdim let Inst{22} = Vd{4}; 1995218893Sdim let Inst{24} = SIMM{7}; 1996218893Sdim let Inst{18-16} = SIMM{6-4}; 1997218893Sdim let Inst{3-0} = SIMM{3-0}; 1998226633Sdim let DecoderMethod = "DecodeNEONModImmInstruction"; 1999194710Sed} 2000194710Sed 2001194710Sed// NEON 2 vector register format. 2002194710Sedclass N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2003194710Sed bits<5> op11_7, bit op6, bit op4, 2004198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2005199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 2006206083Srdivacky : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> { 2007194710Sed let Inst{24-23} = op24_23; 2008194710Sed let Inst{21-20} = op21_20; 2009194710Sed let Inst{19-18} = op19_18; 2010194710Sed let Inst{17-16} = op17_16; 2011212904Sdim let Inst{11-7} = op11_7; 2012212904Sdim let Inst{6} = op6; 2013212904Sdim let Inst{4} = op4; 2014218893Sdim 2015218893Sdim // Instruction operands. 2016218893Sdim bits<5> Vd; 2017218893Sdim bits<5> Vm; 2018218893Sdim 2019218893Sdim let Inst{15-12} = Vd{3-0}; 2020218893Sdim let Inst{22} = Vd{4}; 2021218893Sdim let Inst{3-0} = Vm{3-0}; 2022218893Sdim let Inst{5} = Vm{4}; 2023194710Sed} 2024194710Sed 2025263508Sdim// Same as N2V but not predicated. 2026263508Sdimclass N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 2027263508Sdim dag oops, dag iops, InstrItinClass itin, string OpcodeStr, 2028263508Sdim string Dt, ValueType ResTy, ValueType OpTy, list<dag> pattern> 2029263508Sdim : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin, 2030263508Sdim OpcodeStr, Dt, "$Vd, $Vm", "", pattern> { 2031263508Sdim bits<5> Vd; 2032263508Sdim bits<5> Vm; 2033263508Sdim 2034263508Sdim // Encode instruction operands 2035263508Sdim let Inst{22} = Vd{4}; 2036263508Sdim let Inst{15-12} = Vd{3-0}; 2037263508Sdim let Inst{5} = Vm{4}; 2038263508Sdim let Inst{3-0} = Vm{3-0}; 2039263508Sdim 2040263508Sdim // Encode constant bits 2041263508Sdim let Inst{27-23} = 0b00111; 2042263508Sdim let Inst{21-20} = 0b11; 2043263508Sdim let Inst{19-18} = op19_18; 2044263508Sdim let Inst{17-16} = op17_16; 2045263508Sdim let Inst{11} = 0; 2046263508Sdim let Inst{10-8} = op10_8; 2047263508Sdim let Inst{7} = op7; 2048263508Sdim let Inst{6} = op6; 2049263508Sdim let Inst{4} = 0; 2050263508Sdim 2051263508Sdim let DecoderNamespace = "NEON"; 2052263508Sdim} 2053263508Sdim 2054199989Srdivacky// Same as N2V except it doesn't have a datatype suffix. 2055199989Srdivackyclass N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2056206083Srdivacky bits<5> op11_7, bit op6, bit op4, 2057206083Srdivacky dag oops, dag iops, InstrItinClass itin, 2058206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 2059206083Srdivacky : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> { 2060198396Srdivacky let Inst{24-23} = op24_23; 2061198396Srdivacky let Inst{21-20} = op21_20; 2062199989Srdivacky let Inst{19-18} = op19_18; 2063199989Srdivacky let Inst{17-16} = op17_16; 2064212904Sdim let Inst{11-7} = op11_7; 2065212904Sdim let Inst{6} = op6; 2066212904Sdim let Inst{4} = op4; 2067218893Sdim 2068218893Sdim // Instruction operands. 2069218893Sdim bits<5> Vd; 2070218893Sdim bits<5> Vm; 2071218893Sdim 2072218893Sdim let Inst{15-12} = Vd{3-0}; 2073218893Sdim let Inst{22} = Vd{4}; 2074218893Sdim let Inst{3-0} = Vm{3-0}; 2075218893Sdim let Inst{5} = Vm{4}; 2076198396Srdivacky} 2077198396Srdivacky 2078194710Sed// NEON 2 vector register with immediate. 2079198396Srdivackyclass N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2080206083Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2081199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 2082206083Srdivacky : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2083212904Sdim let Inst{24} = op24; 2084212904Sdim let Inst{23} = op23; 2085194710Sed let Inst{11-8} = op11_8; 2086212904Sdim let Inst{7} = op7; 2087212904Sdim let Inst{6} = op6; 2088212904Sdim let Inst{4} = op4; 2089218893Sdim 2090218893Sdim // Instruction operands. 2091218893Sdim bits<5> Vd; 2092218893Sdim bits<5> Vm; 2093218893Sdim bits<6> SIMM; 2094218893Sdim 2095218893Sdim let Inst{15-12} = Vd{3-0}; 2096218893Sdim let Inst{22} = Vd{4}; 2097218893Sdim let Inst{3-0} = Vm{3-0}; 2098218893Sdim let Inst{5} = Vm{4}; 2099218893Sdim let Inst{21-16} = SIMM{5-0}; 2100194710Sed} 2101194710Sed 2102194710Sed// NEON 3 vector register format. 2103221345Sdim 2104223017Sdimclass N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2105223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2106223017Sdim string opc, string dt, string asm, string cstr, 2107223017Sdim list<dag> pattern> 2108206083Srdivacky : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2109212904Sdim let Inst{24} = op24; 2110212904Sdim let Inst{23} = op23; 2111194710Sed let Inst{21-20} = op21_20; 2112212904Sdim let Inst{11-8} = op11_8; 2113212904Sdim let Inst{6} = op6; 2114212904Sdim let Inst{4} = op4; 2115221345Sdim} 2116218893Sdim 2117221345Sdimclass N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 2118221345Sdim dag oops, dag iops, Format f, InstrItinClass itin, 2119221345Sdim string opc, string dt, string asm, string cstr, list<dag> pattern> 2120221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2121221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2122218893Sdim // Instruction operands. 2123218893Sdim bits<5> Vd; 2124218893Sdim bits<5> Vn; 2125218893Sdim bits<5> Vm; 2126218893Sdim 2127218893Sdim let Inst{15-12} = Vd{3-0}; 2128218893Sdim let Inst{22} = Vd{4}; 2129218893Sdim let Inst{19-16} = Vn{3-0}; 2130218893Sdim let Inst{7} = Vn{4}; 2131218893Sdim let Inst{3-0} = Vm{3-0}; 2132218893Sdim let Inst{5} = Vm{4}; 2133194710Sed} 2134194710Sed 2135263508Sdimclass N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2136263508Sdim bit op4, dag oops, dag iops,Format f, InstrItinClass itin, 2137263508Sdim string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 2138263508Sdim SDPatternOperator IntOp, bit Commutable, list<dag> pattern> 2139263508Sdim : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr, 2140263508Sdim Dt, "$Vd, $Vn, $Vm", "", pattern> { 2141263508Sdim bits<5> Vd; 2142263508Sdim bits<5> Vn; 2143263508Sdim bits<5> Vm; 2144263508Sdim 2145263508Sdim // Encode instruction operands 2146263508Sdim let Inst{22} = Vd{4}; 2147263508Sdim let Inst{15-12} = Vd{3-0}; 2148263508Sdim let Inst{19-16} = Vn{3-0}; 2149263508Sdim let Inst{7} = Vn{4}; 2150263508Sdim let Inst{5} = Vm{4}; 2151263508Sdim let Inst{3-0} = Vm{3-0}; 2152263508Sdim 2153263508Sdim // Encode constant bits 2154263508Sdim let Inst{27-23} = op27_23; 2155263508Sdim let Inst{21-20} = op21_20; 2156263508Sdim let Inst{11-8} = op11_8; 2157263508Sdim let Inst{6} = op6; 2158263508Sdim let Inst{4} = op4; 2159263508Sdim} 2160263508Sdim 2161223017Sdimclass N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2162223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2163223017Sdim string opc, string dt, string asm, string cstr, 2164223017Sdim list<dag> pattern> 2165221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2166221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2167221345Sdim 2168221345Sdim // Instruction operands. 2169221345Sdim bits<5> Vd; 2170221345Sdim bits<5> Vn; 2171221345Sdim bits<5> Vm; 2172221345Sdim bit lane; 2173221345Sdim 2174221345Sdim let Inst{15-12} = Vd{3-0}; 2175221345Sdim let Inst{22} = Vd{4}; 2176221345Sdim let Inst{19-16} = Vn{3-0}; 2177221345Sdim let Inst{7} = Vn{4}; 2178221345Sdim let Inst{3-0} = Vm{3-0}; 2179221345Sdim let Inst{5} = lane; 2180221345Sdim} 2181221345Sdim 2182223017Sdimclass N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2183223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2184223017Sdim string opc, string dt, string asm, string cstr, 2185223017Sdim list<dag> pattern> 2186221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2187221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2188221345Sdim 2189221345Sdim // Instruction operands. 2190221345Sdim bits<5> Vd; 2191221345Sdim bits<5> Vn; 2192221345Sdim bits<5> Vm; 2193221345Sdim bits<2> lane; 2194221345Sdim 2195221345Sdim let Inst{15-12} = Vd{3-0}; 2196221345Sdim let Inst{22} = Vd{4}; 2197221345Sdim let Inst{19-16} = Vn{3-0}; 2198221345Sdim let Inst{7} = Vn{4}; 2199221345Sdim let Inst{2-0} = Vm{2-0}; 2200221345Sdim let Inst{5} = lane{1}; 2201221345Sdim let Inst{3} = lane{0}; 2202221345Sdim} 2203221345Sdim 2204206083Srdivacky// Same as N3V except it doesn't have a data type suffix. 2205206083Srdivackyclass N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2206206083Srdivacky bit op4, 2207206083Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2208206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 2209206083Srdivacky : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> { 2210212904Sdim let Inst{24} = op24; 2211212904Sdim let Inst{23} = op23; 2212198396Srdivacky let Inst{21-20} = op21_20; 2213212904Sdim let Inst{11-8} = op11_8; 2214212904Sdim let Inst{6} = op6; 2215212904Sdim let Inst{4} = op4; 2216218893Sdim 2217218893Sdim // Instruction operands. 2218218893Sdim bits<5> Vd; 2219218893Sdim bits<5> Vn; 2220218893Sdim bits<5> Vm; 2221218893Sdim 2222218893Sdim let Inst{15-12} = Vd{3-0}; 2223218893Sdim let Inst{22} = Vd{4}; 2224218893Sdim let Inst{19-16} = Vn{3-0}; 2225218893Sdim let Inst{7} = Vn{4}; 2226218893Sdim let Inst{3-0} = Vm{3-0}; 2227218893Sdim let Inst{5} = Vm{4}; 2228198396Srdivacky} 2229198396Srdivacky 2230194710Sed// NEON VMOVs between scalar and core registers. 2231194710Sedclass NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2232198090Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2233199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2234224145Sdim : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain, 2235206083Srdivacky "", itin> { 2236194710Sed let Inst{27-20} = opcod1; 2237212904Sdim let Inst{11-8} = opcod2; 2238212904Sdim let Inst{6-5} = opcod3; 2239212904Sdim let Inst{4} = 1; 2240221345Sdim // A8.6.303, A8.6.328, A8.6.329 2241221345Sdim let Inst{3-0} = 0b0000; 2242199989Srdivacky 2243199989Srdivacky let OutOperandList = oops; 2244205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 2245218893Sdim let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2246199989Srdivacky let Pattern = pattern; 2247194710Sed list<Predicate> Predicates = [HasNEON]; 2248218893Sdim 2249218893Sdim let PostEncoderMethod = "NEONThumb2DupPostEncoder"; 2250226633Sdim let DecoderNamespace = "NEONDup"; 2251218893Sdim 2252218893Sdim bits<5> V; 2253218893Sdim bits<4> R; 2254218893Sdim bits<4> p; 2255218893Sdim bits<4> lane; 2256218893Sdim 2257218893Sdim let Inst{31-28} = p{3-0}; 2258218893Sdim let Inst{7} = V{4}; 2259218893Sdim let Inst{19-16} = V{3-0}; 2260218893Sdim let Inst{15-12} = R{3-0}; 2261194710Sed} 2262194710Sedclass NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2263198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2264199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2265210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin, 2266199989Srdivacky opc, dt, asm, pattern>; 2267194710Sedclass NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2268198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2269199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2270210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin, 2271199989Srdivacky opc, dt, asm, pattern>; 2272194710Sedclass NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2273198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2274199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2275210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin, 2276199989Srdivacky opc, dt, asm, pattern>; 2277198090Srdivacky 2278206083Srdivacky// Vector Duplicate Lane (from scalar to all elements) 2279206083Srdivackyclass NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops, 2280206083Srdivacky InstrItinClass itin, string opc, string dt, string asm, 2281206083Srdivacky list<dag> pattern> 2282206083Srdivacky : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> { 2283206083Srdivacky let Inst{24-23} = 0b11; 2284206083Srdivacky let Inst{21-20} = 0b11; 2285206083Srdivacky let Inst{19-16} = op19_16; 2286212904Sdim let Inst{11-7} = 0b11000; 2287212904Sdim let Inst{6} = op6; 2288212904Sdim let Inst{4} = 0; 2289218893Sdim 2290218893Sdim bits<5> Vd; 2291218893Sdim bits<5> Vm; 2292218893Sdim 2293218893Sdim let Inst{22} = Vd{4}; 2294218893Sdim let Inst{15-12} = Vd{3-0}; 2295218893Sdim let Inst{5} = Vm{4}; 2296218893Sdim let Inst{3-0} = Vm{3-0}; 2297206083Srdivacky} 2298206083Srdivacky 2299198090Srdivacky// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 2300198090Srdivacky// for single-precision FP. 2301198090Srdivackyclass NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 2302198090Srdivacky list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 2303198090Srdivacky} 2304234353Sdim 2305234353Sdim// VFP/NEON Instruction aliases for type suffices. 2306234353Sdimclass VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result> : 2307234353Sdim InstAlias<!strconcat(opc, dt, "\t", asm), Result>, Requires<[HasVFP2]>; 2308234353Sdim 2309234353Sdimmulticlass VFPDTAnyInstAlias<string opc, string asm, dag Result> { 2310234353Sdim def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; 2311234353Sdim def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; 2312234353Sdim def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; 2313234353Sdim def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; 2314234353Sdim} 2315234353Sdim 2316234353Sdimmulticlass NEONDTAnyInstAlias<string opc, string asm, dag Result> { 2317234353Sdim let Predicates = [HasNEON] in { 2318234353Sdim def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; 2319234353Sdim def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; 2320234353Sdim def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; 2321234353Sdim def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; 2322234353Sdim} 2323234353Sdim} 2324234353Sdim 2325234353Sdim// The same alias classes using AsmPseudo instead, for the more complex 2326234353Sdim// stuff in NEON that InstAlias can't quite handle. 2327234353Sdim// Note that we can't use anonymous defm references here like we can 2328234353Sdim// above, as we care about the ultimate instruction enum names generated, unlike 2329234353Sdim// for instalias defs. 2330234353Sdimclass NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> : 2331234353Sdim AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>; 2332234353Sdim 2333234353Sdim// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM. 2334234353Sdimdef : TokenAlias<".s8", ".i8">; 2335234353Sdimdef : TokenAlias<".u8", ".i8">; 2336234353Sdimdef : TokenAlias<".s16", ".i16">; 2337234353Sdimdef : TokenAlias<".u16", ".i16">; 2338234353Sdimdef : TokenAlias<".s32", ".i32">; 2339234353Sdimdef : TokenAlias<".u32", ".i32">; 2340234353Sdimdef : TokenAlias<".s64", ".i64">; 2341234353Sdimdef : TokenAlias<".u64", ".i64">; 2342234353Sdim 2343234353Sdimdef : TokenAlias<".i8", ".8">; 2344234353Sdimdef : TokenAlias<".i16", ".16">; 2345234353Sdimdef : TokenAlias<".i32", ".32">; 2346234353Sdimdef : TokenAlias<".i64", ".64">; 2347234353Sdim 2348234353Sdimdef : TokenAlias<".p8", ".8">; 2349234353Sdimdef : TokenAlias<".p16", ".16">; 2350234353Sdim 2351234353Sdimdef : TokenAlias<".f32", ".32">; 2352234353Sdimdef : TokenAlias<".f64", ".64">; 2353234353Sdimdef : TokenAlias<".f", ".f32">; 2354234353Sdimdef : TokenAlias<".d", ".f64">; 2355