Home | History | Annotate | Download | only in ARM
      1 //===- ARMInstrFormats.td - ARM Instruction Formats ----------*- tablegen -*-=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 //===----------------------------------------------------------------------===//
     11 //
     12 // ARM Instruction Format Definitions.
     13 //
     14 
     15 // Format specifies the encoding used by the instruction.  This is part of the
     16 // ad-hoc solution used to emit machine instruction encodings by our machine
     17 // code emitter.
     18 class Format<bits<6> val> {
     19   bits<6> Value = val;
     20 }
     21 
     22 def Pseudo        : Format<0>;
     23 def MulFrm        : Format<1>;
     24 def BrFrm         : Format<2>;
     25 def BrMiscFrm     : Format<3>;
     26 
     27 def DPFrm         : Format<4>;
     28 def DPSoRegRegFrm    : Format<5>;
     29 
     30 def LdFrm         : Format<6>;
     31 def StFrm         : Format<7>;
     32 def LdMiscFrm     : Format<8>;
     33 def StMiscFrm     : Format<9>;
     34 def LdStMulFrm    : Format<10>;
     35 
     36 def LdStExFrm     : Format<11>;
     37 
     38 def ArithMiscFrm  : Format<12>;
     39 def SatFrm        : Format<13>;
     40 def ExtFrm        : Format<14>;
     41 
     42 def VFPUnaryFrm   : Format<15>;
     43 def VFPBinaryFrm  : Format<16>;
     44 def VFPConv1Frm   : Format<17>;
     45 def VFPConv2Frm   : Format<18>;
     46 def VFPConv3Frm   : Format<19>;
     47 def VFPConv4Frm   : Format<20>;
     48 def VFPConv5Frm   : Format<21>;
     49 def VFPLdStFrm    : Format<22>;
     50 def VFPLdStMulFrm : Format<23>;
     51 def VFPMiscFrm    : Format<24>;
     52 
     53 def ThumbFrm      : Format<25>;
     54 def MiscFrm       : Format<26>;
     55 
     56 def NGetLnFrm     : Format<27>;
     57 def NSetLnFrm     : Format<28>;
     58 def NDupFrm       : Format<29>;
     59 def NLdStFrm      : Format<30>;
     60 def N1RegModImmFrm: Format<31>;
     61 def N2RegFrm      : Format<32>;
     62 def NVCVTFrm      : Format<33>;
     63 def NVDupLnFrm    : Format<34>;
     64 def N2RegVShLFrm  : Format<35>;
     65 def N2RegVShRFrm  : Format<36>;
     66 def N3RegFrm      : Format<37>;
     67 def N3RegVShFrm   : Format<38>;
     68 def NVExtFrm      : Format<39>;
     69 def NVMulSLFrm    : Format<40>;
     70 def NVTBLFrm      : Format<41>;
     71 def DPSoRegImmFrm  : Format<42>;
     72 
     73 // Misc flags.
     74 
     75 // The instruction has an Rn register operand.
     76 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
     77 // it doesn't have a Rn operand.
     78 class UnaryDP    { bit isUnaryDataProc = 1; }
     79 
     80 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
     81 // a 16-bit Thumb instruction if certain conditions are met.
     82 class Xform16Bit { bit canXformTo16Bit = 1; }
     83 
     84 //===----------------------------------------------------------------------===//
     85 // ARM Instruction flags.  These need to match ARMBaseInstrInfo.h.
     86 //
     87 
     88 // FIXME: Once the JIT is MC-ized, these can go away.
     89 // Addressing mode.
     90 class AddrMode<bits<5> val> {
     91   bits<5> Value = val;
     92 }
     93 def AddrModeNone    : AddrMode<0>;
     94 def AddrMode1       : AddrMode<1>;
     95 def AddrMode2       : AddrMode<2>;
     96 def AddrMode3       : AddrMode<3>;
     97 def AddrMode4       : AddrMode<4>;
     98 def AddrMode5       : AddrMode<5>;
     99 def AddrMode6       : AddrMode<6>;
    100 def AddrModeT1_1    : AddrMode<7>;
    101 def AddrModeT1_2    : AddrMode<8>;
    102 def AddrModeT1_4    : AddrMode<9>;
    103 def AddrModeT1_s    : AddrMode<10>;
    104 def AddrModeT2_i12  : AddrMode<11>;
    105 def AddrModeT2_i8   : AddrMode<12>;
    106 def AddrModeT2_so   : AddrMode<13>;
    107 def AddrModeT2_pc   : AddrMode<14>;
    108 def AddrModeT2_i8s4 : AddrMode<15>;
    109 def AddrMode_i12    : AddrMode<16>;
    110 
    111 // Load / store index mode.
    112 class IndexMode<bits<2> val> {
    113   bits<2> Value = val;
    114 }
    115 def IndexModeNone : IndexMode<0>;
    116 def IndexModePre  : IndexMode<1>;
    117 def IndexModePost : IndexMode<2>;
    118 def IndexModeUpd  : IndexMode<3>;
    119 
    120 // Instruction execution domain.
    121 class Domain<bits<3> val> {
    122   bits<3> Value = val;
    123 }
    124 def GenericDomain : Domain<0>;
    125 def VFPDomain     : Domain<1>; // Instructions in VFP domain only
    126 def NeonDomain    : Domain<2>; // Instructions in Neon domain only
    127 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
    128 def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8
    129 
    130 //===----------------------------------------------------------------------===//
    131 // ARM special operands.
    132 //
    133 
    134 // ARM imod and iflag operands, used only by the CPS instruction.
    135 def imod_op : Operand<i32> {
    136   let PrintMethod = "printCPSIMod";
    137 }
    138 
    139 def ProcIFlagsOperand : AsmOperandClass {
    140   let Name = "ProcIFlags";
    141   let ParserMethod = "parseProcIFlagsOperand";
    142 }
    143 def iflags_op : Operand<i32> {
    144   let PrintMethod = "printCPSIFlag";
    145   let ParserMatchClass = ProcIFlagsOperand;
    146 }
    147 
    148 // ARM Predicate operand. Default to 14 = always (AL). Second part is CC
    149 // register whose default is 0 (no register).
    150 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
    151 def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
    152                                      (ops (i32 14), (i32 zero_reg))> {
    153   let PrintMethod = "printPredicateOperand";
    154   let ParserMatchClass = CondCodeOperand;
    155   let DecoderMethod = "DecodePredicateOperand";
    156 }
    157 
    158 // Conditional code result for instructions whose 's' bit is set, e.g. subs.
    159 def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
    160 def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
    161   let EncoderMethod = "getCCOutOpValue";
    162   let PrintMethod = "printSBitModifierOperand";
    163   let ParserMatchClass = CCOutOperand;
    164   let DecoderMethod = "DecodeCCOutOperand";
    165 }
    166 
    167 // Same as cc_out except it defaults to setting CPSR.
    168 def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
    169   let EncoderMethod = "getCCOutOpValue";
    170   let PrintMethod = "printSBitModifierOperand";
    171   let ParserMatchClass = CCOutOperand;
    172   let DecoderMethod = "DecodeCCOutOperand";
    173 }
    174 
    175 // ARM special operands for disassembly only.
    176 //
    177 def SetEndAsmOperand : AsmOperandClass {
    178   let Name = "SetEndImm";
    179   let ParserMethod = "parseSetEndImm";
    180 }
    181 def setend_op : Operand<i32> {
    182   let PrintMethod = "printSetendOperand";
    183   let ParserMatchClass = SetEndAsmOperand;
    184 }
    185 
    186 def MSRMaskOperand : AsmOperandClass {
    187   let Name = "MSRMask";
    188   let ParserMethod = "parseMSRMaskOperand";
    189 }
    190 def msr_mask : Operand<i32> {
    191   let PrintMethod = "printMSRMaskOperand";
    192   let DecoderMethod = "DecodeMSRMask";
    193   let ParserMatchClass = MSRMaskOperand;
    194 }
    195 
    196 // Shift Right Immediate - A shift right immediate is encoded differently from
    197 // other shift immediates. The imm6 field is encoded like so:
    198 //
    199 //    Offset    Encoding
    200 //     8        imm6<5:3> = '001', 8 - <imm> is encoded in imm6<2:0>
    201 //     16       imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
    202 //     32       imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
    203 //     64       64 - <imm> is encoded in imm6<5:0>
    204 def shr_imm8  : Operand<i32> {
    205   let EncoderMethod = "getShiftRight8Imm";
    206   let DecoderMethod = "DecodeShiftRight8Imm";
    207 }
    208 def shr_imm16 : Operand<i32> {
    209   let EncoderMethod = "getShiftRight16Imm";
    210   let DecoderMethod = "DecodeShiftRight16Imm";
    211 }
    212 def shr_imm32 : Operand<i32> {
    213   let EncoderMethod = "getShiftRight32Imm";
    214   let DecoderMethod = "DecodeShiftRight32Imm";
    215 }
    216 def shr_imm64 : Operand<i32> {
    217   let EncoderMethod = "getShiftRight64Imm";
    218   let DecoderMethod = "DecodeShiftRight64Imm";
    219 }
    220 
    221 //===----------------------------------------------------------------------===//
    222 // ARM Assembler alias templates.
    223 //
    224 class ARMInstAlias<string Asm, dag Result, bit Emit = 0b1>
    225       : InstAlias<Asm, Result, Emit>, Requires<[IsARM]>;
    226 class  tInstAlias<string Asm, dag Result, bit Emit = 0b1>
    227       : InstAlias<Asm, Result, Emit>, Requires<[IsThumb]>;
    228 class t2InstAlias<string Asm, dag Result, bit Emit = 0b1>
    229       : InstAlias<Asm, Result, Emit>, Requires<[IsThumb2]>;
    230 class VFP2InstAlias<string Asm, dag Result, bit Emit = 0b1>
    231       : InstAlias<Asm, Result, Emit>, Requires<[HasVFP2]>;
    232 class VFP3InstAlias<string Asm, dag Result, bit Emit = 0b1>
    233       : InstAlias<Asm, Result, Emit>, Requires<[HasVFP3]>;
    234 
    235 //===----------------------------------------------------------------------===//
    236 // ARM Instruction templates.
    237 //
    238 
    239 
    240 class InstTemplate<AddrMode am, int sz, IndexMode im,
    241                    Format f, Domain d, string cstr, InstrItinClass itin>
    242   : Instruction {
    243   let Namespace = "ARM";
    244 
    245   AddrMode AM = am;
    246   int Size = sz;
    247   IndexMode IM = im;
    248   bits<2> IndexModeBits = IM.Value;
    249   Format F = f;
    250   bits<6> Form = F.Value;
    251   Domain D = d;
    252   bit isUnaryDataProc = 0;
    253   bit canXformTo16Bit = 0;
    254   // The instruction is a 16-bit flag setting Thumb instruction. Used
    255   // by the parser to determine whether to require the 'S' suffix on the
    256   // mnemonic (when not in an IT block) or preclude it (when in an IT block).
    257   bit thumbArithFlagSetting = 0;
    258 
    259   // If this is a pseudo instruction, mark it isCodeGenOnly.
    260   let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
    261 
    262   // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
    263   let TSFlags{4-0}   = AM.Value;
    264   let TSFlags{6-5}   = IndexModeBits;
    265   let TSFlags{12-7} = Form;
    266   let TSFlags{13}    = isUnaryDataProc;
    267   let TSFlags{14}    = canXformTo16Bit;
    268   let TSFlags{17-15} = D.Value;
    269   let TSFlags{18}    = thumbArithFlagSetting;
    270 
    271   let Constraints = cstr;
    272   let Itinerary = itin;
    273 }
    274 
    275 class Encoding {
    276   field bits<32> Inst;
    277 }
    278 
    279 class InstARM<AddrMode am, int sz, IndexMode im,
    280               Format f, Domain d, string cstr, InstrItinClass itin>
    281   : InstTemplate<am, sz, im, f, d, cstr, itin>, Encoding {
    282   let DecoderNamespace = "ARM";
    283 }
    284 
    285 // This Encoding-less class is used by Thumb1 to specify the encoding bits later
    286 // on by adding flavors to specific instructions.
    287 class InstThumb<AddrMode am, int sz, IndexMode im,
    288                 Format f, Domain d, string cstr, InstrItinClass itin>
    289   : InstTemplate<am, sz, im, f, d, cstr, itin> {
    290   let DecoderNamespace = "Thumb";
    291 }
    292 
    293 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>
    294   : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo,
    295                  GenericDomain, "", itin> {
    296   let OutOperandList = oops;
    297   let InOperandList = iops;
    298   let Pattern = pattern;
    299   let isCodeGenOnly = 1;
    300   let isPseudo = 1;
    301 }
    302 
    303 // PseudoInst that's ARM-mode only.
    304 class ARMPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
    305                     list<dag> pattern>
    306   : PseudoInst<oops, iops, itin, pattern> {
    307   let Size = sz;
    308   list<Predicate> Predicates = [IsARM];
    309 }
    310 
    311 // PseudoInst that's Thumb-mode only.
    312 class tPseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
    313                     list<dag> pattern>
    314   : PseudoInst<oops, iops, itin, pattern> {
    315   let Size = sz;
    316   list<Predicate> Predicates = [IsThumb];
    317 }
    318 
    319 // PseudoInst that's Thumb2-mode only.
    320 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,
    321                     list<dag> pattern>
    322   : PseudoInst<oops, iops, itin, pattern> {
    323   let Size = sz;
    324   list<Predicate> Predicates = [IsThumb2];
    325 }
    326 
    327 class ARMPseudoExpand<dag oops, dag iops, int sz,
    328                       InstrItinClass itin, list<dag> pattern,
    329                       dag Result>
    330   : ARMPseudoInst<oops, iops, sz, itin, pattern>,
    331     PseudoInstExpansion<Result>;
    332 
    333 class tPseudoExpand<dag oops, dag iops, int sz,
    334                     InstrItinClass itin, list<dag> pattern,
    335                     dag Result>
    336   : tPseudoInst<oops, iops, sz, itin, pattern>,
    337     PseudoInstExpansion<Result>;
    338 
    339 class t2PseudoExpand<dag oops, dag iops, int sz,
    340                     InstrItinClass itin, list<dag> pattern,
    341                     dag Result>
    342   : t2PseudoInst<oops, iops, sz, itin, pattern>,
    343     PseudoInstExpansion<Result>;
    344 
    345 // Almost all ARM instructions are predicable.
    346 class I<dag oops, dag iops, AddrMode am, int sz,
    347         IndexMode im, Format f, InstrItinClass itin,
    348         string opc, string asm, string cstr,
    349         list<dag> pattern>
    350   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
    351   bits<4> p;
    352   let Inst{31-28} = p;
    353   let OutOperandList = oops;
    354   let InOperandList = !con(iops, (ins pred:$p));
    355   let AsmString = !strconcat(opc, "${p}", asm);
    356   let Pattern = pattern;
    357   list<Predicate> Predicates = [IsARM];
    358 }
    359 
    360 // A few are not predicable
    361 class InoP<dag oops, dag iops, AddrMode am, int sz,
    362            IndexMode im, Format f, InstrItinClass itin,
    363            string opc, string asm, string cstr,
    364            list<dag> pattern>
    365   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
    366   let OutOperandList = oops;
    367   let InOperandList = iops;
    368   let AsmString = !strconcat(opc, asm);
    369   let Pattern = pattern;
    370   let isPredicable = 0;
    371   list<Predicate> Predicates = [IsARM];
    372 }
    373 
    374 // Same as I except it can optionally modify CPSR. Note it's modeled as an input
    375 // operand since by default it's a zero register. It will become an implicit def
    376 // once it's "flipped".
    377 class sI<dag oops, dag iops, AddrMode am, int sz,
    378          IndexMode im, Format f, InstrItinClass itin,
    379          string opc, string asm, string cstr,
    380          list<dag> pattern>
    381   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
    382   bits<4> p; // Predicate operand
    383   bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
    384   let Inst{31-28} = p;
    385   let Inst{20} = s;
    386 
    387   let OutOperandList = oops;
    388   let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
    389   let AsmString = !strconcat(opc, "${s}${p}", asm);
    390   let Pattern = pattern;
    391   list<Predicate> Predicates = [IsARM];
    392 }
    393 
    394 // Special cases
    395 class XI<dag oops, dag iops, AddrMode am, int sz,
    396          IndexMode im, Format f, InstrItinClass itin,
    397          string asm, string cstr, list<dag> pattern>
    398   : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
    399   let OutOperandList = oops;
    400   let InOperandList = iops;
    401   let AsmString = asm;
    402   let Pattern = pattern;
    403   list<Predicate> Predicates = [IsARM];
    404 }
    405 
    406 class AI<dag oops, dag iops, Format f, InstrItinClass itin,
    407          string opc, string asm, list<dag> pattern>
    408   : I<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
    409       opc, asm, "", pattern>;
    410 class AsI<dag oops, dag iops, Format f, InstrItinClass itin,
    411           string opc, string asm, list<dag> pattern>
    412   : sI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
    413        opc, asm, "", pattern>;
    414 class AXI<dag oops, dag iops, Format f, InstrItinClass itin,
    415           string asm, list<dag> pattern>
    416   : XI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
    417        asm, "", pattern>;
    418 class AInoP<dag oops, dag iops, Format f, InstrItinClass itin,
    419             string opc, string asm, list<dag> pattern>
    420   : InoP<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
    421          opc, asm, "", pattern>;
    422 
    423 // Ctrl flow instructions
    424 class ABI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
    425           string opc, string asm, list<dag> pattern>
    426   : I<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
    427       opc, asm, "", pattern> {
    428   let Inst{27-24} = opcod;
    429 }
    430 class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
    431            string asm, list<dag> pattern>
    432   : XI<oops, iops, AddrModeNone, 4, IndexModeNone, BrFrm, itin,
    433        asm, "", pattern> {
    434   let Inst{27-24} = opcod;
    435 }
    436 
    437 // BR_JT instructions
    438 class JTI<dag oops, dag iops, InstrItinClass itin,
    439           string asm, list<dag> pattern>
    440   : XI<oops, iops, AddrModeNone, 0, IndexModeNone, BrMiscFrm, itin,
    441        asm, "", pattern>;
    442 
    443 // Atomic load/store instructions
    444 class AIldrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
    445               string opc, string asm, list<dag> pattern>
    446   : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
    447       opc, asm, "", pattern> {
    448   bits<4> Rt;
    449   bits<4> addr;
    450   let Inst{27-23} = 0b00011;
    451   let Inst{22-21} = opcod;
    452   let Inst{20}    = 1;
    453   let Inst{19-16} = addr;
    454   let Inst{15-12} = Rt;
    455   let Inst{11-0}  = 0b111110011111;
    456 }
    457 class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
    458               string opc, string asm, list<dag> pattern>
    459   : I<oops, iops, AddrModeNone, 4, IndexModeNone, LdStExFrm, itin,
    460       opc, asm, "", pattern> {
    461   bits<4> Rd;
    462   bits<4> Rt;
    463   bits<4> addr;
    464   let Inst{27-23} = 0b00011;
    465   let Inst{22-21} = opcod;
    466   let Inst{20}    = 0;
    467   let Inst{19-16} = addr;
    468   let Inst{15-12} = Rd;
    469   let Inst{11-4}  = 0b11111001;
    470   let Inst{3-0}   = Rt;
    471 }
    472 class AIswp<bit b, dag oops, dag iops, string opc, list<dag> pattern>
    473   : AI<oops, iops, MiscFrm, NoItinerary, opc, "\t$Rt, $Rt2, $addr", pattern> {
    474   bits<4> Rt;
    475   bits<4> Rt2;
    476   bits<4> addr;
    477   let Inst{27-23} = 0b00010;
    478   let Inst{22} = b;
    479   let Inst{21-20} = 0b00;
    480   let Inst{19-16} = addr;
    481   let Inst{15-12} = Rt;
    482   let Inst{11-4} = 0b00001001;
    483   let Inst{3-0} = Rt2;
    484 }
    485 
    486 // addrmode1 instructions
    487 class AI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
    488           string opc, string asm, list<dag> pattern>
    489   : I<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
    490       opc, asm, "", pattern> {
    491   let Inst{24-21} = opcod;
    492   let Inst{27-26} = 0b00;
    493 }
    494 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
    495            string opc, string asm, list<dag> pattern>
    496   : sI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
    497        opc, asm, "", pattern> {
    498   let Inst{24-21} = opcod;
    499   let Inst{27-26} = 0b00;
    500 }
    501 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, InstrItinClass itin,
    502            string asm, list<dag> pattern>
    503   : XI<oops, iops, AddrMode1, 4, IndexModeNone, f, itin,
    504        asm, "", pattern> {
    505   let Inst{24-21} = opcod;
    506   let Inst{27-26} = 0b00;
    507 }
    508 
    509 // loads
    510 
    511 // LDR/LDRB/STR/STRB/...
    512 class AI2ldst<bits<3> op, bit isLd, bit isByte, dag oops, dag iops, AddrMode am,
    513              Format f, InstrItinClass itin, string opc, string asm,
    514              list<dag> pattern>
    515   : I<oops, iops, am, 4, IndexModeNone, f, itin, opc, asm,
    516       "", pattern> {
    517   let Inst{27-25} = op;
    518   let Inst{24} = 1;  // 24 == P
    519   // 23 == U
    520   let Inst{22} = isByte;
    521   let Inst{21} = 0;  // 21 == W
    522   let Inst{20} = isLd;
    523 }
    524 // Indexed load/stores
    525 class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
    526                 IndexMode im, Format f, InstrItinClass itin, string opc,
    527                 string asm, string cstr, list<dag> pattern>
    528   : I<oops, iops, AddrMode2, 4, im, f, itin,
    529       opc, asm, cstr, pattern> {
    530   bits<4> Rt;
    531   let Inst{27-26} = 0b01;
    532   let Inst{24}    = isPre; // P bit
    533   let Inst{22}    = isByte; // B bit
    534   let Inst{21}    = isPre; // W bit
    535   let Inst{20}    = isLd; // L bit
    536   let Inst{15-12} = Rt;
    537 }
    538 class AI2stridx_reg<bit isByte, bit isPre, dag oops, dag iops,
    539                 IndexMode im, Format f, InstrItinClass itin, string opc,
    540                 string asm, string cstr, list<dag> pattern>
    541   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
    542                pattern> {
    543   // AM2 store w/ two operands: (GPR, am2offset)
    544   // {12}     isAdd
    545   // {11-0}   imm12/Rm
    546   bits<14> offset;
    547   bits<4> Rn;
    548   let Inst{25} = 1;
    549   let Inst{23} = offset{12};
    550   let Inst{19-16} = Rn;
    551   let Inst{11-5} = offset{11-5};
    552   let Inst{4} = 0;
    553   let Inst{3-0} = offset{3-0};
    554 }
    555 
    556 class AI2stridx_imm<bit isByte, bit isPre, dag oops, dag iops,
    557                 IndexMode im, Format f, InstrItinClass itin, string opc,
    558                 string asm, string cstr, list<dag> pattern>
    559   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
    560                pattern> {
    561   // AM2 store w/ two operands: (GPR, am2offset)
    562   // {12}     isAdd
    563   // {11-0}   imm12/Rm
    564   bits<14> offset;
    565   bits<4> Rn;
    566   let Inst{25} = 0;
    567   let Inst{23} = offset{12};
    568   let Inst{19-16} = Rn;
    569   let Inst{11-0} = offset{11-0};
    570 }
    571 
    572 
    573 // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB
    574 // but for now use this class for STRT and STRBT.
    575 class AI2stridxT<bit isByte, bit isPre, dag oops, dag iops,
    576                 IndexMode im, Format f, InstrItinClass itin, string opc,
    577                 string asm, string cstr, list<dag> pattern>
    578   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
    579                pattern> {
    580   // AM2 store w/ two operands: (GPR, am2offset)
    581   // {17-14}  Rn
    582   // {13}     1 == Rm, 0 == imm12
    583   // {12}     isAdd
    584   // {11-0}   imm12/Rm
    585   bits<18> addr;
    586   let Inst{25} = addr{13};
    587   let Inst{23} = addr{12};
    588   let Inst{19-16} = addr{17-14};
    589   let Inst{11-0} = addr{11-0};
    590 }
    591 
    592 // addrmode3 instructions
    593 class AI3ld<bits<4> op, bit op20, dag oops, dag iops, Format f,
    594             InstrItinClass itin, string opc, string asm, list<dag> pattern>
    595   : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
    596       opc, asm, "", pattern> {
    597   bits<14> addr;
    598   bits<4> Rt;
    599   let Inst{27-25} = 0b000;
    600   let Inst{24}    = 1;            // P bit
    601   let Inst{23}    = addr{8};      // U bit
    602   let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
    603   let Inst{21}    = 0;            // W bit
    604   let Inst{20}    = op20;         // L bit
    605   let Inst{19-16} = addr{12-9};   // Rn
    606   let Inst{15-12} = Rt;           // Rt
    607   let Inst{11-8}  = addr{7-4};    // imm7_4/zero
    608   let Inst{7-4}   = op;
    609   let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
    610 
    611   let DecoderMethod = "DecodeAddrMode3Instruction";
    612 }
    613 
    614 class AI3ldstidx<bits<4> op, bit op20, bit isPre, dag oops, dag iops,
    615                 IndexMode im, Format f, InstrItinClass itin, string opc,
    616                 string asm, string cstr, list<dag> pattern>
    617   : I<oops, iops, AddrMode3, 4, im, f, itin,
    618       opc, asm, cstr, pattern> {
    619   bits<4> Rt;
    620   let Inst{27-25} = 0b000;
    621   let Inst{24}    = isPre;        // P bit
    622   let Inst{21}    = isPre;        // W bit
    623   let Inst{20}    = op20;         // L bit
    624   let Inst{15-12} = Rt;           // Rt
    625   let Inst{7-4}   = op;
    626 }
    627 
    628 // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB
    629 // but for now use this class for LDRSBT, LDRHT, LDSHT.
    630 class AI3ldstidxT<bits<4> op, bit isLoad, dag oops, dag iops,
    631                   IndexMode im, Format f, InstrItinClass itin, string opc,
    632                   string asm, string cstr, list<dag> pattern>
    633   : I<oops, iops, AddrMode3, 4, im, f, itin, opc, asm, cstr, pattern> {
    634   // {13}     1 == imm8, 0 == Rm
    635   // {12-9}   Rn
    636   // {8}      isAdd
    637   // {7-4}    imm7_4/zero
    638   // {3-0}    imm3_0/Rm
    639   bits<4> addr;
    640   bits<4> Rt;
    641   let Inst{27-25} = 0b000;
    642   let Inst{24}    = 0;            // P bit
    643   let Inst{21}    = 1;
    644   let Inst{20}    = isLoad;       // L bit
    645   let Inst{19-16} = addr;         // Rn
    646   let Inst{15-12} = Rt;           // Rt
    647   let Inst{7-4}   = op;
    648 }
    649 
    650 // stores
    651 class AI3str<bits<4> op, dag oops, dag iops, Format f, InstrItinClass itin,
    652              string opc, string asm, list<dag> pattern>
    653   : I<oops, iops, AddrMode3, 4, IndexModeNone, f, itin,
    654       opc, asm, "", pattern> {
    655   bits<14> addr;
    656   bits<4> Rt;
    657   let Inst{27-25} = 0b000;
    658   let Inst{24}    = 1;            // P bit
    659   let Inst{23}    = addr{8};      // U bit
    660   let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
    661   let Inst{21}    = 0;            // W bit
    662   let Inst{20}    = 0;            // L bit
    663   let Inst{19-16} = addr{12-9};   // Rn
    664   let Inst{15-12} = Rt;           // Rt
    665   let Inst{11-8}  = addr{7-4};    // imm7_4/zero
    666   let Inst{7-4}   = op;
    667   let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
    668   let DecoderMethod = "DecodeAddrMode3Instruction";
    669 }
    670 
    671 // addrmode4 instructions
    672 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
    673            string asm, string cstr, list<dag> pattern>
    674   : XI<oops, iops, AddrMode4, 4, im, f, itin, asm, cstr, pattern> {
    675   bits<4>  p;
    676   bits<16> regs;
    677   bits<4>  Rn;
    678   let Inst{31-28} = p;
    679   let Inst{27-25} = 0b100;
    680   let Inst{22}    = 0; // S bit
    681   let Inst{19-16} = Rn;
    682   let Inst{15-0}  = regs;
    683 }
    684 
    685 // Unsigned multiply, multiply-accumulate instructions.
    686 class AMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
    687              string opc, string asm, list<dag> pattern>
    688   : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
    689       opc, asm, "", pattern> {
    690   let Inst{7-4}   = 0b1001;
    691   let Inst{20}    = 0; // S bit
    692   let Inst{27-21} = opcod;
    693 }
    694 class AsMul1I<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
    695               string opc, string asm, list<dag> pattern>
    696   : sI<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
    697        opc, asm, "", pattern> {
    698   let Inst{7-4}   = 0b1001;
    699   let Inst{27-21} = opcod;
    700 }
    701 
    702 // Most significant word multiply
    703 class AMul2I<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
    704              InstrItinClass itin, string opc, string asm, list<dag> pattern>
    705   : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
    706       opc, asm, "", pattern> {
    707   bits<4> Rd;
    708   bits<4> Rn;
    709   bits<4> Rm;
    710   let Inst{7-4}   = opc7_4;
    711   let Inst{20}    = 1;
    712   let Inst{27-21} = opcod;
    713   let Inst{19-16} = Rd;
    714   let Inst{11-8}  = Rm;
    715   let Inst{3-0}   = Rn;
    716 }
    717 // MSW multiple w/ Ra operand
    718 class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
    719               InstrItinClass itin, string opc, string asm, list<dag> pattern>
    720   : AMul2I<opcod, opc7_4, oops, iops, itin, opc, asm, pattern> {
    721   bits<4> Ra;
    722   let Inst{15-12} = Ra;
    723 }
    724 
    725 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
    726 class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
    727               InstrItinClass itin, string opc, string asm, list<dag> pattern>
    728   : I<oops, iops, AddrModeNone, 4, IndexModeNone, MulFrm, itin,
    729       opc, asm, "", pattern> {
    730   bits<4> Rn;
    731   bits<4> Rm;
    732   let Inst{4}     = 0;
    733   let Inst{7}     = 1;
    734   let Inst{20}    = 0;
    735   let Inst{27-21} = opcod;
    736   let Inst{6-5}   = bit6_5;
    737   let Inst{11-8}  = Rm;
    738   let Inst{3-0}   = Rn;
    739 }
    740 class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
    741               InstrItinClass itin, string opc, string asm, list<dag> pattern>
    742   : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
    743   bits<4> Rd;
    744   let Inst{19-16} = Rd;
    745 }
    746 
    747 // AMulxyI with Ra operand
    748 class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
    749               InstrItinClass itin, string opc, string asm, list<dag> pattern>
    750   : AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
    751   bits<4> Ra;
    752   let Inst{15-12} = Ra;
    753 }
    754 // SMLAL*
    755 class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
    756               InstrItinClass itin, string opc, string asm, list<dag> pattern>
    757   : AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
    758   bits<4> RdLo;
    759   bits<4> RdHi;
    760   let Inst{19-16} = RdHi;
    761   let Inst{15-12} = RdLo;
    762 }
    763 
    764 // Extend instructions.
    765 class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin,
    766             string opc, string asm, list<dag> pattern>
    767   : I<oops, iops, AddrModeNone, 4, IndexModeNone, ExtFrm, itin,
    768       opc, asm, "", pattern> {
    769   // All AExtI instructions have Rd and Rm register operands.
    770   bits<4> Rd;
    771   bits<4> Rm;
    772   let Inst{15-12} = Rd;
    773   let Inst{3-0}   = Rm;
    774   let Inst{7-4}   = 0b0111;
    775   let Inst{9-8}   = 0b00;
    776   let Inst{27-20} = opcod;
    777 }
    778 
    779 // Misc Arithmetic instructions.
    780 class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
    781                InstrItinClass itin, string opc, string asm, list<dag> pattern>
    782   : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
    783       opc, asm, "", pattern> {
    784   bits<4> Rd;
    785   bits<4> Rm;
    786   let Inst{27-20} = opcod;
    787   let Inst{19-16} = 0b1111;
    788   let Inst{15-12} = Rd;
    789   let Inst{11-8}  = 0b1111;
    790   let Inst{7-4}   = opc7_4;
    791   let Inst{3-0}   = Rm;
    792 }
    793 
    794 // PKH instructions
    795 def PKHLSLAsmOperand : AsmOperandClass {
    796   let Name = "PKHLSLImm";
    797   let ParserMethod = "parsePKHLSLImm";
    798 }
    799 def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
    800   let PrintMethod = "printPKHLSLShiftImm";
    801   let ParserMatchClass = PKHLSLAsmOperand;
    802 }
    803 def PKHASRAsmOperand : AsmOperandClass {
    804   let Name = "PKHASRImm";
    805   let ParserMethod = "parsePKHASRImm";
    806 }
    807 def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
    808   let PrintMethod = "printPKHASRShiftImm";
    809   let ParserMatchClass = PKHASRAsmOperand;
    810 }
    811 
    812 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
    813             string opc, string asm, list<dag> pattern>
    814   : I<oops, iops, AddrModeNone, 4, IndexModeNone, ArithMiscFrm, itin,
    815       opc, asm, "", pattern> {
    816   bits<4> Rd;
    817   bits<4> Rn;
    818   bits<4> Rm;
    819   bits<5> sh;
    820   let Inst{27-20} = opcod;
    821   let Inst{19-16} = Rn;
    822   let Inst{15-12} = Rd;
    823   let Inst{11-7}  = sh;
    824   let Inst{6}     = tb;
    825   let Inst{5-4}   = 0b01;
    826   let Inst{3-0}   = Rm;
    827 }
    828 
    829 //===----------------------------------------------------------------------===//
    830 
    831 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
    832 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
    833   list<Predicate> Predicates = [IsARM];
    834 }
    835 class ARMV5TPat<dag pattern, dag result> : Pat<pattern, result> {
    836   list<Predicate> Predicates = [IsARM, HasV5T];
    837 }
    838 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
    839   list<Predicate> Predicates = [IsARM, HasV5TE];
    840 }
    841 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
    842   list<Predicate> Predicates = [IsARM, HasV6];
    843 }
    844 
    845 //===----------------------------------------------------------------------===//
    846 // Thumb Instruction Format Definitions.
    847 //
    848 
    849 class ThumbI<dag oops, dag iops, AddrMode am, int sz,
    850              InstrItinClass itin, string asm, string cstr, list<dag> pattern>
    851   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
    852   let OutOperandList = oops;
    853   let InOperandList = iops;
    854   let AsmString = asm;
    855   let Pattern = pattern;
    856   list<Predicate> Predicates = [IsThumb];
    857 }
    858 
    859 // TI - Thumb instruction.
    860 class TI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
    861   : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
    862 
    863 // Two-address instructions
    864 class TIt<dag oops, dag iops, InstrItinClass itin, string asm,
    865           list<dag> pattern>
    866   : ThumbI<oops, iops, AddrModeNone, 2, itin, asm, "$lhs = $dst",
    867            pattern>;
    868 
    869 // tBL, tBX 32-bit instructions
    870 class TIx2<bits<5> opcod1, bits<2> opcod2, bit opcod3,
    871            dag oops, dag iops, InstrItinClass itin, string asm,
    872            list<dag> pattern>
    873     : ThumbI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>,
    874       Encoding {
    875   let Inst{31-27} = opcod1;
    876   let Inst{15-14} = opcod2;
    877   let Inst{12}    = opcod3;
    878 }
    879 
    880 // BR_JT instructions
    881 class TJTI<dag oops, dag iops, InstrItinClass itin, string asm,
    882            list<dag> pattern>
    883   : ThumbI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
    884 
    885 // Thumb1 only
    886 class Thumb1I<dag oops, dag iops, AddrMode am, int sz,
    887               InstrItinClass itin, string asm, string cstr, list<dag> pattern>
    888   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
    889   let OutOperandList = oops;
    890   let InOperandList = iops;
    891   let AsmString = asm;
    892   let Pattern = pattern;
    893   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
    894 }
    895 
    896 class T1I<dag oops, dag iops, InstrItinClass itin,
    897           string asm, list<dag> pattern>
    898   : Thumb1I<oops, iops, AddrModeNone, 2, itin, asm, "", pattern>;
    899 class T1Ix2<dag oops, dag iops, InstrItinClass itin,
    900             string asm, list<dag> pattern>
    901   : Thumb1I<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
    902 
    903 // Two-address instructions
    904 class T1It<dag oops, dag iops, InstrItinClass itin,
    905            string asm, string cstr, list<dag> pattern>
    906   : Thumb1I<oops, iops, AddrModeNone, 2, itin,
    907             asm, cstr, pattern>;
    908 
    909 // Thumb1 instruction that can either be predicated or set CPSR.
    910 class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
    911                InstrItinClass itin,
    912                string opc, string asm, string cstr, list<dag> pattern>
    913   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
    914   let OutOperandList = !con(oops, (outs s_cc_out:$s));
    915   let InOperandList = !con(iops, (ins pred:$p));
    916   let AsmString = !strconcat(opc, "${s}${p}", asm);
    917   let Pattern = pattern;
    918   let thumbArithFlagSetting = 1;
    919   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
    920   let DecoderNamespace = "ThumbSBit";
    921 }
    922 
    923 class T1sI<dag oops, dag iops, InstrItinClass itin,
    924            string opc, string asm, list<dag> pattern>
    925   : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
    926 
    927 // Two-address instructions
    928 class T1sIt<dag oops, dag iops, InstrItinClass itin,
    929             string opc, string asm, list<dag> pattern>
    930   : Thumb1sI<oops, iops, AddrModeNone, 2, itin, opc, asm,
    931              "$Rn = $Rdn", pattern>;
    932 
    933 // Thumb1 instruction that can be predicated.
    934 class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
    935                InstrItinClass itin,
    936                string opc, string asm, string cstr, list<dag> pattern>
    937   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
    938   let OutOperandList = oops;
    939   let InOperandList = !con(iops, (ins pred:$p));
    940   let AsmString = !strconcat(opc, "${p}", asm);
    941   let Pattern = pattern;
    942   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
    943 }
    944 
    945 class T1pI<dag oops, dag iops, InstrItinClass itin,
    946            string opc, string asm, list<dag> pattern>
    947   : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm, "", pattern>;
    948 
    949 // Two-address instructions
    950 class T1pIt<dag oops, dag iops, InstrItinClass itin,
    951             string opc, string asm, list<dag> pattern>
    952   : Thumb1pI<oops, iops, AddrModeNone, 2, itin, opc, asm,
    953              "$Rn = $Rdn", pattern>;
    954 
    955 class T1pIs<dag oops, dag iops,
    956             InstrItinClass itin, string opc, string asm, list<dag> pattern>
    957   : Thumb1pI<oops, iops, AddrModeT1_s, 2, itin, opc, asm, "", pattern>;
    958 
    959 class Encoding16 : Encoding {
    960   let Inst{31-16} = 0x0000;
    961 }
    962 
    963 // A6.2 16-bit Thumb instruction encoding
    964 class T1Encoding<bits<6> opcode> : Encoding16 {
    965   let Inst{15-10} = opcode;
    966 }
    967 
    968 // A6.2.1 Shift (immediate), add, subtract, move, and compare encoding.
    969 class T1General<bits<5> opcode> : Encoding16 {
    970   let Inst{15-14} = 0b00;
    971   let Inst{13-9} = opcode;
    972 }
    973 
    974 // A6.2.2 Data-processing encoding.
    975 class T1DataProcessing<bits<4> opcode> : Encoding16 {
    976   let Inst{15-10} = 0b010000;
    977   let Inst{9-6} = opcode;
    978 }
    979 
    980 // A6.2.3 Special data instructions and branch and exchange encoding.
    981 class T1Special<bits<4> opcode> : Encoding16 {
    982   let Inst{15-10} = 0b010001;
    983   let Inst{9-6}   = opcode;
    984 }
    985 
    986 // A6.2.4 Load/store single data item encoding.
    987 class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
    988   let Inst{15-12} = opA;
    989   let Inst{11-9}  = opB;
    990 }
    991 class T1LdStSP<bits<3> opB>   : T1LoadStore<0b1001, opB>; // SP relative
    992 
    993 class T1BranchCond<bits<4> opcode> : Encoding16 {
    994   let Inst{15-12} = opcode;
    995 }
    996 
    997 // Helper classes to encode Thumb1 loads and stores. For immediates, the
    998 // following bits are used for "opA" (see A6.2.4):
    999 //
   1000 //   0b0110 => Immediate, 4 bytes
   1001 //   0b1000 => Immediate, 2 bytes
   1002 //   0b0111 => Immediate, 1 byte
   1003 class T1pILdStEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
   1004                      InstrItinClass itin, string opc, string asm,
   1005                      list<dag> pattern>
   1006   : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
   1007     T1LoadStore<0b0101, opcode> {
   1008   bits<3> Rt;
   1009   bits<8> addr;
   1010   let Inst{8-6} = addr{5-3};    // Rm
   1011   let Inst{5-3} = addr{2-0};    // Rn
   1012   let Inst{2-0} = Rt;
   1013 }
   1014 class T1pILdStEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
   1015                         InstrItinClass itin, string opc, string asm,
   1016                         list<dag> pattern>
   1017   : Thumb1pI<oops, iops, am, 2, itin, opc, asm, "", pattern>,
   1018     T1LoadStore<opA, {opB,?,?}> {
   1019   bits<3> Rt;
   1020   bits<8> addr;
   1021   let Inst{10-6} = addr{7-3};   // imm5
   1022   let Inst{5-3}  = addr{2-0};   // Rn
   1023   let Inst{2-0}  = Rt;
   1024 }
   1025 
   1026 // A6.2.5 Miscellaneous 16-bit instructions encoding.
   1027 class T1Misc<bits<7> opcode> : Encoding16 {
   1028   let Inst{15-12} = 0b1011;
   1029   let Inst{11-5} = opcode;
   1030 }
   1031 
   1032 // Thumb2I - Thumb2 instruction. Almost all Thumb2 instructions are predicable.
   1033 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
   1034               InstrItinClass itin,
   1035               string opc, string asm, string cstr, list<dag> pattern>
   1036   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
   1037   let OutOperandList = oops;
   1038   let InOperandList = !con(iops, (ins pred:$p));
   1039   let AsmString = !strconcat(opc, "${p}", asm);
   1040   let Pattern = pattern;
   1041   list<Predicate> Predicates = [IsThumb2];
   1042   let DecoderNamespace = "Thumb2";
   1043 }
   1044 
   1045 // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an
   1046 // input operand since by default it's a zero register. It will become an
   1047 // implicit def once it's "flipped".
   1048 //
   1049 // FIXME: This uses unified syntax so {s} comes before {p}. We should make it
   1050 // more consistent.
   1051 class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
   1052                InstrItinClass itin,
   1053                string opc, string asm, string cstr, list<dag> pattern>
   1054   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
   1055   bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
   1056   let Inst{20} = s;
   1057 
   1058   let OutOperandList = oops;
   1059   let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
   1060   let AsmString = !strconcat(opc, "${s}${p}", asm);
   1061   let Pattern = pattern;
   1062   list<Predicate> Predicates = [IsThumb2];
   1063   let DecoderNamespace = "Thumb2";
   1064 }
   1065 
   1066 // Special cases
   1067 class Thumb2XI<dag oops, dag iops, AddrMode am, int sz,
   1068                InstrItinClass itin,
   1069                string asm, string cstr, list<dag> pattern>
   1070   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
   1071   let OutOperandList = oops;
   1072   let InOperandList = iops;
   1073   let AsmString = asm;
   1074   let Pattern = pattern;
   1075   list<Predicate> Predicates = [IsThumb2];
   1076   let DecoderNamespace = "Thumb2";
   1077 }
   1078 
   1079 class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
   1080               InstrItinClass itin,
   1081               string asm, string cstr, list<dag> pattern>
   1082   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
   1083   let OutOperandList = oops;
   1084   let InOperandList = iops;
   1085   let AsmString = asm;
   1086   let Pattern = pattern;
   1087   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
   1088   let DecoderNamespace = "Thumb";
   1089 }
   1090 
   1091 class T2I<dag oops, dag iops, InstrItinClass itin,
   1092           string opc, string asm, list<dag> pattern>
   1093   : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
   1094 class T2Ii12<dag oops, dag iops, InstrItinClass itin,
   1095              string opc, string asm, list<dag> pattern>
   1096   : Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
   1097 class T2Ii8<dag oops, dag iops, InstrItinClass itin,
   1098             string opc, string asm, list<dag> pattern>
   1099   : Thumb2I<oops, iops, AddrModeT2_i8, 4, itin, opc, asm, "", pattern>;
   1100 class T2Iso<dag oops, dag iops, InstrItinClass itin,
   1101             string opc, string asm, list<dag> pattern>
   1102   : Thumb2I<oops, iops, AddrModeT2_so, 4, itin, opc, asm, "", pattern>;
   1103 class T2Ipc<dag oops, dag iops, InstrItinClass itin,
   1104             string opc, string asm, list<dag> pattern>
   1105   : Thumb2I<oops, iops, AddrModeT2_pc, 4, itin, opc, asm, "", pattern>;
   1106 class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
   1107               string opc, string asm, string cstr, list<dag> pattern>
   1108   : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
   1109             pattern> {
   1110   bits<4> Rt;
   1111   bits<4> Rt2;
   1112   bits<13> addr;
   1113   let Inst{31-25} = 0b1110100;
   1114   let Inst{24}    = P;
   1115   let Inst{23}    = addr{8};
   1116   let Inst{22}    = 1;
   1117   let Inst{21}    = W;
   1118   let Inst{20}    = isLoad;
   1119   let Inst{19-16} = addr{12-9};
   1120   let Inst{15-12} = Rt{3-0};
   1121   let Inst{11-8}  = Rt2{3-0};
   1122   let Inst{7-0}   = addr{7-0};
   1123 }
   1124 class T2Ii8s4post<bit P, bit W, bit isLoad, dag oops, dag iops,
   1125                   InstrItinClass itin, string opc, string asm, string cstr,
   1126                   list<dag> pattern>
   1127   : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, cstr,
   1128             pattern> {
   1129   bits<4> Rt;
   1130   bits<4> Rt2;
   1131   bits<4> addr;
   1132   bits<9> imm;
   1133   let Inst{31-25} = 0b1110100;
   1134   let Inst{24}    = P;
   1135   let Inst{23}    = imm{8};
   1136   let Inst{22}    = 1;
   1137   let Inst{21}    = W;
   1138   let Inst{20}    = isLoad;
   1139   let Inst{19-16} = addr;
   1140   let Inst{15-12} = Rt{3-0};
   1141   let Inst{11-8}  = Rt2{3-0};
   1142   let Inst{7-0}   = imm{7-0};
   1143 }
   1144 
   1145 class T2sI<dag oops, dag iops, InstrItinClass itin,
   1146            string opc, string asm, list<dag> pattern>
   1147   : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
   1148 
   1149 class T2XI<dag oops, dag iops, InstrItinClass itin,
   1150            string asm, list<dag> pattern>
   1151   : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, "", pattern>;
   1152 class T2JTI<dag oops, dag iops, InstrItinClass itin,
   1153             string asm, list<dag> pattern>
   1154   : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
   1155 
   1156 // Move to/from coprocessor instructions
   1157 class T2Cop<bits<4> opc, dag oops, dag iops, string asm, list<dag> pattern>
   1158   : T2XI <oops, iops, NoItinerary, asm, pattern>, Requires<[IsThumb2]> {
   1159   let Inst{31-28} = opc;
   1160 }
   1161 
   1162 // Two-address instructions
   1163 class T2XIt<dag oops, dag iops, InstrItinClass itin,
   1164             string asm, string cstr, list<dag> pattern>
   1165   : Thumb2XI<oops, iops, AddrModeNone, 4, itin, asm, cstr, pattern>;
   1166 
   1167 // T2Ipreldst - Thumb2 pre-indexed load / store instructions.
   1168 class T2Ipreldst<bit signed, bits<2> opcod, bit load, bit pre,
   1169                  dag oops, dag iops,
   1170                  AddrMode am, IndexMode im, InstrItinClass itin,
   1171                  string opc, string asm, string cstr, list<dag> pattern>
   1172   : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
   1173   let OutOperandList = oops;
   1174   let InOperandList = !con(iops, (ins pred:$p));
   1175   let AsmString = !strconcat(opc, "${p}", asm);
   1176   let Pattern = pattern;
   1177   list<Predicate> Predicates = [IsThumb2];
   1178   let DecoderNamespace = "Thumb2";
   1179 
   1180   bits<4> Rt;
   1181   bits<13> addr;
   1182   let Inst{31-27} = 0b11111;
   1183   let Inst{26-25} = 0b00;
   1184   let Inst{24}    = signed;
   1185   let Inst{23}    = 0;
   1186   let Inst{22-21} = opcod;
   1187   let Inst{20}    = load;
   1188   let Inst{19-16} = addr{12-9};
   1189   let Inst{15-12} = Rt{3-0};
   1190   let Inst{11}    = 1;
   1191   // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
   1192   let Inst{10}    = pre; // The P bit.
   1193   let Inst{9}     = addr{8}; // Sign bit
   1194   let Inst{8}     = 1; // The W bit.
   1195   let Inst{7-0}   = addr{7-0};
   1196 
   1197   let DecoderMethod = "DecodeT2LdStPre";
   1198 }
   1199 
   1200 // T2Ipostldst - Thumb2 post-indexed load / store instructions.
   1201 class T2Ipostldst<bit signed, bits<2> opcod, bit load, bit pre,
   1202                  dag oops, dag iops,
   1203                  AddrMode am, IndexMode im, InstrItinClass itin,
   1204                  string opc, string asm, string cstr, list<dag> pattern>
   1205   : InstARM<am, 4, im, ThumbFrm, GenericDomain, cstr, itin> {
   1206   let OutOperandList = oops;
   1207   let InOperandList = !con(iops, (ins pred:$p));
   1208   let AsmString = !strconcat(opc, "${p}", asm);
   1209   let Pattern = pattern;
   1210   list<Predicate> Predicates = [IsThumb2];
   1211   let DecoderNamespace = "Thumb2";
   1212 
   1213   bits<4> Rt;
   1214   bits<4> Rn;
   1215   bits<9> offset;
   1216   let Inst{31-27} = 0b11111;
   1217   let Inst{26-25} = 0b00;
   1218   let Inst{24}    = signed;
   1219   let Inst{23}    = 0;
   1220   let Inst{22-21} = opcod;
   1221   let Inst{20}    = load;
   1222   let Inst{19-16} = Rn;
   1223   let Inst{15-12} = Rt{3-0};
   1224   let Inst{11}    = 1;
   1225   // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed
   1226   let Inst{10}    = pre; // The P bit.
   1227   let Inst{9}     = offset{8}; // Sign bit
   1228   let Inst{8}     = 1; // The W bit.
   1229   let Inst{7-0}   = offset{7-0};
   1230 
   1231   let DecoderMethod = "DecodeT2LdStPre";
   1232 }
   1233 
   1234 // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
   1235 class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
   1236   list<Predicate> Predicates = [IsThumb, IsThumb1Only, HasV5T];
   1237 }
   1238 
   1239 // T1Pat - Same as Pat<>, but requires that the compiler be in Thumb1 mode.
   1240 class T1Pat<dag pattern, dag result> : Pat<pattern, result> {
   1241   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
   1242 }
   1243 
   1244 // T2v6Pat - Same as Pat<>, but requires V6T2 Thumb2 mode.
   1245 class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
   1246   list<Predicate> Predicates = [IsThumb2, HasV6T2];
   1247 }
   1248 
   1249 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
   1250 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
   1251   list<Predicate> Predicates = [IsThumb2];
   1252 }
   1253 
   1254 //===----------------------------------------------------------------------===//
   1255 
   1256 //===----------------------------------------------------------------------===//
   1257 // ARM VFP Instruction templates.
   1258 //
   1259 
   1260 // Almost all VFP instructions are predicable.
   1261 class VFPI<dag oops, dag iops, AddrMode am, int sz,
   1262            IndexMode im, Format f, InstrItinClass itin,
   1263            string opc, string asm, string cstr, list<dag> pattern>
   1264   : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
   1265   bits<4> p;
   1266   let Inst{31-28} = p;
   1267   let OutOperandList = oops;
   1268   let InOperandList = !con(iops, (ins pred:$p));
   1269   let AsmString = !strconcat(opc, "${p}", asm);
   1270   let Pattern = pattern;
   1271   let PostEncoderMethod = "VFPThumb2PostEncoder";
   1272   let DecoderNamespace = "VFP";
   1273   list<Predicate> Predicates = [HasVFP2];
   1274 }
   1275 
   1276 // Special cases
   1277 class VFPXI<dag oops, dag iops, AddrMode am, int sz,
   1278             IndexMode im, Format f, InstrItinClass itin,
   1279             string asm, string cstr, list<dag> pattern>
   1280   : InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
   1281   bits<4> p;
   1282   let Inst{31-28} = p;
   1283   let OutOperandList = oops;
   1284   let InOperandList = iops;
   1285   let AsmString = asm;
   1286   let Pattern = pattern;
   1287   let PostEncoderMethod = "VFPThumb2PostEncoder";
   1288   let DecoderNamespace = "VFP";
   1289   list<Predicate> Predicates = [HasVFP2];
   1290 }
   1291 
   1292 class VFPAI<dag oops, dag iops, Format f, InstrItinClass itin,
   1293             string opc, string asm, list<dag> pattern>
   1294   : VFPI<oops, iops, AddrModeNone, 4, IndexModeNone, f, itin,
   1295          opc, asm, "", pattern> {
   1296   let PostEncoderMethod = "VFPThumb2PostEncoder";
   1297 }
   1298 
   1299 // ARM VFP addrmode5 loads and stores
   1300 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
   1301            InstrItinClass itin,
   1302            string opc, string asm, list<dag> pattern>
   1303   : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
   1304          VFPLdStFrm, itin, opc, asm, "", pattern> {
   1305   // Instruction operands.
   1306   bits<5>  Dd;
   1307   bits<13> addr;
   1308 
   1309   // Encode instruction operands.
   1310   let Inst{23}    = addr{8};      // U (add = (U == '1'))
   1311   let Inst{22}    = Dd{4};
   1312   let Inst{19-16} = addr{12-9};   // Rn
   1313   let Inst{15-12} = Dd{3-0};
   1314   let Inst{7-0}   = addr{7-0};    // imm8
   1315 
   1316   // TODO: Mark the instructions with the appropriate subtarget info.
   1317   let Inst{27-24} = opcod1;
   1318   let Inst{21-20} = opcod2;
   1319   let Inst{11-9}  = 0b101;
   1320   let Inst{8}     = 1;          // Double precision
   1321 
   1322   // Loads & stores operate on both NEON and VFP pipelines.
   1323   let D = VFPNeonDomain;
   1324 }
   1325 
   1326 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
   1327            InstrItinClass itin,
   1328            string opc, string asm, list<dag> pattern>
   1329   : VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
   1330          VFPLdStFrm, itin, opc, asm, "", pattern> {
   1331   // Instruction operands.
   1332   bits<5>  Sd;
   1333   bits<13> addr;
   1334 
   1335   // Encode instruction operands.
   1336   let Inst{23}    = addr{8};      // U (add = (U == '1'))
   1337   let Inst{22}    = Sd{0};
   1338   let Inst{19-16} = addr{12-9};   // Rn
   1339   let Inst{15-12} = Sd{4-1};
   1340   let Inst{7-0}   = addr{7-0};    // imm8
   1341 
   1342   // TODO: Mark the instructions with the appropriate subtarget info.
   1343   let Inst{27-24} = opcod1;
   1344   let Inst{21-20} = opcod2;
   1345   let Inst{11-9}  = 0b101;
   1346   let Inst{8}     = 0;          // Single precision
   1347 
   1348   // Loads & stores operate on both NEON and VFP pipelines.
   1349   let D = VFPNeonDomain;
   1350 }
   1351 
   1352 // VFP Load / store multiple pseudo instructions.
   1353 class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
   1354                      list<dag> pattern>
   1355   : InstARM<AddrMode4, 4, IndexModeNone, Pseudo, VFPNeonDomain,
   1356             cstr, itin> {
   1357   let OutOperandList = oops;
   1358   let InOperandList = !con(iops, (ins pred:$p));
   1359   let Pattern = pattern;
   1360   list<Predicate> Predicates = [HasVFP2];
   1361 }
   1362 
   1363 // Load / store multiple
   1364 class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
   1365             string asm, string cstr, list<dag> pattern>
   1366   : VFPXI<oops, iops, AddrMode4, 4, im,
   1367           VFPLdStMulFrm, itin, asm, cstr, pattern> {
   1368   // Instruction operands.
   1369   bits<4>  Rn;
   1370   bits<13> regs;
   1371 
   1372   // Encode instruction operands.
   1373   let Inst{19-16} = Rn;
   1374   let Inst{22}    = regs{12};
   1375   let Inst{15-12} = regs{11-8};
   1376   let Inst{7-0}   = regs{7-0};
   1377 
   1378   // TODO: Mark the instructions with the appropriate subtarget info.
   1379   let Inst{27-25} = 0b110;
   1380   let Inst{11-9}  = 0b101;
   1381   let Inst{8}     = 1;          // Double precision
   1382 }
   1383 
   1384 class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin,
   1385             string asm, string cstr, list<dag> pattern>
   1386   : VFPXI<oops, iops, AddrMode4, 4, im,
   1387           VFPLdStMulFrm, itin, asm, cstr, pattern> {
   1388   // Instruction operands.
   1389   bits<4> Rn;
   1390   bits<13> regs;
   1391 
   1392   // Encode instruction operands.
   1393   let Inst{19-16} = Rn;
   1394   let Inst{22}    = regs{8};
   1395   let Inst{15-12} = regs{12-9};
   1396   let Inst{7-0}   = regs{7-0};
   1397 
   1398   // TODO: Mark the instructions with the appropriate subtarget info.
   1399   let Inst{27-25} = 0b110;
   1400   let Inst{11-9}  = 0b101;
   1401   let Inst{8}     = 0;          // Single precision
   1402 }
   1403 
   1404 // Double precision, unary
   1405 class ADuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
   1406            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
   1407            string asm, list<dag> pattern>
   1408   : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
   1409   // Instruction operands.
   1410   bits<5> Dd;
   1411   bits<5> Dm;
   1412 
   1413   // Encode instruction operands.
   1414   let Inst{3-0}   = Dm{3-0};
   1415   let Inst{5}     = Dm{4};
   1416   let Inst{15-12} = Dd{3-0};
   1417   let Inst{22}    = Dd{4};
   1418 
   1419   let Inst{27-23} = opcod1;
   1420   let Inst{21-20} = opcod2;
   1421   let Inst{19-16} = opcod3;
   1422   let Inst{11-9}  = 0b101;
   1423   let Inst{8}     = 1;          // Double precision
   1424   let Inst{7-6}   = opcod4;
   1425   let Inst{4}     = opcod5;
   1426 }
   1427 
   1428 // Double precision, binary
   1429 class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
   1430            dag iops, InstrItinClass itin, string opc, string asm,
   1431            list<dag> pattern>
   1432   : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
   1433   // Instruction operands.
   1434   bits<5> Dd;
   1435   bits<5> Dn;
   1436   bits<5> Dm;
   1437 
   1438   // Encode instruction operands.
   1439   let Inst{3-0}   = Dm{3-0};
   1440   let Inst{5}     = Dm{4};
   1441   let Inst{19-16} = Dn{3-0};
   1442   let Inst{7}     = Dn{4};
   1443   let Inst{15-12} = Dd{3-0};
   1444   let Inst{22}    = Dd{4};
   1445 
   1446   let Inst{27-23} = opcod1;
   1447   let Inst{21-20} = opcod2;
   1448   let Inst{11-9}  = 0b101;
   1449   let Inst{8}     = 1;          // Double precision
   1450   let Inst{6}     = op6;
   1451   let Inst{4}     = op4;
   1452 }
   1453 
   1454 // Single precision, unary
   1455 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
   1456            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
   1457            string asm, list<dag> pattern>
   1458   : VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
   1459   // Instruction operands.
   1460   bits<5> Sd;
   1461   bits<5> Sm;
   1462 
   1463   // Encode instruction operands.
   1464   let Inst{3-0}   = Sm{4-1};
   1465   let Inst{5}     = Sm{0};
   1466   let Inst{15-12} = Sd{4-1};
   1467   let Inst{22}    = Sd{0};
   1468 
   1469   let Inst{27-23} = opcod1;
   1470   let Inst{21-20} = opcod2;
   1471   let Inst{19-16} = opcod3;
   1472   let Inst{11-9}  = 0b101;
   1473   let Inst{8}     = 0;          // Single precision
   1474   let Inst{7-6}   = opcod4;
   1475   let Inst{4}     = opcod5;
   1476 }
   1477 
   1478 // Single precision unary, if no NEON. Same as ASuI except not available if
   1479 // NEON is enabled.
   1480 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
   1481             bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
   1482             string asm, list<dag> pattern>
   1483   : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc, asm,
   1484          pattern> {
   1485   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
   1486 }
   1487 
   1488 // Single precision, binary
   1489 class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
   1490            InstrItinClass itin, string opc, string asm, list<dag> pattern>
   1491   : VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
   1492   // Instruction operands.
   1493   bits<5> Sd;
   1494   bits<5> Sn;
   1495   bits<5> Sm;
   1496 
   1497   // Encode instruction operands.
   1498   let Inst{3-0}   = Sm{4-1};
   1499   let Inst{5}     = Sm{0};
   1500   let Inst{19-16} = Sn{4-1};
   1501   let Inst{7}     = Sn{0};
   1502   let Inst{15-12} = Sd{4-1};
   1503   let Inst{22}    = Sd{0};
   1504 
   1505   let Inst{27-23} = opcod1;
   1506   let Inst{21-20} = opcod2;
   1507   let Inst{11-9}  = 0b101;
   1508   let Inst{8}     = 0;          // Single precision
   1509   let Inst{6}     = op6;
   1510   let Inst{4}     = op4;
   1511 }
   1512 
   1513 // Single precision binary, if no NEON. Same as ASbI except not available if
   1514 // NEON is enabled.
   1515 class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
   1516             dag iops, InstrItinClass itin, string opc, string asm,
   1517             list<dag> pattern>
   1518   : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
   1519   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
   1520 
   1521   // Instruction operands.
   1522   bits<5> Sd;
   1523   bits<5> Sn;
   1524   bits<5> Sm;
   1525 
   1526   // Encode instruction operands.
   1527   let Inst{3-0}   = Sm{4-1};
   1528   let Inst{5}     = Sm{0};
   1529   let Inst{19-16} = Sn{4-1};
   1530   let Inst{7}     = Sn{0};
   1531   let Inst{15-12} = Sd{4-1};
   1532   let Inst{22}    = Sd{0};
   1533 }
   1534 
   1535 // VFP conversion instructions
   1536 class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
   1537                dag oops, dag iops, InstrItinClass itin, string opc, string asm,
   1538                list<dag> pattern>
   1539   : VFPAI<oops, iops, VFPConv1Frm, itin, opc, asm, pattern> {
   1540   let Inst{27-23} = opcod1;
   1541   let Inst{21-20} = opcod2;
   1542   let Inst{19-16} = opcod3;
   1543   let Inst{11-8}  = opcod4;
   1544   let Inst{6}     = 1;
   1545   let Inst{4}     = 0;
   1546 }
   1547 
   1548 // VFP conversion between floating-point and fixed-point
   1549 class AVConv1XI<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
   1550                 dag oops, dag iops, InstrItinClass itin, string opc, string asm,
   1551                 list<dag> pattern>
   1552   : AVConv1I<op1, op2, op3, op4, oops, iops, itin, opc, asm, pattern> {
   1553   // size (fixed-point number): sx == 0 ? 16 : 32
   1554   let Inst{7} = op5; // sx
   1555 }
   1556 
   1557 // VFP conversion instructions, if no NEON
   1558 class AVConv1In<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
   1559                 dag oops, dag iops, InstrItinClass itin,
   1560                 string opc, string asm, list<dag> pattern>
   1561   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1562              pattern> {
   1563   list<Predicate> Predicates = [HasVFP2,DontUseNEONForFP];
   1564 }
   1565 
   1566 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
   1567                InstrItinClass itin,
   1568                string opc, string asm, list<dag> pattern>
   1569   : VFPAI<oops, iops, f, itin, opc, asm, pattern> {
   1570   let Inst{27-20} = opcod1;
   1571   let Inst{11-8}  = opcod2;
   1572   let Inst{4}     = 1;
   1573 }
   1574 
   1575 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
   1576                InstrItinClass itin, string opc, string asm, list<dag> pattern>
   1577   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, itin, opc, asm, pattern>;
   1578 
   1579 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
   1580                InstrItinClass itin, string opc, string asm, list<dag> pattern>
   1581   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, itin, opc, asm, pattern>;
   1582 
   1583 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
   1584                InstrItinClass itin, string opc, string asm, list<dag> pattern>
   1585   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, itin, opc, asm, pattern>;
   1586 
   1587 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
   1588                InstrItinClass itin, string opc, string asm, list<dag> pattern>
   1589   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, itin, opc, asm, pattern>;
   1590 
   1591 //===----------------------------------------------------------------------===//
   1592 
   1593 //===----------------------------------------------------------------------===//
   1594 // ARM NEON Instruction templates.
   1595 //
   1596 
   1597 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
   1598             InstrItinClass itin, string opc, string dt, string asm, string cstr,
   1599             list<dag> pattern>
   1600   : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
   1601   let OutOperandList = oops;
   1602   let InOperandList = !con(iops, (ins pred:$p));
   1603   let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
   1604   let Pattern = pattern;
   1605   list<Predicate> Predicates = [HasNEON];
   1606   let DecoderNamespace = "NEON";
   1607 }
   1608 
   1609 // Same as NeonI except it does not have a "data type" specifier.
   1610 class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
   1611              InstrItinClass itin, string opc, string asm, string cstr,
   1612              list<dag> pattern>
   1613   : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
   1614   let OutOperandList = oops;
   1615   let InOperandList = !con(iops, (ins pred:$p));
   1616   let AsmString = !strconcat(opc, "${p}", "\t", asm);
   1617   let Pattern = pattern;
   1618   list<Predicate> Predicates = [HasNEON];
   1619   let DecoderNamespace = "NEON";
   1620 }
   1621 
   1622 class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
   1623             dag oops, dag iops, InstrItinClass itin,
   1624             string opc, string dt, string asm, string cstr, list<dag> pattern>
   1625   : NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
   1626           cstr, pattern> {
   1627   let Inst{31-24} = 0b11110100;
   1628   let Inst{23}    = op23;
   1629   let Inst{21-20} = op21_20;
   1630   let Inst{11-8}  = op11_8;
   1631   let Inst{7-4}   = op7_4;
   1632 
   1633   let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder";
   1634   let DecoderNamespace = "NEONLoadStore";
   1635 
   1636   bits<5> Vd;
   1637   bits<6> Rn;
   1638   bits<4> Rm;
   1639 
   1640   let Inst{22}    = Vd{4};
   1641   let Inst{15-12} = Vd{3-0};
   1642   let Inst{19-16} = Rn{3-0};
   1643   let Inst{3-0}   = Rm{3-0};
   1644 }
   1645 
   1646 class NLdStLn<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
   1647             dag oops, dag iops, InstrItinClass itin,
   1648             string opc, string dt, string asm, string cstr, list<dag> pattern>
   1649   : NLdSt<op23, op21_20, op11_8, op7_4, oops, iops, itin, opc,
   1650           dt, asm, cstr, pattern> {
   1651   bits<3> lane;
   1652 }
   1653 
   1654 class PseudoNLdSt<dag oops, dag iops, InstrItinClass itin, string cstr>
   1655   : InstARM<AddrMode6, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
   1656             itin> {
   1657   let OutOperandList = oops;
   1658   let InOperandList = !con(iops, (ins pred:$p));
   1659   list<Predicate> Predicates = [HasNEON];
   1660 }
   1661 
   1662 class PseudoNeonI<dag oops, dag iops, InstrItinClass itin, string cstr,
   1663                   list<dag> pattern>
   1664   : InstARM<AddrModeNone, 4, IndexModeNone, Pseudo, NeonDomain, cstr,
   1665             itin> {
   1666   let OutOperandList = oops;
   1667   let InOperandList = !con(iops, (ins pred:$p));
   1668   let Pattern = pattern;
   1669   list<Predicate> Predicates = [HasNEON];
   1670 }
   1671 
   1672 class NDataI<dag oops, dag iops, Format f, InstrItinClass itin,
   1673              string opc, string dt, string asm, string cstr, list<dag> pattern>
   1674   : NeonI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, dt, asm, cstr,
   1675           pattern> {
   1676   let Inst{31-25} = 0b1111001;
   1677   let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
   1678   let DecoderNamespace = "NEONData";
   1679 }
   1680 
   1681 class NDataXI<dag oops, dag iops, Format f, InstrItinClass itin,
   1682               string opc, string asm, string cstr, list<dag> pattern>
   1683   : NeonXI<oops, iops, AddrModeNone, IndexModeNone, f, itin, opc, asm,
   1684            cstr, pattern> {
   1685   let Inst{31-25} = 0b1111001;
   1686   let PostEncoderMethod = "NEONThumb2DataIPostEncoder";
   1687   let DecoderNamespace = "NEONData";
   1688 }
   1689 
   1690 // NEON "one register and a modified immediate" format.
   1691 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
   1692                bit op5, bit op4,
   1693                dag oops, dag iops, InstrItinClass itin,
   1694                string opc, string dt, string asm, string cstr,
   1695                list<dag> pattern>
   1696   : NDataI<oops, iops, N1RegModImmFrm, itin, opc, dt, asm, cstr, pattern> {
   1697   let Inst{23}    = op23;
   1698   let Inst{21-19} = op21_19;
   1699   let Inst{11-8}  = op11_8;
   1700   let Inst{7}     = op7;
   1701   let Inst{6}     = op6;
   1702   let Inst{5}     = op5;
   1703   let Inst{4}     = op4;
   1704 
   1705   // Instruction operands.
   1706   bits<5> Vd;
   1707   bits<13> SIMM;
   1708 
   1709   let Inst{15-12} = Vd{3-0};
   1710   let Inst{22}    = Vd{4};
   1711   let Inst{24}    = SIMM{7};
   1712   let Inst{18-16} = SIMM{6-4};
   1713   let Inst{3-0}   = SIMM{3-0};
   1714   let DecoderMethod = "DecodeNEONModImmInstruction";
   1715 }
   1716 
   1717 // NEON 2 vector register format.
   1718 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
   1719           bits<5> op11_7, bit op6, bit op4,
   1720           dag oops, dag iops, InstrItinClass itin,
   1721           string opc, string dt, string asm, string cstr, list<dag> pattern>
   1722   : NDataI<oops, iops, N2RegFrm, itin, opc, dt, asm, cstr, pattern> {
   1723   let Inst{24-23} = op24_23;
   1724   let Inst{21-20} = op21_20;
   1725   let Inst{19-18} = op19_18;
   1726   let Inst{17-16} = op17_16;
   1727   let Inst{11-7}  = op11_7;
   1728   let Inst{6}     = op6;
   1729   let Inst{4}     = op4;
   1730 
   1731   // Instruction operands.
   1732   bits<5> Vd;
   1733   bits<5> Vm;
   1734 
   1735   let Inst{15-12} = Vd{3-0};
   1736   let Inst{22}    = Vd{4};
   1737   let Inst{3-0}   = Vm{3-0};
   1738   let Inst{5}     = Vm{4};
   1739 }
   1740 
   1741 // Same as N2V except it doesn't have a datatype suffix.
   1742 class N2VX<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
   1743            bits<5> op11_7, bit op6, bit op4,
   1744            dag oops, dag iops, InstrItinClass itin,
   1745            string opc, string asm, string cstr, list<dag> pattern>
   1746   : NDataXI<oops, iops, N2RegFrm, itin, opc, asm, cstr, pattern> {
   1747   let Inst{24-23} = op24_23;
   1748   let Inst{21-20} = op21_20;
   1749   let Inst{19-18} = op19_18;
   1750   let Inst{17-16} = op17_16;
   1751   let Inst{11-7}  = op11_7;
   1752   let Inst{6}     = op6;
   1753   let Inst{4}     = op4;
   1754 
   1755   // Instruction operands.
   1756   bits<5> Vd;
   1757   bits<5> Vm;
   1758 
   1759   let Inst{15-12} = Vd{3-0};
   1760   let Inst{22}    = Vd{4};
   1761   let Inst{3-0}   = Vm{3-0};
   1762   let Inst{5}     = Vm{4};
   1763 }
   1764 
   1765 // NEON 2 vector register with immediate.
   1766 class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4,
   1767              dag oops, dag iops, Format f, InstrItinClass itin,
   1768              string opc, string dt, string asm, string cstr, list<dag> pattern>
   1769   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
   1770   let Inst{24}   = op24;
   1771   let Inst{23}   = op23;
   1772   let Inst{11-8} = op11_8;
   1773   let Inst{7}    = op7;
   1774   let Inst{6}    = op6;
   1775   let Inst{4}    = op4;
   1776 
   1777   // Instruction operands.
   1778   bits<5> Vd;
   1779   bits<5> Vm;
   1780   bits<6> SIMM;
   1781 
   1782   let Inst{15-12} = Vd{3-0};
   1783   let Inst{22}    = Vd{4};
   1784   let Inst{3-0}   = Vm{3-0};
   1785   let Inst{5}     = Vm{4};
   1786   let Inst{21-16} = SIMM{5-0};
   1787 }
   1788 
   1789 // NEON 3 vector register format.
   1790 
   1791 class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
   1792                 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
   1793                 string opc, string dt, string asm, string cstr,
   1794                 list<dag> pattern>
   1795   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
   1796   let Inst{24}    = op24;
   1797   let Inst{23}    = op23;
   1798   let Inst{21-20} = op21_20;
   1799   let Inst{11-8}  = op11_8;
   1800   let Inst{6}     = op6;
   1801   let Inst{4}     = op4;
   1802 }
   1803 
   1804 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
   1805           dag oops, dag iops, Format f, InstrItinClass itin,
   1806           string opc, string dt, string asm, string cstr, list<dag> pattern>
   1807   : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
   1808               oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
   1809 
   1810   // Instruction operands.
   1811   bits<5> Vd;
   1812   bits<5> Vn;
   1813   bits<5> Vm;
   1814 
   1815   let Inst{15-12} = Vd{3-0};
   1816   let Inst{22}    = Vd{4};
   1817   let Inst{19-16} = Vn{3-0};
   1818   let Inst{7}     = Vn{4};
   1819   let Inst{3-0}   = Vm{3-0};
   1820   let Inst{5}     = Vm{4};
   1821 }
   1822 
   1823 class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
   1824                 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
   1825                 string opc, string dt, string asm, string cstr,
   1826                 list<dag> pattern>
   1827   : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
   1828               oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
   1829 
   1830   // Instruction operands.
   1831   bits<5> Vd;
   1832   bits<5> Vn;
   1833   bits<5> Vm;
   1834   bit lane;
   1835 
   1836   let Inst{15-12} = Vd{3-0};
   1837   let Inst{22}    = Vd{4};
   1838   let Inst{19-16} = Vn{3-0};
   1839   let Inst{7}     = Vn{4};
   1840   let Inst{3-0}   = Vm{3-0};
   1841   let Inst{5}     = lane;
   1842 }
   1843 
   1844 class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
   1845                 bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
   1846                 string opc, string dt, string asm, string cstr,
   1847                 list<dag> pattern>
   1848   : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
   1849               oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
   1850 
   1851   // Instruction operands.
   1852   bits<5> Vd;
   1853   bits<5> Vn;
   1854   bits<5> Vm;
   1855   bits<2> lane;
   1856 
   1857   let Inst{15-12} = Vd{3-0};
   1858   let Inst{22}    = Vd{4};
   1859   let Inst{19-16} = Vn{3-0};
   1860   let Inst{7}     = Vn{4};
   1861   let Inst{2-0}   = Vm{2-0};
   1862   let Inst{5}     = lane{1};
   1863   let Inst{3}     = lane{0};
   1864 }
   1865 
   1866 // Same as N3V except it doesn't have a data type suffix.
   1867 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
   1868            bit op4,
   1869            dag oops, dag iops, Format f, InstrItinClass itin,
   1870            string opc, string asm, string cstr, list<dag> pattern>
   1871   : NDataXI<oops, iops, f, itin, opc, asm, cstr, pattern> {
   1872   let Inst{24}    = op24;
   1873   let Inst{23}    = op23;
   1874   let Inst{21-20} = op21_20;
   1875   let Inst{11-8}  = op11_8;
   1876   let Inst{6}     = op6;
   1877   let Inst{4}     = op4;
   1878 
   1879   // Instruction operands.
   1880   bits<5> Vd;
   1881   bits<5> Vn;
   1882   bits<5> Vm;
   1883 
   1884   let Inst{15-12} = Vd{3-0};
   1885   let Inst{22}    = Vd{4};
   1886   let Inst{19-16} = Vn{3-0};
   1887   let Inst{7}     = Vn{4};
   1888   let Inst{3-0}   = Vm{3-0};
   1889   let Inst{5}     = Vm{4};
   1890 }
   1891 
   1892 // NEON VMOVs between scalar and core registers.
   1893 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
   1894                dag oops, dag iops, Format f, InstrItinClass itin,
   1895                string opc, string dt, string asm, list<dag> pattern>
   1896   : InstARM<AddrModeNone, 4, IndexModeNone, f, NeonDomain,
   1897             "", itin> {
   1898   let Inst{27-20} = opcod1;
   1899   let Inst{11-8}  = opcod2;
   1900   let Inst{6-5}   = opcod3;
   1901   let Inst{4}     = 1;
   1902   // A8.6.303, A8.6.328, A8.6.329
   1903   let Inst{3-0}   = 0b0000;
   1904 
   1905   let OutOperandList = oops;
   1906   let InOperandList = !con(iops, (ins pred:$p));
   1907   let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
   1908   let Pattern = pattern;
   1909   list<Predicate> Predicates = [HasNEON];
   1910 
   1911   let PostEncoderMethod = "NEONThumb2DupPostEncoder";
   1912   let DecoderNamespace = "NEONDup";
   1913 
   1914   bits<5> V;
   1915   bits<4> R;
   1916   bits<4> p;
   1917   bits<4> lane;
   1918 
   1919   let Inst{31-28} = p{3-0};
   1920   let Inst{7}     = V{4};
   1921   let Inst{19-16} = V{3-0};
   1922   let Inst{15-12} = R{3-0};
   1923 }
   1924 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
   1925                 dag oops, dag iops, InstrItinClass itin,
   1926                 string opc, string dt, string asm, list<dag> pattern>
   1927   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NGetLnFrm, itin,
   1928              opc, dt, asm, pattern>;
   1929 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
   1930                 dag oops, dag iops, InstrItinClass itin,
   1931                 string opc, string dt, string asm, list<dag> pattern>
   1932   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NSetLnFrm, itin,
   1933              opc, dt, asm, pattern>;
   1934 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
   1935             dag oops, dag iops, InstrItinClass itin,
   1936             string opc, string dt, string asm, list<dag> pattern>
   1937   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NDupFrm, itin,
   1938              opc, dt, asm, pattern>;
   1939 
   1940 // Vector Duplicate Lane (from scalar to all elements)
   1941 class NVDupLane<bits<4> op19_16, bit op6, dag oops, dag iops,
   1942                 InstrItinClass itin, string opc, string dt, string asm,
   1943                 list<dag> pattern>
   1944   : NDataI<oops, iops, NVDupLnFrm, itin, opc, dt, asm, "", pattern> {
   1945   let Inst{24-23} = 0b11;
   1946   let Inst{21-20} = 0b11;
   1947   let Inst{19-16} = op19_16;
   1948   let Inst{11-7}  = 0b11000;
   1949   let Inst{6}     = op6;
   1950   let Inst{4}     = 0;
   1951 
   1952   bits<5> Vd;
   1953   bits<5> Vm;
   1954 
   1955   let Inst{22}     = Vd{4};
   1956   let Inst{15-12} = Vd{3-0};
   1957   let Inst{5}     = Vm{4};
   1958   let Inst{3-0} = Vm{3-0};
   1959 }
   1960 
   1961 // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON
   1962 // for single-precision FP.
   1963 class NEONFPPat<dag pattern, dag result> : Pat<pattern, result> {
   1964   list<Predicate> Predicates = [HasNEON,UseNEONForFP];
   1965 }
   1966