ARMInstrFormats.td revision 276479
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 158261991Sdim// Selectable predicate operand for CMOV instructions. We can't use a normal 159261991Sdim// predicate because the default values interfere with instruction selection. In 160261991Sdim// all other respects it is identical though: pseudo-instruction expansion 161261991Sdim// relies on the MachineOperands being compatible. 162261991Sdimdef cmovpred : Operand<i32>, PredicateOp, 163261991Sdim ComplexPattern<i32, 2, "SelectCMOVPred"> { 164261991Sdim let MIOperandInfo = (ops i32imm, i32imm); 165261991Sdim let PrintMethod = "printPredicateOperand"; 166261991Sdim} 167261991Sdim 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"; } 215276479Sdimdef shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> { 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"; } 221276479Sdimdef shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> { 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"; } 227276479Sdimdef shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> { 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"; } 233276479Sdimdef shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> { 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]>; 250261991Sdimclass VFP2DPInstAlias<string Asm, dag Result, bit Emit = 0b1> 251261991Sdim : 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. 332276479Sdimclass AsmPseudoInst<string asm, dag iops, dag oops = (outs)> 333234353Sdim : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, 334234353Sdim "", NoItinerary> { 335276479Sdim let OutOperandList = oops; 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 343276479Sdimclass ARMAsmPseudo<string asm, dag iops, dag oops = (outs)> 344276479Sdim : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>; 345276479Sdimclass tAsmPseudo<string asm, dag iops, dag oops = (outs)> 346276479Sdim : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>; 347276479Sdimclass t2AsmPseudo<string asm, dag iops, dag oops = (outs)> 348276479Sdim : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>; 349276479Sdimclass VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)> 350276479Sdim : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>; 351276479Sdimclass NEONAsmPseudo<string asm, dag iops, dag oops = (outs)> 352276479Sdim : AsmPseudoInst<asm, iops, oops>, 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>; 480276479Sdimclass AXIM<dag oops, dag iops, AddrMode am, Format f, InstrItinClass itin, 481276479Sdim string asm, list<dag> pattern> 482276479Sdim : XI<oops, iops, am, 4, IndexModeNone, f, itin, 483276479Sdim asm, "", pattern>; 484200581Srdivackyclass AInoP<dag oops, dag iops, Format f, InstrItinClass itin, 485206083Srdivacky string opc, string asm, list<dag> pattern> 486224145Sdim : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 487206083Srdivacky opc, asm, "", pattern>; 488193323Sed 489193323Sed// Ctrl flow instructions 490198090Srdivackyclass ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 491198090Srdivacky string opc, string asm, list<dag> pattern> 492224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 493198090Srdivacky opc, asm, "", pattern> { 494193323Sed let Inst{27-24} = opcod; 495193323Sed} 496198090Srdivackyclass ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin, 497198090Srdivacky string asm, list<dag> pattern> 498224145Sdim : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin, 499198090Srdivacky asm, "", pattern> { 500193323Sed let Inst{27-24} = opcod; 501193323Sed} 502193323Sed 503193323Sed// BR_JT instructions 504198090Srdivackyclass JTI<dag oops, dag iops, InstrItinClass itin, 505198090Srdivacky string asm, list<dag> pattern> 506224145Sdim : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin, 507193323Sed asm, "", pattern>; 508193323Sed 509261991Sdimclass AIldr_ex_or_acq<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 510200581Srdivacky string opc, string asm, list<dag> pattern> 511224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 512200581Srdivacky opc, asm, "", pattern> { 513218893Sdim bits<4> Rt; 514226633Sdim bits<4> addr; 515200581Srdivacky let Inst{27-23} = 0b00011; 516200581Srdivacky let Inst{22-21} = opcod; 517212904Sdim let Inst{20} = 1; 518226633Sdim let Inst{19-16} = addr; 519218893Sdim let Inst{15-12} = Rt; 520261991Sdim let Inst{11-10} = 0b11; 521261991Sdim let Inst{9-8} = opcod2; 522261991Sdim let Inst{7-0} = 0b10011111; 523200581Srdivacky} 524261991Sdimclass AIstr_ex_or_rel<bits<2> opcod, bits<2> opcod2, dag oops, dag iops, InstrItinClass itin, 525200581Srdivacky string opc, string asm, list<dag> pattern> 526224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin, 527200581Srdivacky opc, asm, "", pattern> { 528218893Sdim bits<4> Rt; 529221345Sdim bits<4> addr; 530200581Srdivacky let Inst{27-23} = 0b00011; 531200581Srdivacky let Inst{22-21} = opcod; 532212904Sdim let Inst{20} = 0; 533221345Sdim let Inst{19-16} = addr; 534261991Sdim let Inst{11-10} = 0b11; 535261991Sdim let Inst{9-8} = opcod2; 536261991Sdim let Inst{7-4} = 0b1001; 537218893Sdim let Inst{3-0} = Rt; 538200581Srdivacky} 539261991Sdim// Atomic load/store instructions 540261991Sdimclass AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 541261991Sdim string opc, string asm, list<dag> pattern> 542261991Sdim : AIldr_ex_or_acq<opcod, 0b11, oops, iops, itin, opc, asm, pattern>; 543261991Sdim 544261991Sdimclass AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 545261991Sdim string opc, string asm, list<dag> pattern> 546261991Sdim : AIstr_ex_or_rel<opcod, 0b11, oops, iops, itin, opc, asm, pattern> { 547261991Sdim bits<4> Rd; 548261991Sdim let Inst{15-12} = Rd; 549261991Sdim} 550261991Sdim 551261991Sdim// Exclusive load/store instructions 552261991Sdim 553261991Sdimclass AIldaex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 554261991Sdim string opc, string asm, list<dag> pattern> 555261991Sdim : AIldr_ex_or_acq<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 556261991Sdim Requires<[IsARM, HasV8]>; 557261991Sdim 558261991Sdimclass AIstlex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 559261991Sdim string opc, string asm, list<dag> pattern> 560261991Sdim : AIstr_ex_or_rel<opcod, 0b10, oops, iops, itin, opc, asm, pattern>, 561261991Sdim Requires<[IsARM, HasV8]> { 562261991Sdim bits<4> Rd; 563261991Sdim let Inst{15-12} = Rd; 564261991Sdim} 565261991Sdim 566218893Sdimclass AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern> 567226633Sdim : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> { 568218893Sdim bits<4> Rt; 569218893Sdim bits<4> Rt2; 570226633Sdim bits<4> addr; 571218893Sdim let Inst{27-23} = 0b00010; 572218893Sdim let Inst{22} = b; 573218893Sdim let Inst{21-20} = 0b00; 574226633Sdim let Inst{19-16} = addr; 575218893Sdim let Inst{15-12} = Rt; 576218893Sdim let Inst{11-4} = 0b00001001; 577218893Sdim let Inst{3-0} = Rt2; 578234353Sdim 579234982Sdim let Unpredictable{11-8} = 0b1111; 580234353Sdim let DecoderMethod = "DecodeSwap"; 581218893Sdim} 582261991Sdim// Acquire/Release load/store instructions 583261991Sdimclass AIldracq<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 584261991Sdim string opc, string asm, list<dag> pattern> 585261991Sdim : AIldr_ex_or_acq<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 586261991Sdim Requires<[IsARM, HasV8]>; 587200581Srdivacky 588261991Sdimclass AIstrrel<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 589261991Sdim string opc, string asm, list<dag> pattern> 590261991Sdim : AIstr_ex_or_rel<opcod, 0b00, oops, iops, itin, opc, asm, pattern>, 591261991Sdim Requires<[IsARM, HasV8]> { 592261991Sdim let Inst{15-12} = 0b1111; 593261991Sdim} 594261991Sdim 595193323Sed// addrmode1 instructions 596198090Srdivackyclass AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 597198090Srdivacky string opc, string asm, list<dag> pattern> 598224145Sdim : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 599198090Srdivacky opc, asm, "", pattern> { 600193323Sed let Inst{24-21} = opcod; 601212904Sdim let Inst{27-26} = 0b00; 602193323Sed} 603198090Srdivackyclass AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 604198090Srdivacky string opc, string asm, list<dag> pattern> 605224145Sdim : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 606198090Srdivacky opc, asm, "", pattern> { 607193323Sed let Inst{24-21} = opcod; 608212904Sdim let Inst{27-26} = 0b00; 609193323Sed} 610198090Srdivackyclass AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin, 611198090Srdivacky string asm, list<dag> pattern> 612224145Sdim : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin, 613198090Srdivacky asm, "", pattern> { 614193323Sed let Inst{24-21} = opcod; 615212904Sdim let Inst{27-26} = 0b00; 616193323Sed} 617193323Sed 618193323Sed// loads 619193323Sed 620218893Sdim// LDR/LDRB/STR/STRB/... 621218893Sdimclass AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am, 622218893Sdim Format f, InstrItinClass itin, string opc, string asm, 623218893Sdim list<dag> pattern> 624224145Sdim : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm, 625218893Sdim "", pattern> { 626218893Sdim let Inst{27-25} = op; 627218893Sdim let Inst{24} = 1; // 24 == P 628218893Sdim // 23 == U 629218893Sdim let Inst{22} = isByte; 630218893Sdim let Inst{21} = 0; // 21 == W 631218893Sdim let Inst{20} = isLd; 632193323Sed} 633218893Sdim// Indexed load/stores 634218893Sdimclass AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops, 635218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 636218893Sdim string asm, string cstr, list<dag> pattern> 637224145Sdim : I<oops, iops, AddrMode2, 4, im, f, itin, 638198090Srdivacky opc, asm, cstr, pattern> { 639218893Sdim bits<4> Rt; 640212904Sdim let Inst{27-26} = 0b01; 641218893Sdim let Inst{24} = isPre; // P bit 642218893Sdim let Inst{22} = isByte; // B bit 643218893Sdim let Inst{21} = isPre; // W bit 644218893Sdim let Inst{20} = isLd; // L bit 645218893Sdim let Inst{15-12} = Rt; 646193323Sed} 647226633Sdimclass AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops, 648218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 649218893Sdim string asm, string cstr, list<dag> pattern> 650218893Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 651218893Sdim pattern> { 652218893Sdim // AM2 store w/ two operands: (GPR, am2offset) 653218893Sdim // {12} isAdd 654218893Sdim // {11-0} imm12/Rm 655218893Sdim bits<14> offset; 656218893Sdim bits<4> Rn; 657226633Sdim let Inst{25} = 1; 658218893Sdim let Inst{23} = offset{12}; 659218893Sdim let Inst{19-16} = Rn; 660226633Sdim let Inst{11-5} = offset{11-5}; 661226633Sdim let Inst{4} = 0; 662226633Sdim let Inst{3-0} = offset{3-0}; 663226633Sdim} 664226633Sdim 665226633Sdimclass AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops, 666226633Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 667226633Sdim string asm, string cstr, list<dag> pattern> 668226633Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 669226633Sdim pattern> { 670226633Sdim // AM2 store w/ two operands: (GPR, am2offset) 671226633Sdim // {12} isAdd 672226633Sdim // {11-0} imm12/Rm 673226633Sdim bits<14> offset; 674226633Sdim bits<4> Rn; 675226633Sdim let Inst{25} = 0; 676226633Sdim let Inst{23} = offset{12}; 677226633Sdim let Inst{19-16} = Rn; 678218893Sdim let Inst{11-0} = offset{11-0}; 679193323Sed} 680226633Sdim 681226633Sdim 682221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for STR, STRB 683221345Sdim// but for now use this class for STRT and STRBT. 684221345Sdimclass AI2stridxT<bit isByte, bit isPre, dag oops, dag iops, 685221345Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 686221345Sdim string asm, string cstr, list<dag> pattern> 687221345Sdim : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, 688221345Sdim pattern> { 689221345Sdim // AM2 store w/ two operands: (GPR, am2offset) 690221345Sdim // {17-14} Rn 691221345Sdim // {13} 1 == Rm, 0 == imm12 692221345Sdim // {12} isAdd 693221345Sdim // {11-0} imm12/Rm 694221345Sdim bits<18> addr; 695221345Sdim let Inst{25} = addr{13}; 696221345Sdim let Inst{23} = addr{12}; 697221345Sdim let Inst{19-16} = addr{17-14}; 698221345Sdim let Inst{11-0} = addr{11-0}; 699221345Sdim} 700193323Sed 701193323Sed// addrmode3 instructions 702218893Sdimclass AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f, 703218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 704224145Sdim : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 705198090Srdivacky opc, asm, "", pattern> { 706218893Sdim bits<14> addr; 707218893Sdim bits<4> Rt; 708198090Srdivacky let Inst{27-25} = 0b000; 709218893Sdim let Inst{24} = 1; // P bit 710218893Sdim let Inst{23} = addr{8}; // U bit 711218893Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 712218893Sdim let Inst{21} = 0; // W bit 713218893Sdim let Inst{20} = op20; // L bit 714218893Sdim let Inst{19-16} = addr{12-9}; // Rn 715218893Sdim let Inst{15-12} = Rt; // Rt 716218893Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 717218893Sdim let Inst{7-4} = op; 718218893Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 719226633Sdim 720226633Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 721193323Sed} 722218893Sdim 723226633Sdimclass AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops, 724218893Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 725218893Sdim string asm, string cstr, list<dag> pattern> 726224145Sdim : I<oops, iops, AddrMode3, 4, im, f, itin, 727218893Sdim opc, asm, cstr, pattern> { 728218893Sdim bits<4> Rt; 729198090Srdivacky let Inst{27-25} = 0b000; 730218893Sdim let Inst{24} = isPre; // P bit 731218893Sdim let Inst{21} = isPre; // W bit 732218893Sdim let Inst{20} = op20; // L bit 733218893Sdim let Inst{15-12} = Rt; // Rt 734218893Sdim let Inst{7-4} = op; 735193323Sed} 736221345Sdim 737221345Sdim// FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB 738221345Sdim// but for now use this class for LDRSBT, LDRHT, LDSHT. 739226633Sdimclass AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops, 740221345Sdim IndexMode im, Format f, InstrItinClass itin, string opc, 741221345Sdim string asm, string cstr, list<dag> pattern> 742226633Sdim : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> { 743221345Sdim // {13} 1 == imm8, 0 == Rm 744221345Sdim // {12-9} Rn 745221345Sdim // {8} isAdd 746221345Sdim // {7-4} imm7_4/zero 747221345Sdim // {3-0} imm3_0/Rm 748226633Sdim bits<4> addr; 749221345Sdim bits<4> Rt; 750221345Sdim let Inst{27-25} = 0b000; 751226633Sdim let Inst{24} = 0; // P bit 752226633Sdim let Inst{21} = 1; 753226633Sdim let Inst{20} = isLoad; // L bit 754226633Sdim let Inst{19-16} = addr; // Rn 755221345Sdim let Inst{15-12} = Rt; // Rt 756221345Sdim let Inst{7-4} = op; 757221345Sdim} 758221345Sdim 759193323Sed// stores 760218893Sdimclass AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin, 761198090Srdivacky string opc, string asm, list<dag> pattern> 762224145Sdim : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin, 763198090Srdivacky opc, asm, "", pattern> { 764218893Sdim bits<14> addr; 765218893Sdim bits<4> Rt; 766198090Srdivacky let Inst{27-25} = 0b000; 767218893Sdim let Inst{24} = 1; // P bit 768218893Sdim let Inst{23} = addr{8}; // U bit 769218893Sdim let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 770218893Sdim let Inst{21} = 0; // W bit 771218893Sdim let Inst{20} = 0; // L bit 772218893Sdim let Inst{19-16} = addr{12-9}; // Rn 773218893Sdim let Inst{15-12} = Rt; // Rt 774218893Sdim let Inst{11-8} = addr{7-4}; // imm7_4/zero 775218893Sdim let Inst{7-4} = op; 776218893Sdim let Inst{3-0} = addr{3-0}; // imm3_0/Rm 777226633Sdim let DecoderMethod = "DecodeAddrMode3Instruction"; 778193323Sed} 779193323Sed 780193323Sed// addrmode4 instructions 781218893Sdimclass AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, 782218893Sdim string asm, string cstr, list<dag> pattern> 783224145Sdim : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> { 784218893Sdim bits<4> p; 785218893Sdim bits<16> regs; 786218893Sdim bits<4> Rn; 787218893Sdim let Inst{31-28} = p; 788193323Sed let Inst{27-25} = 0b100; 789193323Sed let Inst{22} = 0; // S bit 790218893Sdim let Inst{19-16} = Rn; 791218893Sdim let Inst{15-0} = regs; 792193323Sed} 793193323Sed 794193323Sed// Unsigned multiply, multiply-accumulate instructions. 795198090Srdivackyclass AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 796198090Srdivacky string opc, string asm, list<dag> pattern> 797224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 798198090Srdivacky opc, asm, "", pattern> { 799193323Sed let Inst{7-4} = 0b1001; 800193323Sed let Inst{20} = 0; // S bit 801193323Sed let Inst{27-21} = opcod; 802193323Sed} 803198090Srdivackyclass AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 804198090Srdivacky string opc, string asm, list<dag> pattern> 805224145Sdim : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 806198090Srdivacky opc, asm, "", pattern> { 807193323Sed let Inst{7-4} = 0b1001; 808193323Sed let Inst{27-21} = opcod; 809193323Sed} 810193323Sed 811193323Sed// Most significant word multiply 812218893Sdimclass AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 813218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 814224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 815198090Srdivacky opc, asm, "", pattern> { 816218893Sdim bits<4> Rd; 817218893Sdim bits<4> Rn; 818218893Sdim bits<4> Rm; 819218893Sdim let Inst{7-4} = opc7_4; 820193323Sed let Inst{20} = 1; 821193323Sed let Inst{27-21} = opcod; 822218893Sdim let Inst{19-16} = Rd; 823218893Sdim let Inst{11-8} = Rm; 824218893Sdim let Inst{3-0} = Rn; 825193323Sed} 826218893Sdim// MSW multiple w/ Ra operand 827218893Sdimclass AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops, 828218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 829218893Sdim : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> { 830218893Sdim bits<4> Ra; 831218893Sdim let Inst{15-12} = Ra; 832218893Sdim} 833193323Sed 834193323Sed// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y> 835218893Sdimclass AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 836218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 837224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin, 838198090Srdivacky opc, asm, "", pattern> { 839218893Sdim bits<4> Rn; 840218893Sdim bits<4> Rm; 841193323Sed let Inst{4} = 0; 842193323Sed let Inst{7} = 1; 843193323Sed let Inst{20} = 0; 844193323Sed let Inst{27-21} = opcod; 845218893Sdim let Inst{6-5} = bit6_5; 846218893Sdim let Inst{11-8} = Rm; 847218893Sdim let Inst{3-0} = Rn; 848193323Sed} 849218893Sdimclass AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 850218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 851218893Sdim : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 852218893Sdim bits<4> Rd; 853218893Sdim let Inst{19-16} = Rd; 854218893Sdim} 855193323Sed 856218893Sdim// AMulxyI with Ra operand 857218893Sdimclass AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 858218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 859218893Sdim : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 860218893Sdim bits<4> Ra; 861218893Sdim let Inst{15-12} = Ra; 862218893Sdim} 863218893Sdim// SMLAL* 864218893Sdimclass AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops, 865218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 866218893Sdim : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> { 867218893Sdim bits<4> RdLo; 868218893Sdim bits<4> RdHi; 869218893Sdim let Inst{19-16} = RdHi; 870218893Sdim let Inst{15-12} = RdLo; 871218893Sdim} 872218893Sdim 873193323Sed// Extend instructions. 874198090Srdivackyclass AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, 875198090Srdivacky string opc, string asm, list<dag> pattern> 876224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin, 877198090Srdivacky opc, asm, "", pattern> { 878218893Sdim // All AExtI instructions have Rd and Rm register operands. 879218893Sdim bits<4> Rd; 880218893Sdim bits<4> Rm; 881218893Sdim let Inst{15-12} = Rd; 882218893Sdim let Inst{3-0} = Rm; 883193323Sed let Inst{7-4} = 0b0111; 884218893Sdim let Inst{9-8} = 0b00; 885193323Sed let Inst{27-20} = opcod; 886239462Sdim 887239462Sdim let Unpredictable{9-8} = 0b11; 888193323Sed} 889193323Sed 890193323Sed// Misc Arithmetic instructions. 891218893Sdimclass AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops, 892218893Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 893224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 894198090Srdivacky opc, asm, "", pattern> { 895218893Sdim bits<4> Rd; 896218893Sdim bits<4> Rm; 897193323Sed let Inst{27-20} = opcod; 898218893Sdim let Inst{19-16} = 0b1111; 899218893Sdim let Inst{15-12} = Rd; 900218893Sdim let Inst{11-8} = 0b1111; 901218893Sdim let Inst{7-4} = opc7_4; 902218893Sdim let Inst{3-0} = Rm; 903193323Sed} 904193323Sed 905243830Sdim// Division instructions. 906243830Sdimclass ADivA1I<bits<3> opcod, dag oops, dag iops, 907243830Sdim InstrItinClass itin, string opc, string asm, list<dag> pattern> 908243830Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 909243830Sdim opc, asm, "", pattern> { 910243830Sdim bits<4> Rd; 911243830Sdim bits<4> Rn; 912243830Sdim bits<4> Rm; 913243830Sdim let Inst{27-23} = 0b01110; 914243830Sdim let Inst{22-20} = opcod; 915243830Sdim let Inst{19-16} = Rd; 916243830Sdim let Inst{15-12} = 0b1111; 917243830Sdim let Inst{11-8} = Rm; 918243830Sdim let Inst{7-4} = 0b0001; 919243830Sdim let Inst{3-0} = Rn; 920243830Sdim} 921243830Sdim 922218893Sdim// PKH instructions 923234353Sdimdef PKHLSLAsmOperand : ImmAsmOperand { 924226633Sdim let Name = "PKHLSLImm"; 925226633Sdim let ParserMethod = "parsePKHLSLImm"; 926226633Sdim} 927226633Sdimdef pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{ 928226633Sdim let PrintMethod = "printPKHLSLShiftImm"; 929226633Sdim let ParserMatchClass = PKHLSLAsmOperand; 930226633Sdim} 931226633Sdimdef PKHASRAsmOperand : AsmOperandClass { 932226633Sdim let Name = "PKHASRImm"; 933226633Sdim let ParserMethod = "parsePKHASRImm"; 934226633Sdim} 935226633Sdimdef pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{ 936226633Sdim let PrintMethod = "printPKHASRShiftImm"; 937226633Sdim let ParserMatchClass = PKHASRAsmOperand; 938226633Sdim} 939226633Sdim 940218893Sdimclass APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin, 941218893Sdim string opc, string asm, list<dag> pattern> 942224145Sdim : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin, 943218893Sdim opc, asm, "", pattern> { 944218893Sdim bits<4> Rd; 945218893Sdim bits<4> Rn; 946218893Sdim bits<4> Rm; 947226633Sdim bits<5> sh; 948218893Sdim let Inst{27-20} = opcod; 949218893Sdim let Inst{19-16} = Rn; 950218893Sdim let Inst{15-12} = Rd; 951226633Sdim let Inst{11-7} = sh; 952218893Sdim let Inst{6} = tb; 953218893Sdim let Inst{5-4} = 0b01; 954218893Sdim let Inst{3-0} = Rm; 955218893Sdim} 956218893Sdim 957193323Sed//===----------------------------------------------------------------------===// 958193323Sed 959193323Sed// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode. 960193323Sedclass ARMPat<dag pattern, dag result> : Pat<pattern, result> { 961193323Sed list<Predicate> Predicates = [IsARM]; 962193323Sed} 963223017Sdimclass ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> { 964223017Sdim list<Predicate> Predicates = [IsARM, HasV5T]; 965223017Sdim} 966193323Sedclass ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> { 967193323Sed list<Predicate> Predicates = [IsARM, HasV5TE]; 968193323Sed} 969243830Sdim// ARMV5MOPat - Same as ARMV5TEPat with UseMulOps. 970243830Sdimclass ARMV5MOPat<dag pattern, dag result> : Pat<pattern, result> { 971243830Sdim list<Predicate> Predicates = [IsARM, HasV5TE, UseMulOps]; 972243830Sdim} 973193323Sedclass ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> { 974193323Sed list<Predicate> Predicates = [IsARM, HasV6]; 975193323Sed} 976193323Sed 977193323Sed//===----------------------------------------------------------------------===// 978193323Sed// Thumb Instruction Format Definitions. 979193323Sed// 980193323Sed 981224145Sdimclass ThumbI<dag oops, dag iops, AddrMode am, int sz, 982198090Srdivacky InstrItinClass itin, string asm, string cstr, list<dag> pattern> 983201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 984198090Srdivacky let OutOperandList = oops; 985198090Srdivacky let InOperandList = iops; 986208599Srdivacky let AsmString = asm; 987193323Sed let Pattern = pattern; 988193323Sed list<Predicate> Predicates = [IsThumb]; 989193323Sed} 990193323Sed 991218893Sdim// TI - Thumb instruction. 992198090Srdivackyclass TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> 993224145Sdim : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 994193323Sed 995198090Srdivacky// Two-address instructions 996206083Srdivackyclass TIt<dag oops, dag iops, InstrItinClass itin, string asm, 997206083Srdivacky list<dag> pattern> 998224145Sdim : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst", 999206083Srdivacky pattern>; 1000193323Sed 1001201360Srdivacky// tBL, tBX 32-bit instructions 1002201360Srdivackyclass TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3, 1003206083Srdivacky dag oops, dag iops, InstrItinClass itin, string asm, 1004206083Srdivacky list<dag> pattern> 1005224145Sdim : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>, 1006206083Srdivacky Encoding { 1007201360Srdivacky let Inst{31-27} = opcod1; 1008201360Srdivacky let Inst{15-14} = opcod2; 1009212904Sdim let Inst{12} = opcod3; 1010201360Srdivacky} 1011198090Srdivacky 1012193323Sed// BR_JT instructions 1013206083Srdivackyclass TJTI<dag oops, dag iops, InstrItinClass itin, string asm, 1014206083Srdivacky list<dag> pattern> 1015224145Sdim : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1016193323Sed 1017198090Srdivacky// Thumb1 only 1018224145Sdimclass Thumb1I<dag oops, dag iops, AddrMode am, int sz, 1019198090Srdivacky InstrItinClass itin, string asm, string cstr, list<dag> pattern> 1020201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1021198090Srdivacky let OutOperandList = oops; 1022198090Srdivacky let InOperandList = iops; 1023208599Srdivacky let AsmString = asm; 1024198090Srdivacky let Pattern = pattern; 1025218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1026194710Sed} 1027193323Sed 1028198090Srdivackyclass T1I<dag oops, dag iops, InstrItinClass itin, 1029198090Srdivacky string asm, list<dag> pattern> 1030224145Sdim : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>; 1031198090Srdivackyclass T1Ix2<dag oops, dag iops, InstrItinClass itin, 1032198090Srdivacky string asm, list<dag> pattern> 1033224145Sdim : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1034194710Sed 1035198090Srdivacky// Two-address instructions 1036198090Srdivackyclass T1It<dag oops, dag iops, InstrItinClass itin, 1037205218Srdivacky string asm, string cstr, list<dag> pattern> 1038224145Sdim : Thumb1I<oops, iops, AddrModeNone, 2, itin, 1039205218Srdivacky asm, cstr, pattern>; 1040198090Srdivacky 1041198090Srdivacky// Thumb1 instruction that can either be predicated or set CPSR. 1042224145Sdimclass Thumb1sI<dag oops, dag iops, AddrMode am, int sz, 1043198090Srdivacky InstrItinClass itin, 1044198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1045201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1046205407Srdivacky let OutOperandList = !con(oops, (outs s_cc_out:$s)); 1047205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1048218893Sdim let AsmString = !strconcat(opc, "${s}${p}", asm); 1049194754Sed let Pattern = pattern; 1050226633Sdim let thumbArithFlagSetting = 1; 1051218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1052226633Sdim let DecoderNamespace = "ThumbSBit"; 1053195098Sed} 1054195098Sed 1055198090Srdivackyclass T1sI<dag oops, dag iops, InstrItinClass itin, 1056198090Srdivacky string opc, string asm, list<dag> pattern> 1057224145Sdim : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1058195098Sed 1059195098Sed// Two-address instructions 1060198090Srdivackyclass T1sIt<dag oops, dag iops, InstrItinClass itin, 1061198090Srdivacky string opc, string asm, list<dag> pattern> 1062224145Sdim : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1063218893Sdim "$Rn = $Rdn", pattern>; 1064195098Sed 1065198090Srdivacky// Thumb1 instruction that can be predicated. 1066224145Sdimclass Thumb1pI<dag oops, dag iops, AddrMode am, int sz, 1067198090Srdivacky InstrItinClass itin, 1068198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1069201360Srdivacky : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1070198090Srdivacky let OutOperandList = oops; 1071205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1072218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1073198090Srdivacky let Pattern = pattern; 1074218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1075195098Sed} 1076195098Sed 1077198090Srdivackyclass T1pI<dag oops, dag iops, InstrItinClass itin, 1078198090Srdivacky string opc, string asm, list<dag> pattern> 1079224145Sdim : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>; 1080198090Srdivacky 1081198090Srdivacky// Two-address instructions 1082198090Srdivackyclass T1pIt<dag oops, dag iops, InstrItinClass itin, 1083198090Srdivacky string opc, string asm, list<dag> pattern> 1084224145Sdim : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, 1085218893Sdim "$Rn = $Rdn", pattern>; 1086198090Srdivacky 1087206083Srdivackyclass T1pIs<dag oops, dag iops, 1088198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1089224145Sdim : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>; 1090198090Srdivacky 1091201360Srdivackyclass Encoding16 : Encoding { 1092201360Srdivacky let Inst{31-16} = 0x0000; 1093201360Srdivacky} 1094201360Srdivacky 1095201360Srdivacky// A6.2 16-bit Thumb instruction encoding 1096201360Srdivackyclass T1Encoding<bits<6> opcode> : Encoding16 { 1097201360Srdivacky let Inst{15-10} = opcode; 1098201360Srdivacky} 1099201360Srdivacky 1100201360Srdivacky// A6.2.1 Shift (immediate), add, subtract, move, and compare encoding. 1101201360Srdivackyclass T1General<bits<5> opcode> : Encoding16 { 1102201360Srdivacky let Inst{15-14} = 0b00; 1103201360Srdivacky let Inst{13-9} = opcode; 1104201360Srdivacky} 1105201360Srdivacky 1106201360Srdivacky// A6.2.2 Data-processing encoding. 1107201360Srdivackyclass T1DataProcessing<bits<4> opcode> : Encoding16 { 1108201360Srdivacky let Inst{15-10} = 0b010000; 1109201360Srdivacky let Inst{9-6} = opcode; 1110201360Srdivacky} 1111201360Srdivacky 1112201360Srdivacky// A6.2.3 Special data instructions and branch and exchange encoding. 1113201360Srdivackyclass T1Special<bits<4> opcode> : Encoding16 { 1114201360Srdivacky let Inst{15-10} = 0b010001; 1115218893Sdim let Inst{9-6} = opcode; 1116201360Srdivacky} 1117201360Srdivacky 1118201360Srdivacky// A6.2.4 Load/store single data item encoding. 1119201360Srdivackyclass T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 { 1120201360Srdivacky let Inst{15-12} = opA; 1121212904Sdim let Inst{11-9} = opB; 1122201360Srdivacky} 1123212904Sdimclass T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative 1124201360Srdivacky 1125223017Sdimclass T1BranchCond<bits<4> opcode> : Encoding16 { 1126223017Sdim let Inst{15-12} = opcode; 1127223017Sdim} 1128223017Sdim 1129218893Sdim// Helper classes to encode Thumb1 loads and stores. For immediates, the 1130218893Sdim// following bits are used for "opA" (see A6.2.4): 1131218893Sdim// 1132218893Sdim// 0b0110 => Immediate, 4 bytes 1133218893Sdim// 0b1000 => Immediate, 2 bytes 1134218893Sdim// 0b0111 => Immediate, 1 byte 1135218893Sdimclass T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am, 1136218893Sdim InstrItinClass itin, string opc, string asm, 1137218893Sdim list<dag> pattern> 1138224145Sdim : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1139218893Sdim T1LoadStore<0b0101, opcode> { 1140218893Sdim bits<3> Rt; 1141218893Sdim bits<8> addr; 1142218893Sdim let Inst{8-6} = addr{5-3}; // Rm 1143218893Sdim let Inst{5-3} = addr{2-0}; // Rn 1144218893Sdim let Inst{2-0} = Rt; 1145218893Sdim} 1146218893Sdimclass T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am, 1147218893Sdim InstrItinClass itin, string opc, string asm, 1148218893Sdim list<dag> pattern> 1149224145Sdim : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>, 1150218893Sdim T1LoadStore<opA, {opB,?,?}> { 1151218893Sdim bits<3> Rt; 1152218893Sdim bits<8> addr; 1153218893Sdim let Inst{10-6} = addr{7-3}; // imm5 1154218893Sdim let Inst{5-3} = addr{2-0}; // Rn 1155218893Sdim let Inst{2-0} = Rt; 1156218893Sdim} 1157218893Sdim 1158201360Srdivacky// A6.2.5 Miscellaneous 16-bit instructions encoding. 1159201360Srdivackyclass T1Misc<bits<7> opcode> : Encoding16 { 1160201360Srdivacky let Inst{15-12} = 0b1011; 1161201360Srdivacky let Inst{11-5} = opcode; 1162201360Srdivacky} 1163201360Srdivacky 1164195098Sed// Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable. 1165224145Sdimclass Thumb2I<dag oops, dag iops, AddrMode am, int sz, 1166198090Srdivacky InstrItinClass itin, 1167195098Sed string opc, string asm, string cstr, list<dag> pattern> 1168198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1169195098Sed let OutOperandList = oops; 1170205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1171218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1172195098Sed let Pattern = pattern; 1173195340Sed list<Predicate> Predicates = [IsThumb2]; 1174226633Sdim let DecoderNamespace = "Thumb2"; 1175194754Sed} 1176194754Sed 1177212904Sdim// Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an 1178212904Sdim// input operand since by default it's a zero register. It will become an 1179212904Sdim// implicit def once it's "flipped". 1180218893Sdim// 1181195098Sed// FIXME: This uses unified syntax so {s} comes before {p}. We should make it 1182195098Sed// more consistent. 1183224145Sdimclass Thumb2sI<dag oops, dag iops, AddrMode am, int sz, 1184198090Srdivacky InstrItinClass itin, 1185195098Sed string opc, string asm, string cstr, list<dag> pattern> 1186198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1187218893Sdim bits<1> s; // condition-code set flag ('1' if the insn should set the flags) 1188218893Sdim let Inst{20} = s; 1189218893Sdim 1190195098Sed let OutOperandList = oops; 1191205407Srdivacky let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); 1192218893Sdim let AsmString = !strconcat(opc, "${s}${p}", asm); 1193195098Sed let Pattern = pattern; 1194195340Sed list<Predicate> Predicates = [IsThumb2]; 1195226633Sdim let DecoderNamespace = "Thumb2"; 1196195098Sed} 1197194754Sed 1198195098Sed// Special cases 1199224145Sdimclass Thumb2XI<dag oops, dag iops, AddrMode am, int sz, 1200198090Srdivacky InstrItinClass itin, 1201195098Sed string asm, string cstr, list<dag> pattern> 1202198892Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1203195098Sed let OutOperandList = oops; 1204195098Sed let InOperandList = iops; 1205208599Srdivacky let AsmString = asm; 1206195098Sed let Pattern = pattern; 1207195340Sed list<Predicate> Predicates = [IsThumb2]; 1208226633Sdim let DecoderNamespace = "Thumb2"; 1209194754Sed} 1210194754Sed 1211224145Sdimclass ThumbXI<dag oops, dag iops, AddrMode am, int sz, 1212206083Srdivacky InstrItinClass itin, 1213206083Srdivacky string asm, string cstr, list<dag> pattern> 1214200581Srdivacky : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> { 1215200581Srdivacky let OutOperandList = oops; 1216200581Srdivacky let InOperandList = iops; 1217208599Srdivacky let AsmString = asm; 1218200581Srdivacky let Pattern = pattern; 1219218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1220226633Sdim let DecoderNamespace = "Thumb"; 1221200581Srdivacky} 1222200581Srdivacky 1223198090Srdivackyclass T2I<dag oops, dag iops, InstrItinClass itin, 1224198090Srdivacky string opc, string asm, list<dag> pattern> 1225224145Sdim : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1226198090Srdivackyclass T2Ii12<dag oops, dag iops, InstrItinClass itin, 1227198090Srdivacky string opc, string asm, list<dag> pattern> 1228224145Sdim : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>; 1229198090Srdivackyclass T2Ii8<dag oops, dag iops, InstrItinClass itin, 1230198090Srdivacky string opc, string asm, list<dag> pattern> 1231224145Sdim : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>; 1232198090Srdivackyclass T2Iso<dag oops, dag iops, InstrItinClass itin, 1233198090Srdivacky string opc, string asm, list<dag> pattern> 1234224145Sdim : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>; 1235198090Srdivackyclass T2Ipc<dag oops, dag iops, InstrItinClass itin, 1236198090Srdivacky string opc, string asm, list<dag> pattern> 1237224145Sdim : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>; 1238218893Sdimclass T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin, 1239226633Sdim string opc, string asm, string cstr, list<dag> pattern> 1240226633Sdim : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1241201360Srdivacky pattern> { 1242218893Sdim bits<4> Rt; 1243218893Sdim bits<4> Rt2; 1244218893Sdim bits<13> addr; 1245218893Sdim let Inst{31-25} = 0b1110100; 1246212904Sdim let Inst{24} = P; 1247218893Sdim let Inst{23} = addr{8}; 1248212904Sdim let Inst{22} = 1; 1249212904Sdim let Inst{21} = W; 1250218893Sdim let Inst{20} = isLoad; 1251218893Sdim let Inst{19-16} = addr{12-9}; 1252218893Sdim let Inst{15-12} = Rt{3-0}; 1253218893Sdim let Inst{11-8} = Rt2{3-0}; 1254218893Sdim let Inst{7-0} = addr{7-0}; 1255201360Srdivacky} 1256226633Sdimclass T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops, 1257226633Sdim InstrItinClass itin, string opc, string asm, string cstr, 1258226633Sdim list<dag> pattern> 1259226633Sdim : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr, 1260226633Sdim pattern> { 1261226633Sdim bits<4> Rt; 1262226633Sdim bits<4> Rt2; 1263226633Sdim bits<4> addr; 1264226633Sdim bits<9> imm; 1265226633Sdim let Inst{31-25} = 0b1110100; 1266226633Sdim let Inst{24} = P; 1267226633Sdim let Inst{23} = imm{8}; 1268226633Sdim let Inst{22} = 1; 1269226633Sdim let Inst{21} = W; 1270226633Sdim let Inst{20} = isLoad; 1271226633Sdim let Inst{19-16} = addr; 1272226633Sdim let Inst{15-12} = Rt{3-0}; 1273226633Sdim let Inst{11-8} = Rt2{3-0}; 1274226633Sdim let Inst{7-0} = imm{7-0}; 1275226633Sdim} 1276195098Sed 1277198090Srdivackyclass T2sI<dag oops, dag iops, InstrItinClass itin, 1278198090Srdivacky string opc, string asm, list<dag> pattern> 1279224145Sdim : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>; 1280195098Sed 1281198090Srdivackyclass T2XI<dag oops, dag iops, InstrItinClass itin, 1282198090Srdivacky string asm, list<dag> pattern> 1283224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>; 1284198090Srdivackyclass T2JTI<dag oops, dag iops, InstrItinClass itin, 1285198090Srdivacky string asm, list<dag> pattern> 1286224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>; 1287195098Sed 1288218893Sdim// Move to/from coprocessor instructions 1289261991Sdimclass T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm, 1290261991Sdim list<dag> pattern> 1291261991Sdim : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> { 1292224145Sdim let Inst{31-28} = opc; 1293218893Sdim} 1294198090Srdivacky 1295205218Srdivacky// Two-address instructions 1296205218Srdivackyclass T2XIt<dag oops, dag iops, InstrItinClass itin, 1297205218Srdivacky string asm, string cstr, list<dag> pattern> 1298224145Sdim : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>; 1299198090Srdivacky 1300226633Sdim// T2Ipreldst - Thumb2 pre-indexed load / store instructions. 1301226633Sdimclass T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre, 1302201360Srdivacky dag oops, dag iops, 1303201360Srdivacky AddrMode am, IndexMode im, InstrItinClass itin, 1304195340Sed string opc, string asm, string cstr, list<dag> pattern> 1305224145Sdim : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1306195340Sed let OutOperandList = oops; 1307205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1308218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1309195340Sed let Pattern = pattern; 1310195340Sed list<Predicate> Predicates = [IsThumb2]; 1311226633Sdim let DecoderNamespace = "Thumb2"; 1312226633Sdim 1313226633Sdim bits<4> Rt; 1314226633Sdim bits<13> addr; 1315201360Srdivacky let Inst{31-27} = 0b11111; 1316201360Srdivacky let Inst{26-25} = 0b00; 1317212904Sdim let Inst{24} = signed; 1318212904Sdim let Inst{23} = 0; 1319201360Srdivacky let Inst{22-21} = opcod; 1320212904Sdim let Inst{20} = load; 1321226633Sdim let Inst{19-16} = addr{12-9}; 1322226633Sdim let Inst{15-12} = Rt{3-0}; 1323212904Sdim let Inst{11} = 1; 1324201360Srdivacky // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1325212904Sdim let Inst{10} = pre; // The P bit. 1326226633Sdim let Inst{9} = addr{8}; // Sign bit 1327212904Sdim let Inst{8} = 1; // The W bit. 1328226633Sdim let Inst{7-0} = addr{7-0}; 1329195340Sed 1330226633Sdim let DecoderMethod = "DecodeT2LdStPre"; 1331226633Sdim} 1332218893Sdim 1333226633Sdim// T2Ipostldst - Thumb2 post-indexed load / store instructions. 1334226633Sdimclass T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre, 1335226633Sdim dag oops, dag iops, 1336226633Sdim AddrMode am, IndexMode im, InstrItinClass itin, 1337226633Sdim string opc, string asm, string cstr, list<dag> pattern> 1338226633Sdim : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> { 1339226633Sdim let OutOperandList = oops; 1340226633Sdim let InOperandList = !con(iops, (ins pred:$p)); 1341226633Sdim let AsmString = !strconcat(opc, "${p}", asm); 1342226633Sdim let Pattern = pattern; 1343226633Sdim list<Predicate> Predicates = [IsThumb2]; 1344226633Sdim let DecoderNamespace = "Thumb2"; 1345226633Sdim 1346218893Sdim bits<4> Rt; 1347218893Sdim bits<4> Rn; 1348226633Sdim bits<9> offset; 1349226633Sdim let Inst{31-27} = 0b11111; 1350226633Sdim let Inst{26-25} = 0b00; 1351226633Sdim let Inst{24} = signed; 1352226633Sdim let Inst{23} = 0; 1353226633Sdim let Inst{22-21} = opcod; 1354226633Sdim let Inst{20} = load; 1355226633Sdim let Inst{19-16} = Rn; 1356218893Sdim let Inst{15-12} = Rt{3-0}; 1357226633Sdim let Inst{11} = 1; 1358226633Sdim // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed 1359226633Sdim let Inst{10} = pre; // The P bit. 1360226633Sdim let Inst{9} = offset{8}; // Sign bit 1361226633Sdim let Inst{8} = 1; // The W bit. 1362226633Sdim let Inst{7-0} = offset{7-0}; 1363226633Sdim 1364226633Sdim let DecoderMethod = "DecodeT2LdStPre"; 1365204642Srdivacky} 1366204642Srdivacky 1367198090Srdivacky// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. 1368198090Srdivackyclass Tv5Pat<dag pattern, dag result> : Pat<pattern, result> { 1369218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T]; 1370198090Srdivacky} 1371195340Sed 1372198090Srdivacky// T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode. 1373198090Srdivackyclass T1Pat<dag pattern, dag result> : Pat<pattern, result> { 1374218893Sdim list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 1375198090Srdivacky} 1376198090Srdivacky 1377223017Sdim// T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode. 1378223017Sdimclass T2v6Pat<dag pattern, dag result> : Pat<pattern, result> { 1379223017Sdim list<Predicate> Predicates = [IsThumb2, HasV6T2]; 1380223017Sdim} 1381223017Sdim 1382195098Sed// T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode. 1383195098Sedclass T2Pat<dag pattern, dag result> : Pat<pattern, result> { 1384195340Sed list<Predicate> Predicates = [IsThumb2]; 1385195098Sed} 1386195098Sed 1387193323Sed//===----------------------------------------------------------------------===// 1388193323Sed 1389193323Sed//===----------------------------------------------------------------------===// 1390193323Sed// ARM VFP Instruction templates. 1391193323Sed// 1392193323Sed 1393198090Srdivacky// Almost all VFP instructions are predicable. 1394224145Sdimclass VFPI<dag oops, dag iops, AddrMode am, int sz, 1395198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 1396198090Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1397198892Srdivacky : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1398218893Sdim bits<4> p; 1399218893Sdim let Inst{31-28} = p; 1400198090Srdivacky let OutOperandList = oops; 1401205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1402218893Sdim let AsmString = !strconcat(opc, "${p}", asm); 1403198090Srdivacky let Pattern = pattern; 1404218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1405226633Sdim let DecoderNamespace = "VFP"; 1406198090Srdivacky list<Predicate> Predicates = [HasVFP2]; 1407198090Srdivacky} 1408198090Srdivacky 1409198090Srdivacky// Special cases 1410224145Sdimclass VFPXI<dag oops, dag iops, AddrMode am, int sz, 1411198090Srdivacky IndexMode im, Format f, InstrItinClass itin, 1412198090Srdivacky string asm, string cstr, list<dag> pattern> 1413198892Srdivacky : InstARM<am, sz, im, f, VFPDomain, cstr, itin> { 1414218893Sdim bits<4> p; 1415218893Sdim let Inst{31-28} = p; 1416198090Srdivacky let OutOperandList = oops; 1417198090Srdivacky let InOperandList = iops; 1418208599Srdivacky let AsmString = asm; 1419198090Srdivacky let Pattern = pattern; 1420218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1421226633Sdim let DecoderNamespace = "VFP"; 1422198090Srdivacky list<Predicate> Predicates = [HasVFP2]; 1423198090Srdivacky} 1424198090Srdivacky 1425198090Srdivackyclass VFPAI<dag oops, dag iops, Format f, InstrItinClass itin, 1426198090Srdivacky string opc, string asm, list<dag> pattern> 1427224145Sdim : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin, 1428218893Sdim opc, asm, "", pattern> { 1429218893Sdim let PostEncoderMethod = "VFPThumb2PostEncoder"; 1430218893Sdim} 1431198090Srdivacky 1432193323Sed// ARM VFP addrmode5 loads and stores 1433193323Sedclass ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1434198090Srdivacky InstrItinClass itin, 1435193323Sed string opc, string asm, list<dag> pattern> 1436224145Sdim : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1437206083Srdivacky VFPLdStFrm, itin, opc, asm, "", pattern> { 1438218893Sdim // Instruction operands. 1439218893Sdim bits<5> Dd; 1440218893Sdim bits<13> addr; 1441218893Sdim 1442218893Sdim // Encode instruction operands. 1443218893Sdim let Inst{23} = addr{8}; // U (add = (U == '1')) 1444218893Sdim let Inst{22} = Dd{4}; 1445218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1446218893Sdim let Inst{15-12} = Dd{3-0}; 1447218893Sdim let Inst{7-0} = addr{7-0}; // imm8 1448218893Sdim 1449193323Sed let Inst{27-24} = opcod1; 1450193323Sed let Inst{21-20} = opcod2; 1451218893Sdim let Inst{11-9} = 0b101; 1452218893Sdim let Inst{8} = 1; // Double precision 1453198892Srdivacky 1454218893Sdim // Loads & stores operate on both NEON and VFP pipelines. 1455206274Srdivacky let D = VFPNeonDomain; 1456193323Sed} 1457193323Sed 1458193323Sedclass ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, 1459198090Srdivacky InstrItinClass itin, 1460193323Sed string opc, string asm, list<dag> pattern> 1461224145Sdim : VFPI<oops, iops, AddrMode5, 4, IndexModeNone, 1462206083Srdivacky VFPLdStFrm, itin, opc, asm, "", pattern> { 1463218893Sdim // Instruction operands. 1464218893Sdim bits<5> Sd; 1465218893Sdim bits<13> addr; 1466218893Sdim 1467218893Sdim // Encode instruction operands. 1468218893Sdim let Inst{23} = addr{8}; // U (add = (U == '1')) 1469218893Sdim let Inst{22} = Sd{0}; 1470218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1471218893Sdim let Inst{15-12} = Sd{4-1}; 1472218893Sdim let Inst{7-0} = addr{7-0}; // imm8 1473218893Sdim 1474193323Sed let Inst{27-24} = opcod1; 1475193323Sed let Inst{21-20} = opcod2; 1476218893Sdim let Inst{11-9} = 0b101; 1477218893Sdim let Inst{8} = 0; // Single precision 1478218893Sdim 1479218893Sdim // Loads & stores operate on both NEON and VFP pipelines. 1480218893Sdim let D = VFPNeonDomain; 1481193323Sed} 1482193323Sed 1483218893Sdim// VFP Load / store multiple pseudo instructions. 1484218893Sdimclass PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr, 1485218893Sdim list<dag> pattern> 1486224145Sdim : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain, 1487218893Sdim cstr, itin> { 1488218893Sdim let OutOperandList = oops; 1489218893Sdim let InOperandList = !con(iops, (ins pred:$p)); 1490218893Sdim let Pattern = pattern; 1491218893Sdim list<Predicate> Predicates = [HasVFP2]; 1492218893Sdim} 1493218893Sdim 1494193323Sed// Load / store multiple 1495261991Sdim 1496261991Sdim// Unknown precision 1497261991Sdimclass AXXI4<dag oops, dag iops, IndexMode im, 1498261991Sdim string asm, string cstr, list<dag> pattern> 1499261991Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1500261991Sdim VFPLdStFrm, NoItinerary, asm, cstr, pattern> { 1501261991Sdim // Instruction operands. 1502261991Sdim bits<4> Rn; 1503261991Sdim bits<13> regs; 1504261991Sdim 1505261991Sdim // Encode instruction operands. 1506261991Sdim let Inst{19-16} = Rn; 1507261991Sdim let Inst{22} = 0; 1508261991Sdim let Inst{15-12} = regs{11-8}; 1509261991Sdim let Inst{7-1} = regs{7-1}; 1510261991Sdim 1511261991Sdim let Inst{27-25} = 0b110; 1512261991Sdim let Inst{11-8} = 0b1011; 1513261991Sdim let Inst{0} = 1; 1514261991Sdim} 1515261991Sdim 1516261991Sdim// Double precision 1517212904Sdimclass AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1518205218Srdivacky string asm, string cstr, list<dag> pattern> 1519224145Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1520206083Srdivacky VFPLdStMulFrm, itin, asm, cstr, pattern> { 1521218893Sdim // Instruction operands. 1522218893Sdim bits<4> Rn; 1523218893Sdim bits<13> regs; 1524218893Sdim 1525218893Sdim // Encode instruction operands. 1526218893Sdim let Inst{19-16} = Rn; 1527218893Sdim let Inst{22} = regs{12}; 1528218893Sdim let Inst{15-12} = regs{11-8}; 1529261991Sdim let Inst{7-1} = regs{7-1}; 1530218893Sdim 1531193323Sed let Inst{27-25} = 0b110; 1532218893Sdim let Inst{11-9} = 0b101; 1533218893Sdim let Inst{8} = 1; // Double precision 1534261991Sdim let Inst{0} = 0; 1535193323Sed} 1536193323Sed 1537261991Sdim// Single Precision 1538212904Sdimclass AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, 1539205218Srdivacky string asm, string cstr, list<dag> pattern> 1540224145Sdim : VFPXI<oops, iops, AddrMode4, 4, im, 1541206083Srdivacky VFPLdStMulFrm, itin, asm, cstr, pattern> { 1542218893Sdim // Instruction operands. 1543218893Sdim bits<4> Rn; 1544218893Sdim bits<13> regs; 1545218893Sdim 1546218893Sdim // Encode instruction operands. 1547218893Sdim let Inst{19-16} = Rn; 1548218893Sdim let Inst{22} = regs{8}; 1549218893Sdim let Inst{15-12} = regs{12-9}; 1550218893Sdim let Inst{7-0} = regs{7-0}; 1551218893Sdim 1552193323Sed let Inst{27-25} = 0b110; 1553218893Sdim let Inst{11-9} = 0b101; 1554218893Sdim let Inst{8} = 0; // Single precision 1555193323Sed} 1556193323Sed 1557193323Sed// Double precision, unary 1558203954Srdivackyclass ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1559203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1560203954Srdivacky string asm, list<dag> pattern> 1561198090Srdivacky : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1562218893Sdim // Instruction operands. 1563218893Sdim bits<5> Dd; 1564218893Sdim bits<5> Dm; 1565218893Sdim 1566218893Sdim // Encode instruction operands. 1567218893Sdim let Inst{3-0} = Dm{3-0}; 1568218893Sdim let Inst{5} = Dm{4}; 1569218893Sdim let Inst{15-12} = Dd{3-0}; 1570218893Sdim let Inst{22} = Dd{4}; 1571218893Sdim 1572203954Srdivacky let Inst{27-23} = opcod1; 1573203954Srdivacky let Inst{21-20} = opcod2; 1574203954Srdivacky let Inst{19-16} = opcod3; 1575218893Sdim let Inst{11-9} = 0b101; 1576218893Sdim let Inst{8} = 1; // Double precision 1577203954Srdivacky let Inst{7-6} = opcod4; 1578203954Srdivacky let Inst{4} = opcod5; 1579261991Sdim 1580261991Sdim let Predicates = [HasVFP2, HasDPVFP]; 1581193323Sed} 1582193323Sed 1583261991Sdim// Double precision, unary, not-predicated 1584261991Sdimclass ADuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1585261991Sdim bit opcod5, dag oops, dag iops, InstrItinClass itin, 1586261991Sdim string asm, list<dag> pattern> 1587261991Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPUnaryFrm, itin, asm, "", pattern> { 1588261991Sdim // Instruction operands. 1589261991Sdim bits<5> Dd; 1590261991Sdim bits<5> Dm; 1591261991Sdim 1592261991Sdim let Inst{31-28} = 0b1111; 1593261991Sdim 1594261991Sdim // Encode instruction operands. 1595261991Sdim let Inst{3-0} = Dm{3-0}; 1596261991Sdim let Inst{5} = Dm{4}; 1597261991Sdim let Inst{15-12} = Dd{3-0}; 1598261991Sdim let Inst{22} = Dd{4}; 1599261991Sdim 1600261991Sdim let Inst{27-23} = opcod1; 1601261991Sdim let Inst{21-20} = opcod2; 1602261991Sdim let Inst{19-16} = opcod3; 1603261991Sdim let Inst{11-9} = 0b101; 1604261991Sdim let Inst{8} = 1; // Double precision 1605261991Sdim let Inst{7-6} = opcod4; 1606261991Sdim let Inst{4} = opcod5; 1607261991Sdim} 1608261991Sdim 1609193323Sed// Double precision, binary 1610203954Srdivackyclass ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1611206083Srdivacky dag iops, InstrItinClass itin, string opc, string asm, 1612206083Srdivacky list<dag> pattern> 1613198090Srdivacky : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1614218893Sdim // Instruction operands. 1615218893Sdim bits<5> Dd; 1616218893Sdim bits<5> Dn; 1617218893Sdim bits<5> Dm; 1618193323Sed 1619218893Sdim // Encode instruction operands. 1620218893Sdim let Inst{3-0} = Dm{3-0}; 1621218893Sdim let Inst{5} = Dm{4}; 1622218893Sdim let Inst{19-16} = Dn{3-0}; 1623218893Sdim let Inst{7} = Dn{4}; 1624218893Sdim let Inst{15-12} = Dd{3-0}; 1625218893Sdim let Inst{22} = Dd{4}; 1626218893Sdim 1627206083Srdivacky let Inst{27-23} = opcod1; 1628206083Srdivacky let Inst{21-20} = opcod2; 1629218893Sdim let Inst{11-9} = 0b101; 1630218893Sdim let Inst{8} = 1; // Double precision 1631212904Sdim let Inst{6} = op6; 1632212904Sdim let Inst{4} = op4; 1633261991Sdim 1634261991Sdim let Predicates = [HasVFP2, HasDPVFP]; 1635206083Srdivacky} 1636206083Srdivacky 1637261991Sdim// FP, binary, not predicated 1638261991Sdimclass ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1639261991Sdim InstrItinClass itin, string asm, list<dag> pattern> 1640261991Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin, 1641261991Sdim asm, "", pattern> 1642261991Sdim{ 1643261991Sdim // Instruction operands. 1644261991Sdim bits<5> Dd; 1645261991Sdim bits<5> Dn; 1646261991Sdim bits<5> Dm; 1647261991Sdim 1648261991Sdim let Inst{31-28} = 0b1111; 1649261991Sdim 1650261991Sdim // Encode instruction operands. 1651261991Sdim let Inst{3-0} = Dm{3-0}; 1652261991Sdim let Inst{5} = Dm{4}; 1653261991Sdim let Inst{19-16} = Dn{3-0}; 1654261991Sdim let Inst{7} = Dn{4}; 1655261991Sdim let Inst{15-12} = Dd{3-0}; 1656261991Sdim let Inst{22} = Dd{4}; 1657261991Sdim 1658261991Sdim let Inst{27-23} = opcod1; 1659261991Sdim let Inst{21-20} = opcod2; 1660261991Sdim let Inst{11-9} = 0b101; 1661261991Sdim let Inst{8} = 1; // double precision 1662261991Sdim let Inst{6} = opcod3; 1663261991Sdim let Inst{4} = 0; 1664261991Sdim 1665261991Sdim let Predicates = [HasVFP2, HasDPVFP]; 1666261991Sdim} 1667261991Sdim 1668261991Sdim// Single precision, unary, predicated 1669203954Srdivackyclass ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1670203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1671203954Srdivacky string asm, list<dag> pattern> 1672198090Srdivacky : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> { 1673218893Sdim // Instruction operands. 1674218893Sdim bits<5> Sd; 1675218893Sdim bits<5> Sm; 1676218893Sdim 1677218893Sdim // Encode instruction operands. 1678218893Sdim let Inst{3-0} = Sm{4-1}; 1679218893Sdim let Inst{5} = Sm{0}; 1680218893Sdim let Inst{15-12} = Sd{4-1}; 1681218893Sdim let Inst{22} = Sd{0}; 1682218893Sdim 1683203954Srdivacky let Inst{27-23} = opcod1; 1684203954Srdivacky let Inst{21-20} = opcod2; 1685203954Srdivacky let Inst{19-16} = opcod3; 1686218893Sdim let Inst{11-9} = 0b101; 1687218893Sdim let Inst{8} = 0; // Single precision 1688203954Srdivacky let Inst{7-6} = opcod4; 1689203954Srdivacky let Inst{4} = opcod5; 1690193323Sed} 1691193323Sed 1692261991Sdim// Single precision, unary, non-predicated 1693261991Sdimclass ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1694261991Sdim bit opcod5, dag oops, dag iops, InstrItinClass itin, 1695261991Sdim string asm, list<dag> pattern> 1696261991Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1697261991Sdim VFPUnaryFrm, itin, asm, "", pattern> { 1698261991Sdim // Instruction operands. 1699261991Sdim bits<5> Sd; 1700261991Sdim bits<5> Sm; 1701261991Sdim 1702261991Sdim let Inst{31-28} = 0b1111; 1703261991Sdim 1704261991Sdim // Encode instruction operands. 1705261991Sdim let Inst{3-0} = Sm{4-1}; 1706261991Sdim let Inst{5} = Sm{0}; 1707261991Sdim let Inst{15-12} = Sd{4-1}; 1708261991Sdim let Inst{22} = Sd{0}; 1709261991Sdim 1710261991Sdim let Inst{27-23} = opcod1; 1711261991Sdim let Inst{21-20} = opcod2; 1712261991Sdim let Inst{19-16} = opcod3; 1713261991Sdim let Inst{11-9} = 0b101; 1714261991Sdim let Inst{8} = 0; // Single precision 1715261991Sdim let Inst{7-6} = opcod4; 1716261991Sdim let Inst{4} = opcod5; 1717261991Sdim} 1718261991Sdim 1719218893Sdim// Single precision unary, if no NEON. Same as ASuI except not available if 1720218893Sdim// NEON is enabled. 1721203954Srdivackyclass ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, 1722203954Srdivacky bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc, 1723203954Srdivacky string asm, list<dag> pattern> 1724203954Srdivacky : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm, 1725203954Srdivacky pattern> { 1726198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1727198090Srdivacky} 1728198090Srdivacky 1729193323Sed// Single precision, binary 1730203954Srdivackyclass ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, 1731203954Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1732198090Srdivacky : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> { 1733218893Sdim // Instruction operands. 1734218893Sdim bits<5> Sd; 1735218893Sdim bits<5> Sn; 1736218893Sdim bits<5> Sm; 1737218893Sdim 1738218893Sdim // Encode instruction operands. 1739218893Sdim let Inst{3-0} = Sm{4-1}; 1740218893Sdim let Inst{5} = Sm{0}; 1741218893Sdim let Inst{19-16} = Sn{4-1}; 1742218893Sdim let Inst{7} = Sn{0}; 1743218893Sdim let Inst{15-12} = Sd{4-1}; 1744218893Sdim let Inst{22} = Sd{0}; 1745218893Sdim 1746203954Srdivacky let Inst{27-23} = opcod1; 1747203954Srdivacky let Inst{21-20} = opcod2; 1748218893Sdim let Inst{11-9} = 0b101; 1749218893Sdim let Inst{8} = 0; // Single precision 1750212904Sdim let Inst{6} = op6; 1751212904Sdim let Inst{4} = op4; 1752193323Sed} 1753193323Sed 1754261991Sdim// Single precision, binary, not predicated 1755261991Sdimclass ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, 1756261991Sdim InstrItinClass itin, string asm, list<dag> pattern> 1757261991Sdim : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, 1758261991Sdim VFPBinaryFrm, itin, asm, "", pattern> 1759261991Sdim{ 1760261991Sdim // Instruction operands. 1761261991Sdim bits<5> Sd; 1762261991Sdim bits<5> Sn; 1763261991Sdim bits<5> Sm; 1764261991Sdim 1765261991Sdim let Inst{31-28} = 0b1111; 1766261991Sdim 1767261991Sdim // Encode instruction operands. 1768261991Sdim let Inst{3-0} = Sm{4-1}; 1769261991Sdim let Inst{5} = Sm{0}; 1770261991Sdim let Inst{19-16} = Sn{4-1}; 1771261991Sdim let Inst{7} = Sn{0}; 1772261991Sdim let Inst{15-12} = Sd{4-1}; 1773261991Sdim let Inst{22} = Sd{0}; 1774261991Sdim 1775261991Sdim let Inst{27-23} = opcod1; 1776261991Sdim let Inst{21-20} = opcod2; 1777261991Sdim let Inst{11-9} = 0b101; 1778261991Sdim let Inst{8} = 0; // Single precision 1779261991Sdim let Inst{6} = opcod3; 1780261991Sdim let Inst{4} = 0; 1781261991Sdim} 1782261991Sdim 1783218893Sdim// Single precision binary, if no NEON. Same as ASbI except not available if 1784218893Sdim// NEON is enabled. 1785203954Srdivackyclass ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, 1786206083Srdivacky dag iops, InstrItinClass itin, string opc, string asm, 1787206083Srdivacky list<dag> pattern> 1788203954Srdivacky : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> { 1789198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1790218893Sdim 1791218893Sdim // Instruction operands. 1792218893Sdim bits<5> Sd; 1793218893Sdim bits<5> Sn; 1794218893Sdim bits<5> Sm; 1795218893Sdim 1796218893Sdim // Encode instruction operands. 1797218893Sdim let Inst{3-0} = Sm{4-1}; 1798218893Sdim let Inst{5} = Sm{0}; 1799218893Sdim let Inst{19-16} = Sn{4-1}; 1800218893Sdim let Inst{7} = Sn{0}; 1801218893Sdim let Inst{15-12} = Sd{4-1}; 1802218893Sdim let Inst{22} = Sd{0}; 1803198090Srdivacky} 1804198090Srdivacky 1805193323Sed// VFP conversion instructions 1806203954Srdivackyclass AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 1807203954Srdivacky dag oops, dag iops, InstrItinClass itin, string opc, string asm, 1808203954Srdivacky list<dag> pattern> 1809198090Srdivacky : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> { 1810203954Srdivacky let Inst{27-23} = opcod1; 1811203954Srdivacky let Inst{21-20} = opcod2; 1812203954Srdivacky let Inst{19-16} = opcod3; 1813203954Srdivacky let Inst{11-8} = opcod4; 1814193323Sed let Inst{6} = 1; 1815203954Srdivacky let Inst{4} = 0; 1816193323Sed} 1817193323Sed 1818203954Srdivacky// VFP conversion between floating-point and fixed-point 1819203954Srdivackyclass AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5, 1820206083Srdivacky dag oops, dag iops, InstrItinClass itin, string opc, string asm, 1821206083Srdivacky list<dag> pattern> 1822203954Srdivacky : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> { 1823234353Sdim bits<5> fbits; 1824203954Srdivacky // size (fixed-point number): sx == 0 ? 16 : 32 1825203954Srdivacky let Inst{7} = op5; // sx 1826234353Sdim let Inst{5} = fbits{0}; 1827234353Sdim let Inst{3-0} = fbits{4-1}; 1828203954Srdivacky} 1829203954Srdivacky 1830198090Srdivacky// VFP conversion instructions, if no NEON 1831203954Srdivackyclass AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4, 1832198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1833198090Srdivacky string opc, string asm, list<dag> pattern> 1834203954Srdivacky : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1835203954Srdivacky pattern> { 1836198090Srdivacky list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP]; 1837198090Srdivacky} 1838198090Srdivacky 1839193323Sedclass AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f, 1840198090Srdivacky InstrItinClass itin, 1841198090Srdivacky string opc, string asm, list<dag> pattern> 1842198090Srdivacky : VFPAI<oops, iops, f, itin, opc, asm, pattern> { 1843193323Sed let Inst{27-20} = opcod1; 1844193323Sed let Inst{11-8} = opcod2; 1845193323Sed let Inst{4} = 1; 1846193323Sed} 1847193323Sed 1848198090Srdivackyclass AVConv2I<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, VFPConv2Frm, itin, opc, asm, pattern>; 1851193323Sed 1852206083Srdivackyclass AVConv3I<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, VFPConv3Frm, itin, opc, asm, pattern>; 1855193323Sed 1856198090Srdivackyclass AVConv4I<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, VFPConv4Frm, itin, opc, asm, pattern>; 1859193323Sed 1860198090Srdivackyclass AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, 1861198090Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 1862198090Srdivacky : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>; 1863193323Sed 1864193323Sed//===----------------------------------------------------------------------===// 1865193323Sed 1866194710Sed//===----------------------------------------------------------------------===// 1867194710Sed// ARM NEON Instruction templates. 1868194710Sed// 1869193323Sed 1870205407Srdivackyclass NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1871205407Srdivacky InstrItinClass itin, string opc, string dt, string asm, string cstr, 1872205407Srdivacky list<dag> pattern> 1873224145Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1874194710Sed let OutOperandList = oops; 1875205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1876218893Sdim let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 1877194710Sed let Pattern = pattern; 1878194710Sed list<Predicate> Predicates = [HasNEON]; 1879226633Sdim let DecoderNamespace = "NEON"; 1880193323Sed} 1881193323Sed 1882199989Srdivacky// Same as NeonI except it does not have a "data type" specifier. 1883206083Srdivackyclass NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1884206083Srdivacky InstrItinClass itin, string opc, string asm, string cstr, 1885206083Srdivacky list<dag> pattern> 1886224145Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1887199989Srdivacky let OutOperandList = oops; 1888205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 1889218893Sdim let AsmString = !strconcat(opc, "${p}", "\t", asm); 1890199989Srdivacky let Pattern = pattern; 1891199989Srdivacky list<Predicate> Predicates = [HasNEON]; 1892226633Sdim let DecoderNamespace = "NEON"; 1893193323Sed} 1894194710Sed 1895261991Sdim// Same as NeonI except it is not predicated 1896261991Sdimclass NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f, 1897261991Sdim InstrItinClass itin, string opc, string dt, string asm, string cstr, 1898261991Sdim list<dag> pattern> 1899261991Sdim : InstARM<am, 4, im, f, NeonDomain, cstr, itin> { 1900261991Sdim let OutOperandList = oops; 1901261991Sdim let InOperandList = iops; 1902261991Sdim let AsmString = !strconcat(opc, ".", dt, "\t", asm); 1903261991Sdim let Pattern = pattern; 1904261991Sdim list<Predicate> Predicates = [HasNEON]; 1905261991Sdim let DecoderNamespace = "NEON"; 1906261991Sdim 1907261991Sdim let Inst{31-28} = 0b1111; 1908261991Sdim} 1909261991Sdim 1910198090Srdivackyclass NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 1911198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1912199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 1913205407Srdivacky : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm, 1914205407Srdivacky cstr, pattern> { 1915198090Srdivacky let Inst{31-24} = 0b11110100; 1916212904Sdim let Inst{23} = op23; 1917198396Srdivacky let Inst{21-20} = op21_20; 1918212904Sdim let Inst{11-8} = op11_8; 1919212904Sdim let Inst{7-4} = op7_4; 1920218893Sdim 1921218893Sdim let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; 1922226633Sdim let DecoderNamespace = "NEONLoadStore"; 1923218893Sdim 1924218893Sdim bits<5> Vd; 1925218893Sdim bits<6> Rn; 1926218893Sdim bits<4> Rm; 1927218893Sdim 1928218893Sdim let Inst{22} = Vd{4}; 1929218893Sdim let Inst{15-12} = Vd{3-0}; 1930218893Sdim let Inst{19-16} = Rn{3-0}; 1931218893Sdim let Inst{3-0} = Rm{3-0}; 1932198090Srdivacky} 1933198090Srdivacky 1934218893Sdimclass NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, 1935218893Sdim dag oops, dag iops, InstrItinClass itin, 1936218893Sdim string opc, string dt, string asm, string cstr, list<dag> pattern> 1937218893Sdim : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc, 1938218893Sdim dt, asm, cstr, pattern> { 1939218893Sdim bits<3> lane; 1940218893Sdim} 1941218893Sdim 1942212904Sdimclass PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr> 1943224145Sdim : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 1944212904Sdim itin> { 1945212904Sdim let OutOperandList = oops; 1946212904Sdim let InOperandList = !con(iops, (ins pred:$p)); 1947212904Sdim list<Predicate> Predicates = [HasNEON]; 1948212904Sdim} 1949212904Sdim 1950218893Sdimclass PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr, 1951218893Sdim list<dag> pattern> 1952224145Sdim : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr, 1953218893Sdim itin> { 1954218893Sdim let OutOperandList = oops; 1955218893Sdim let InOperandList = !con(iops, (ins pred:$p)); 1956218893Sdim let Pattern = pattern; 1957218893Sdim list<Predicate> Predicates = [HasNEON]; 1958218893Sdim} 1959218893Sdim 1960206083Srdivackyclass NDataI<dag oops, dag iops, Format f, InstrItinClass itin, 1961199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 1962206083Srdivacky : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr, 1963206083Srdivacky pattern> { 1964194710Sed let Inst{31-25} = 0b1111001; 1965218893Sdim let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 1966226633Sdim let DecoderNamespace = "NEONData"; 1967194710Sed} 1968194710Sed 1969206083Srdivackyclass NDataXI<dag oops, dag iops, Format f, InstrItinClass itin, 1970206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 1971206083Srdivacky : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm, 1972206083Srdivacky cstr, pattern> { 1973199989Srdivacky let Inst{31-25} = 0b1111001; 1974218893Sdim let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; 1975226633Sdim let DecoderNamespace = "NEONData"; 1976199989Srdivacky} 1977199989Srdivacky 1978194710Sed// NEON "one register and a modified immediate" format. 1979194710Sedclass N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, 1980194710Sed bit op5, bit op4, 1981198090Srdivacky dag oops, dag iops, InstrItinClass itin, 1982206083Srdivacky string opc, string dt, string asm, string cstr, 1983206083Srdivacky list<dag> pattern> 1984206083Srdivacky : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> { 1985212904Sdim let Inst{23} = op23; 1986194710Sed let Inst{21-19} = op21_19; 1987212904Sdim let Inst{11-8} = op11_8; 1988212904Sdim let Inst{7} = op7; 1989212904Sdim let Inst{6} = op6; 1990212904Sdim let Inst{5} = op5; 1991212904Sdim let Inst{4} = op4; 1992218893Sdim 1993218893Sdim // Instruction operands. 1994218893Sdim bits<5> Vd; 1995218893Sdim bits<13> SIMM; 1996218893Sdim 1997218893Sdim let Inst{15-12} = Vd{3-0}; 1998218893Sdim let Inst{22} = Vd{4}; 1999218893Sdim let Inst{24} = SIMM{7}; 2000218893Sdim let Inst{18-16} = SIMM{6-4}; 2001218893Sdim let Inst{3-0} = SIMM{3-0}; 2002226633Sdim let DecoderMethod = "DecodeNEONModImmInstruction"; 2003194710Sed} 2004194710Sed 2005194710Sed// NEON 2 vector register format. 2006194710Sedclass N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2007194710Sed bits<5> op11_7, bit op6, bit op4, 2008198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2009199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 2010206083Srdivacky : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> { 2011194710Sed let Inst{24-23} = op24_23; 2012194710Sed let Inst{21-20} = op21_20; 2013194710Sed let Inst{19-18} = op19_18; 2014194710Sed let Inst{17-16} = op17_16; 2015212904Sdim let Inst{11-7} = op11_7; 2016212904Sdim let Inst{6} = op6; 2017212904Sdim let Inst{4} = op4; 2018218893Sdim 2019218893Sdim // Instruction operands. 2020218893Sdim bits<5> Vd; 2021218893Sdim bits<5> Vm; 2022218893Sdim 2023218893Sdim let Inst{15-12} = Vd{3-0}; 2024218893Sdim let Inst{22} = Vd{4}; 2025218893Sdim let Inst{3-0} = Vm{3-0}; 2026218893Sdim let Inst{5} = Vm{4}; 2027194710Sed} 2028194710Sed 2029261991Sdim// Same as N2V but not predicated. 2030261991Sdimclass N2Vnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 2031261991Sdim dag oops, dag iops, InstrItinClass itin, string OpcodeStr, 2032276479Sdim string Dt, list<dag> pattern> 2033261991Sdim : NeonInp<oops, iops, AddrModeNone, IndexModeNone, N2RegFrm, itin, 2034261991Sdim OpcodeStr, Dt, "$Vd, $Vm", "", pattern> { 2035261991Sdim bits<5> Vd; 2036261991Sdim bits<5> Vm; 2037261991Sdim 2038261991Sdim // Encode instruction operands 2039261991Sdim let Inst{22} = Vd{4}; 2040261991Sdim let Inst{15-12} = Vd{3-0}; 2041261991Sdim let Inst{5} = Vm{4}; 2042261991Sdim let Inst{3-0} = Vm{3-0}; 2043261991Sdim 2044261991Sdim // Encode constant bits 2045261991Sdim let Inst{27-23} = 0b00111; 2046261991Sdim let Inst{21-20} = 0b11; 2047261991Sdim let Inst{19-18} = op19_18; 2048261991Sdim let Inst{17-16} = op17_16; 2049261991Sdim let Inst{11} = 0; 2050261991Sdim let Inst{10-8} = op10_8; 2051261991Sdim let Inst{7} = op7; 2052261991Sdim let Inst{6} = op6; 2053261991Sdim let Inst{4} = 0; 2054261991Sdim 2055261991Sdim let DecoderNamespace = "NEON"; 2056261991Sdim} 2057261991Sdim 2058199989Srdivacky// Same as N2V except it doesn't have a datatype suffix. 2059199989Srdivackyclass N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, 2060206083Srdivacky bits<5> op11_7, bit op6, bit op4, 2061206083Srdivacky dag oops, dag iops, InstrItinClass itin, 2062206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 2063206083Srdivacky : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> { 2064198396Srdivacky let Inst{24-23} = op24_23; 2065198396Srdivacky let Inst{21-20} = op21_20; 2066199989Srdivacky let Inst{19-18} = op19_18; 2067199989Srdivacky let Inst{17-16} = op17_16; 2068212904Sdim let Inst{11-7} = op11_7; 2069212904Sdim let Inst{6} = op6; 2070212904Sdim let Inst{4} = op4; 2071218893Sdim 2072218893Sdim // Instruction operands. 2073218893Sdim bits<5> Vd; 2074218893Sdim bits<5> Vm; 2075218893Sdim 2076218893Sdim let Inst{15-12} = Vd{3-0}; 2077218893Sdim let Inst{22} = Vd{4}; 2078218893Sdim let Inst{3-0} = Vm{3-0}; 2079218893Sdim let Inst{5} = Vm{4}; 2080198396Srdivacky} 2081198396Srdivacky 2082194710Sed// NEON 2 vector register with immediate. 2083198396Srdivackyclass N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 2084206083Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2085199989Srdivacky string opc, string dt, string asm, string cstr, list<dag> pattern> 2086206083Srdivacky : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2087212904Sdim let Inst{24} = op24; 2088212904Sdim let Inst{23} = op23; 2089194710Sed let Inst{11-8} = op11_8; 2090212904Sdim let Inst{7} = op7; 2091212904Sdim let Inst{6} = op6; 2092212904Sdim let Inst{4} = op4; 2093218893Sdim 2094218893Sdim // Instruction operands. 2095218893Sdim bits<5> Vd; 2096218893Sdim bits<5> Vm; 2097218893Sdim bits<6> SIMM; 2098218893Sdim 2099218893Sdim let Inst{15-12} = Vd{3-0}; 2100218893Sdim let Inst{22} = Vd{4}; 2101218893Sdim let Inst{3-0} = Vm{3-0}; 2102218893Sdim let Inst{5} = Vm{4}; 2103218893Sdim let Inst{21-16} = SIMM{5-0}; 2104194710Sed} 2105194710Sed 2106194710Sed// NEON 3 vector register format. 2107221345Sdim 2108223017Sdimclass N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2109223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2110223017Sdim string opc, string dt, string asm, string cstr, 2111223017Sdim list<dag> pattern> 2112206083Srdivacky : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2113212904Sdim let Inst{24} = op24; 2114212904Sdim let Inst{23} = op23; 2115194710Sed let Inst{21-20} = op21_20; 2116212904Sdim let Inst{11-8} = op11_8; 2117212904Sdim let Inst{6} = op6; 2118212904Sdim let Inst{4} = op4; 2119221345Sdim} 2120218893Sdim 2121221345Sdimclass N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, 2122221345Sdim dag oops, dag iops, Format f, InstrItinClass itin, 2123221345Sdim string opc, string dt, string asm, string cstr, list<dag> pattern> 2124221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2125221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2126218893Sdim // Instruction operands. 2127218893Sdim bits<5> Vd; 2128218893Sdim bits<5> Vn; 2129218893Sdim bits<5> Vm; 2130218893Sdim 2131218893Sdim let Inst{15-12} = Vd{3-0}; 2132218893Sdim let Inst{22} = Vd{4}; 2133218893Sdim let Inst{19-16} = Vn{3-0}; 2134218893Sdim let Inst{7} = Vn{4}; 2135218893Sdim let Inst{3-0} = Vm{3-0}; 2136218893Sdim let Inst{5} = Vm{4}; 2137194710Sed} 2138194710Sed 2139261991Sdimclass N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2140261991Sdim bit op4, dag oops, dag iops,Format f, InstrItinClass itin, 2141276479Sdim string OpcodeStr, string Dt, list<dag> pattern> 2142261991Sdim : NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr, 2143261991Sdim Dt, "$Vd, $Vn, $Vm", "", pattern> { 2144261991Sdim bits<5> Vd; 2145261991Sdim bits<5> Vn; 2146261991Sdim bits<5> Vm; 2147261991Sdim 2148261991Sdim // Encode instruction operands 2149261991Sdim let Inst{22} = Vd{4}; 2150261991Sdim let Inst{15-12} = Vd{3-0}; 2151261991Sdim let Inst{19-16} = Vn{3-0}; 2152261991Sdim let Inst{7} = Vn{4}; 2153261991Sdim let Inst{5} = Vm{4}; 2154261991Sdim let Inst{3-0} = Vm{3-0}; 2155261991Sdim 2156261991Sdim // Encode constant bits 2157261991Sdim let Inst{27-23} = op27_23; 2158261991Sdim let Inst{21-20} = op21_20; 2159261991Sdim let Inst{11-8} = op11_8; 2160261991Sdim let Inst{6} = op6; 2161261991Sdim let Inst{4} = op4; 2162261991Sdim} 2163261991Sdim 2164223017Sdimclass N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2165223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2166223017Sdim string opc, string dt, string asm, string cstr, 2167223017Sdim list<dag> pattern> 2168221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2169221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2170221345Sdim 2171221345Sdim // Instruction operands. 2172221345Sdim bits<5> Vd; 2173221345Sdim bits<5> Vn; 2174221345Sdim bits<5> Vm; 2175221345Sdim bit lane; 2176221345Sdim 2177221345Sdim let Inst{15-12} = Vd{3-0}; 2178221345Sdim let Inst{22} = Vd{4}; 2179221345Sdim let Inst{19-16} = Vn{3-0}; 2180221345Sdim let Inst{7} = Vn{4}; 2181221345Sdim let Inst{3-0} = Vm{3-0}; 2182221345Sdim let Inst{5} = lane; 2183221345Sdim} 2184221345Sdim 2185223017Sdimclass N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2186223017Sdim bit op4, dag oops, dag iops, Format f, InstrItinClass itin, 2187223017Sdim string opc, string dt, string asm, string cstr, 2188223017Sdim list<dag> pattern> 2189221345Sdim : N3VCommon<op24, op23, op21_20, op11_8, op6, op4, 2190221345Sdim oops, iops, f, itin, opc, dt, asm, cstr, pattern> { 2191221345Sdim 2192221345Sdim // Instruction operands. 2193221345Sdim bits<5> Vd; 2194221345Sdim bits<5> Vn; 2195221345Sdim bits<5> Vm; 2196221345Sdim bits<2> lane; 2197221345Sdim 2198221345Sdim let Inst{15-12} = Vd{3-0}; 2199221345Sdim let Inst{22} = Vd{4}; 2200221345Sdim let Inst{19-16} = Vn{3-0}; 2201221345Sdim let Inst{7} = Vn{4}; 2202221345Sdim let Inst{2-0} = Vm{2-0}; 2203221345Sdim let Inst{5} = lane{1}; 2204221345Sdim let Inst{3} = lane{0}; 2205221345Sdim} 2206221345Sdim 2207206083Srdivacky// Same as N3V except it doesn't have a data type suffix. 2208206083Srdivackyclass N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, 2209206083Srdivacky bit op4, 2210206083Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2211206083Srdivacky string opc, string asm, string cstr, list<dag> pattern> 2212206083Srdivacky : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> { 2213212904Sdim let Inst{24} = op24; 2214212904Sdim let Inst{23} = op23; 2215198396Srdivacky let Inst{21-20} = op21_20; 2216212904Sdim let Inst{11-8} = op11_8; 2217212904Sdim let Inst{6} = op6; 2218212904Sdim let Inst{4} = op4; 2219218893Sdim 2220218893Sdim // Instruction operands. 2221218893Sdim bits<5> Vd; 2222218893Sdim bits<5> Vn; 2223218893Sdim bits<5> Vm; 2224218893Sdim 2225218893Sdim let Inst{15-12} = Vd{3-0}; 2226218893Sdim let Inst{22} = Vd{4}; 2227218893Sdim let Inst{19-16} = Vn{3-0}; 2228218893Sdim let Inst{7} = Vn{4}; 2229218893Sdim let Inst{3-0} = Vm{3-0}; 2230218893Sdim let Inst{5} = Vm{4}; 2231198396Srdivacky} 2232198396Srdivacky 2233194710Sed// NEON VMOVs between scalar and core registers. 2234194710Sedclass NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2235198090Srdivacky dag oops, dag iops, Format f, InstrItinClass itin, 2236199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2237224145Sdim : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain, 2238206083Srdivacky "", itin> { 2239194710Sed let Inst{27-20} = opcod1; 2240212904Sdim let Inst{11-8} = opcod2; 2241212904Sdim let Inst{6-5} = opcod3; 2242212904Sdim let Inst{4} = 1; 2243221345Sdim // A8.6.303, A8.6.328, A8.6.329 2244221345Sdim let Inst{3-0} = 0b0000; 2245199989Srdivacky 2246199989Srdivacky let OutOperandList = oops; 2247205407Srdivacky let InOperandList = !con(iops, (ins pred:$p)); 2248218893Sdim let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); 2249199989Srdivacky let Pattern = pattern; 2250194710Sed list<Predicate> Predicates = [HasNEON]; 2251218893Sdim 2252218893Sdim let PostEncoderMethod = "NEONThumb2DupPostEncoder"; 2253226633Sdim let DecoderNamespace = "NEONDup"; 2254218893Sdim 2255218893Sdim bits<5> V; 2256218893Sdim bits<4> R; 2257218893Sdim bits<4> p; 2258218893Sdim bits<4> lane; 2259218893Sdim 2260218893Sdim let Inst{31-28} = p{3-0}; 2261218893Sdim let Inst{7} = V{4}; 2262218893Sdim let Inst{19-16} = V{3-0}; 2263218893Sdim let Inst{15-12} = R{3-0}; 2264194710Sed} 2265194710Sedclass NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2266198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2267199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2268210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin, 2269199989Srdivacky opc, dt, asm, pattern>; 2270194710Sedclass NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2271198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2272199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2273210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin, 2274199989Srdivacky opc, dt, asm, pattern>; 2275194710Sedclass NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3, 2276198090Srdivacky dag oops, dag iops, InstrItinClass itin, 2277199989Srdivacky string opc, string dt, string asm, list<dag> pattern> 2278210299Sed : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin, 2279199989Srdivacky opc, dt, asm, pattern>; 2280198090Srdivacky 2281206083Srdivacky// Vector Duplicate Lane (from scalar to all elements) 2282206083Srdivackyclass NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops, 2283206083Srdivacky InstrItinClass itin, string opc, string dt, string asm, 2284206083Srdivacky list<dag> pattern> 2285206083Srdivacky : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> { 2286206083Srdivacky let Inst{24-23} = 0b11; 2287206083Srdivacky let Inst{21-20} = 0b11; 2288206083Srdivacky let Inst{19-16} = op19_16; 2289212904Sdim let Inst{11-7} = 0b11000; 2290212904Sdim let Inst{6} = op6; 2291212904Sdim let Inst{4} = 0; 2292218893Sdim 2293218893Sdim bits<5> Vd; 2294218893Sdim bits<5> Vm; 2295218893Sdim 2296218893Sdim let Inst{22} = Vd{4}; 2297218893Sdim let Inst{15-12} = Vd{3-0}; 2298218893Sdim let Inst{5} = Vm{4}; 2299218893Sdim let Inst{3-0} = Vm{3-0}; 2300206083Srdivacky} 2301206083Srdivacky 2302198090Srdivacky// NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON 2303198090Srdivacky// for single-precision FP. 2304198090Srdivackyclass NEONFPPat<dag pattern, dag result> : Pat<pattern, result> { 2305198090Srdivacky list<Predicate> Predicates = [HasNEON,UseNEONForFP]; 2306198090Srdivacky} 2307234353Sdim 2308234353Sdim// VFP/NEON Instruction aliases for type suffices. 2309234353Sdimclass VFPDataTypeInstAlias<string opc, string dt, string asm, dag Result> : 2310234353Sdim InstAlias<!strconcat(opc, dt, "\t", asm), Result>, Requires<[HasVFP2]>; 2311234353Sdim 2312234353Sdimmulticlass VFPDTAnyInstAlias<string opc, string asm, dag Result> { 2313234353Sdim def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; 2314234353Sdim def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; 2315234353Sdim def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; 2316234353Sdim def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; 2317234353Sdim} 2318234353Sdim 2319234353Sdimmulticlass NEONDTAnyInstAlias<string opc, string asm, dag Result> { 2320234353Sdim let Predicates = [HasNEON] in { 2321234353Sdim def : VFPDataTypeInstAlias<opc, ".8", asm, Result>; 2322234353Sdim def : VFPDataTypeInstAlias<opc, ".16", asm, Result>; 2323234353Sdim def : VFPDataTypeInstAlias<opc, ".32", asm, Result>; 2324234353Sdim def : VFPDataTypeInstAlias<opc, ".64", asm, Result>; 2325234353Sdim} 2326234353Sdim} 2327234353Sdim 2328234353Sdim// The same alias classes using AsmPseudo instead, for the more complex 2329234353Sdim// stuff in NEON that InstAlias can't quite handle. 2330234353Sdim// Note that we can't use anonymous defm references here like we can 2331234353Sdim// above, as we care about the ultimate instruction enum names generated, unlike 2332234353Sdim// for instalias defs. 2333234353Sdimclass NEONDataTypeAsmPseudoInst<string opc, string dt, string asm, dag iops> : 2334234353Sdim AsmPseudoInst<!strconcat(opc, dt, "\t", asm), iops>, Requires<[HasNEON]>; 2335234353Sdim 2336234353Sdim// Data type suffix token aliases. Implements Table A7-3 in the ARM ARM. 2337234353Sdimdef : TokenAlias<".s8", ".i8">; 2338234353Sdimdef : TokenAlias<".u8", ".i8">; 2339234353Sdimdef : TokenAlias<".s16", ".i16">; 2340234353Sdimdef : TokenAlias<".u16", ".i16">; 2341234353Sdimdef : TokenAlias<".s32", ".i32">; 2342234353Sdimdef : TokenAlias<".u32", ".i32">; 2343234353Sdimdef : TokenAlias<".s64", ".i64">; 2344234353Sdimdef : TokenAlias<".u64", ".i64">; 2345234353Sdim 2346234353Sdimdef : TokenAlias<".i8", ".8">; 2347234353Sdimdef : TokenAlias<".i16", ".16">; 2348234353Sdimdef : TokenAlias<".i32", ".32">; 2349234353Sdimdef : TokenAlias<".i64", ".64">; 2350234353Sdim 2351234353Sdimdef : TokenAlias<".p8", ".8">; 2352234353Sdimdef : TokenAlias<".p16", ".16">; 2353234353Sdim 2354234353Sdimdef : TokenAlias<".f32", ".32">; 2355234353Sdimdef : TokenAlias<".f64", ".64">; 2356234353Sdimdef : TokenAlias<".f", ".f32">; 2357234353Sdimdef : TokenAlias<".d", ".f64">; 2358