xref: /aosp_15_r20/external/llvm/lib/Target/ARM/ARMInstrThumb2.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===-- ARMInstrThumb2.td - Thumb2 support for ARM ---------*- tablegen -*-===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This file describes the Thumb2 instruction set.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker// IT block predicate field
15*9880d681SAndroid Build Coastguard Workerdef it_pred_asmoperand : AsmOperandClass {
16*9880d681SAndroid Build Coastguard Worker  let Name = "ITCondCode";
17*9880d681SAndroid Build Coastguard Worker  let ParserMethod = "parseITCondCode";
18*9880d681SAndroid Build Coastguard Worker}
19*9880d681SAndroid Build Coastguard Workerdef it_pred : Operand<i32> {
20*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printMandatoryPredicateOperand";
21*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = it_pred_asmoperand;
22*9880d681SAndroid Build Coastguard Worker}
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker// IT block condition mask
25*9880d681SAndroid Build Coastguard Workerdef it_mask_asmoperand : AsmOperandClass { let Name = "ITMask"; }
26*9880d681SAndroid Build Coastguard Workerdef it_mask : Operand<i32> {
27*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printThumbITMask";
28*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = it_mask_asmoperand;
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker// t2_shift_imm: An integer that encodes a shift amount and the type of shift
32*9880d681SAndroid Build Coastguard Worker// (asr or lsl). The 6-bit immediate encodes as:
33*9880d681SAndroid Build Coastguard Worker//    {5}     0 ==> lsl
34*9880d681SAndroid Build Coastguard Worker//            1     asr
35*9880d681SAndroid Build Coastguard Worker//    {4-0}   imm5 shift amount.
36*9880d681SAndroid Build Coastguard Worker//            asr #32 not allowed
37*9880d681SAndroid Build Coastguard Workerdef t2_shift_imm : Operand<i32> {
38*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printShiftImmOperand";
39*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = ShifterImmAsmOperand;
40*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2ShifterImmOperand";
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker// Shifted operands. No register controlled shifts for Thumb2.
44*9880d681SAndroid Build Coastguard Worker// Note: We do not support rrx shifted operands yet.
45*9880d681SAndroid Build Coastguard Workerdef t2_so_reg : Operand<i32>,    // reg imm
46*9880d681SAndroid Build Coastguard Worker                ComplexPattern<i32, 2, "SelectShiftImmShifterOperand",
47*9880d681SAndroid Build Coastguard Worker                               [shl,srl,sra,rotr]> {
48*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2SORegOpValue";
49*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2SOOperand";
50*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeSORegImmOperand";
51*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = ShiftedImmAsmOperand;
52*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops rGPR, i32imm);
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
56*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
57*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), SDLoc(N),
58*9880d681SAndroid Build Coastguard Worker                                   MVT::i32);
59*9880d681SAndroid Build Coastguard Worker}]>;
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
62*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
63*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(-((int)N->getZExtValue()), SDLoc(N),
64*9880d681SAndroid Build Coastguard Worker                                   MVT::i32);
65*9880d681SAndroid Build Coastguard Worker}]>;
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker// so_imm_notSext_XFORM - Return a so_imm value packed into the format
68*9880d681SAndroid Build Coastguard Worker// described for so_imm_notSext def below, with sign extension from 16
69*9880d681SAndroid Build Coastguard Worker// bits.
70*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_notSext16_XFORM : SDNodeXForm<imm, [{
71*9880d681SAndroid Build Coastguard Worker  APInt apIntN = N->getAPIntValue();
72*9880d681SAndroid Build Coastguard Worker  unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue();
73*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(~N16bitSignExt, SDLoc(N), MVT::i32);
74*9880d681SAndroid Build Coastguard Worker}]>;
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker// t2_so_imm - Match a 32-bit immediate operand, which is an
77*9880d681SAndroid Build Coastguard Worker// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
78*9880d681SAndroid Build Coastguard Worker// immediate splatted into multiple bytes of the word.
79*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_asmoperand : ImmAsmOperand { let Name = "T2SOImm"; }
80*9880d681SAndroid Build Coastguard Workerdef t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
81*9880d681SAndroid Build Coastguard Worker    return ARM_AM::getT2SOImmVal(Imm) != -1;
82*9880d681SAndroid Build Coastguard Worker  }]> {
83*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2_so_imm_asmoperand;
84*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2SOImmOpValue";
85*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2SOImm";
86*9880d681SAndroid Build Coastguard Worker}
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker// t2_so_imm_not - Match an immediate that is a complement
89*9880d681SAndroid Build Coastguard Worker// of a t2_so_imm.
90*9880d681SAndroid Build Coastguard Worker// Note: this pattern doesn't require an encoder method and such, as it's
91*9880d681SAndroid Build Coastguard Worker// only used on aliases (Pat<> and InstAlias<>). The actual encoding
92*9880d681SAndroid Build Coastguard Worker// is handled by the destination instructions, which use t2_so_imm.
93*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_not_asmoperand : AsmOperandClass { let Name = "T2SOImmNot"; }
94*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{
95*9880d681SAndroid Build Coastguard Worker  return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
96*9880d681SAndroid Build Coastguard Worker}], t2_so_imm_not_XFORM> {
97*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2_so_imm_not_asmoperand;
98*9880d681SAndroid Build Coastguard Worker}
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker// t2_so_imm_notSext - match an immediate that is a complement of a t2_so_imm
101*9880d681SAndroid Build Coastguard Worker// if the upper 16 bits are zero.
102*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_notSext : Operand<i32>, PatLeaf<(imm), [{
103*9880d681SAndroid Build Coastguard Worker    APInt apIntN = N->getAPIntValue();
104*9880d681SAndroid Build Coastguard Worker    if (!apIntN.isIntN(16)) return false;
105*9880d681SAndroid Build Coastguard Worker    unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue();
106*9880d681SAndroid Build Coastguard Worker    return ARM_AM::getT2SOImmVal(~N16bitSignExt) != -1;
107*9880d681SAndroid Build Coastguard Worker  }], t2_so_imm_notSext16_XFORM> {
108*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2_so_imm_not_asmoperand;
109*9880d681SAndroid Build Coastguard Worker}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
112*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; }
113*9880d681SAndroid Build Coastguard Workerdef t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
114*9880d681SAndroid Build Coastguard Worker  int64_t Value = -(int)N->getZExtValue();
115*9880d681SAndroid Build Coastguard Worker  return Value && ARM_AM::getT2SOImmVal(Value) != -1;
116*9880d681SAndroid Build Coastguard Worker}], t2_so_imm_neg_XFORM> {
117*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2_so_imm_neg_asmoperand;
118*9880d681SAndroid Build Coastguard Worker}
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
121*9880d681SAndroid Build Coastguard Workerdef imm0_4095_asmoperand: ImmAsmOperand { let Name = "Imm0_4095"; }
122*9880d681SAndroid Build Coastguard Workerdef imm0_4095 : Operand<i32>, ImmLeaf<i32, [{
123*9880d681SAndroid Build Coastguard Worker  return Imm >= 0 && Imm < 4096;
124*9880d681SAndroid Build Coastguard Worker}]> {
125*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = imm0_4095_asmoperand;
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerdef imm0_4095_neg_asmoperand: AsmOperandClass { let Name = "Imm0_4095Neg"; }
129*9880d681SAndroid Build Coastguard Workerdef imm0_4095_neg : Operand<i32>, PatLeaf<(i32 imm), [{
130*9880d681SAndroid Build Coastguard Worker return (uint32_t)(-N->getZExtValue()) < 4096;
131*9880d681SAndroid Build Coastguard Worker}], imm_neg_XFORM> {
132*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = imm0_4095_neg_asmoperand;
133*9880d681SAndroid Build Coastguard Worker}
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerdef imm1_255_neg : PatLeaf<(i32 imm), [{
136*9880d681SAndroid Build Coastguard Worker  uint32_t Val = -N->getZExtValue();
137*9880d681SAndroid Build Coastguard Worker  return (Val > 0 && Val < 255);
138*9880d681SAndroid Build Coastguard Worker}], imm_neg_XFORM>;
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Workerdef imm0_255_not : PatLeaf<(i32 imm), [{
141*9880d681SAndroid Build Coastguard Worker  return (uint32_t)(~N->getZExtValue()) < 255;
142*9880d681SAndroid Build Coastguard Worker}], imm_comp_XFORM>;
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerdef lo5AllOne : PatLeaf<(i32 imm), [{
145*9880d681SAndroid Build Coastguard Worker  // Returns true if all low 5-bits are 1.
146*9880d681SAndroid Build Coastguard Worker  return (((uint32_t)N->getZExtValue()) & 0x1FUL) == 0x1FUL;
147*9880d681SAndroid Build Coastguard Worker}]>;
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker// Define Thumb2 specific addressing modes.
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker// t2addrmode_imm12  := reg + imm12
152*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm12_asmoperand : AsmOperandClass {let Name="MemUImm12Offset";}
153*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm12 : MemOperand,
154*9880d681SAndroid Build Coastguard Worker                       ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
155*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printAddrModeImm12Operand<false>";
156*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getAddrModeImm12OpValue";
157*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm12";
158*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2addrmode_imm12_asmoperand;
159*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
160*9880d681SAndroid Build Coastguard Worker}
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker// t2ldrlabel  := imm12
163*9880d681SAndroid Build Coastguard Workerdef t2ldrlabel : Operand<i32> {
164*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getAddrModeImm12OpValue";
165*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printThumbLdrLabelOperand";
166*9880d681SAndroid Build Coastguard Worker}
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Workerdef t2ldr_pcrel_imm12_asmoperand : AsmOperandClass {let Name = "MemPCRelImm12";}
169*9880d681SAndroid Build Coastguard Workerdef t2ldr_pcrel_imm12 : Operand<i32> {
170*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2ldr_pcrel_imm12_asmoperand;
171*9880d681SAndroid Build Coastguard Worker  // used for assembler pseudo instruction and maps to t2ldrlabel, so
172*9880d681SAndroid Build Coastguard Worker  // doesn't need encoder or print methods of its own.
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker// ADR instruction labels.
176*9880d681SAndroid Build Coastguard Workerdef t2adrlabel : Operand<i32> {
177*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AdrLabelOpValue";
178*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printAdrLabelOperand<0>";
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker// t2addrmode_posimm8  := reg + imm8
182*9880d681SAndroid Build Coastguard Workerdef MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";}
183*9880d681SAndroid Build Coastguard Workerdef t2addrmode_posimm8 : MemOperand {
184*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8Operand<false>";
185*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm8OpValue";
186*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm8";
187*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemPosImm8OffsetAsmOperand;
188*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
189*9880d681SAndroid Build Coastguard Worker}
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker// t2addrmode_negimm8  := reg - imm8
192*9880d681SAndroid Build Coastguard Workerdef MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";}
193*9880d681SAndroid Build Coastguard Workerdef t2addrmode_negimm8 : MemOperand,
194*9880d681SAndroid Build Coastguard Worker                      ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
195*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8Operand<false>";
196*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm8OpValue";
197*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm8";
198*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemNegImm8OffsetAsmOperand;
199*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
200*9880d681SAndroid Build Coastguard Worker}
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker// t2addrmode_imm8  := reg +/- imm8
203*9880d681SAndroid Build Coastguard Workerdef MemImm8OffsetAsmOperand : AsmOperandClass { let Name = "MemImm8Offset"; }
204*9880d681SAndroid Build Coastguard Workerclass T2AddrMode_Imm8 : MemOperand,
205*9880d681SAndroid Build Coastguard Worker                        ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
206*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm8OpValue";
207*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm8";
208*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemImm8OffsetAsmOperand;
209*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
210*9880d681SAndroid Build Coastguard Worker}
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm8 : T2AddrMode_Imm8 {
213*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8Operand<false>";
214*9880d681SAndroid Build Coastguard Worker}
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm8_pre : T2AddrMode_Imm8 {
217*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8Operand<true>";
218*9880d681SAndroid Build Coastguard Worker}
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Workerdef t2am_imm8_offset : MemOperand,
221*9880d681SAndroid Build Coastguard Worker                       ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
222*9880d681SAndroid Build Coastguard Worker                                      [], [SDNPWantRoot]> {
223*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8OffsetOperand";
224*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
225*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2Imm8";
226*9880d681SAndroid Build Coastguard Worker}
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker// t2addrmode_imm8s4  := reg +/- (imm8 << 2)
229*9880d681SAndroid Build Coastguard Workerdef MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";}
230*9880d681SAndroid Build Coastguard Workerclass T2AddrMode_Imm8s4 : MemOperand {
231*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm8s4OpValue";
232*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm8s4";
233*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemImm8s4OffsetAsmOperand;
234*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
235*9880d681SAndroid Build Coastguard Worker}
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm8s4 : T2AddrMode_Imm8s4 {
238*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8s4Operand<false>";
239*9880d681SAndroid Build Coastguard Worker}
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm8s4_pre : T2AddrMode_Imm8s4 {
242*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8s4Operand<true>";
243*9880d681SAndroid Build Coastguard Worker}
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Workerdef t2am_imm8s4_offset_asmoperand : AsmOperandClass { let Name = "Imm8s4"; }
246*9880d681SAndroid Build Coastguard Workerdef t2am_imm8s4_offset : MemOperand {
247*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
248*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2Imm8s4OpValue";
249*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2Imm8S4";
250*9880d681SAndroid Build Coastguard Worker}
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker// t2addrmode_imm0_1020s4  := reg + (imm8 << 2)
253*9880d681SAndroid Build Coastguard Workerdef MemImm0_1020s4OffsetAsmOperand : AsmOperandClass {
254*9880d681SAndroid Build Coastguard Worker  let Name = "MemImm0_1020s4Offset";
255*9880d681SAndroid Build Coastguard Worker}
256*9880d681SAndroid Build Coastguard Workerdef t2addrmode_imm0_1020s4 : MemOperand,
257*9880d681SAndroid Build Coastguard Worker                         ComplexPattern<i32, 2, "SelectT2AddrModeExclusive"> {
258*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeImm0_1020s4Operand";
259*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeImm0_1020s4OpValue";
260*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeImm0_1020s4";
261*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemImm0_1020s4OffsetAsmOperand;
262*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPRnopc:$base, i32imm:$offsimm);
263*9880d681SAndroid Build Coastguard Worker}
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker// t2addrmode_so_reg  := reg + (reg << imm2)
266*9880d681SAndroid Build Coastguard Workerdef t2addrmode_so_reg_asmoperand : AsmOperandClass {let Name="T2MemRegOffset";}
267*9880d681SAndroid Build Coastguard Workerdef t2addrmode_so_reg : MemOperand,
268*9880d681SAndroid Build Coastguard Worker                        ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
269*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printT2AddrModeSoRegOperand";
270*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getT2AddrModeSORegOpValue";
271*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2AddrModeSOReg";
272*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = t2addrmode_so_reg_asmoperand;
273*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPRnopc:$base, rGPR:$offsreg, i32imm:$offsimm);
274*9880d681SAndroid Build Coastguard Worker}
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker// Addresses for the TBB/TBH instructions.
277*9880d681SAndroid Build Coastguard Workerdef addrmode_tbb_asmoperand : AsmOperandClass { let Name = "MemTBB"; }
278*9880d681SAndroid Build Coastguard Workerdef addrmode_tbb : MemOperand {
279*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printAddrModeTBB";
280*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = addrmode_tbb_asmoperand;
281*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm);
282*9880d681SAndroid Build Coastguard Worker}
283*9880d681SAndroid Build Coastguard Workerdef addrmode_tbh_asmoperand : AsmOperandClass { let Name = "MemTBH"; }
284*9880d681SAndroid Build Coastguard Workerdef addrmode_tbh : MemOperand {
285*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printAddrModeTBH";
286*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = addrmode_tbh_asmoperand;
287*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm);
288*9880d681SAndroid Build Coastguard Worker}
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
291*9880d681SAndroid Build Coastguard Worker// Multiclass helpers...
292*9880d681SAndroid Build Coastguard Worker//
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Workerclass T2OneRegImm<dag oops, dag iops, InstrItinClass itin,
296*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
297*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
298*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
299*9880d681SAndroid Build Coastguard Worker  bits<12> imm;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
302*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
303*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
304*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
305*9880d681SAndroid Build Coastguard Worker}
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Workerclass T2sOneRegImm<dag oops, dag iops, InstrItinClass itin,
309*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
310*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
311*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
312*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
313*9880d681SAndroid Build Coastguard Worker  bits<12> imm;
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
316*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
317*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
318*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
319*9880d681SAndroid Build Coastguard Worker}
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Workerclass T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin,
322*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
323*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
324*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
325*9880d681SAndroid Build Coastguard Worker  bits<12> imm;
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker  let Inst{19-16}  = Rn;
328*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
329*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
330*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
331*9880d681SAndroid Build Coastguard Worker}
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker
334*9880d681SAndroid Build Coastguard Workerclass T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
335*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
336*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
337*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
338*9880d681SAndroid Build Coastguard Worker  bits<12> ShiftedRm;
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
341*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = ShiftedRm{3-0};
342*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = ShiftedRm{6-5};
343*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = ShiftedRm{11-9};
344*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = ShiftedRm{8-7};
345*9880d681SAndroid Build Coastguard Worker}
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Workerclass T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
348*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
349*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
350*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
351*9880d681SAndroid Build Coastguard Worker  bits<12> ShiftedRm;
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
354*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = ShiftedRm{3-0};
355*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = ShiftedRm{6-5};
356*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = ShiftedRm{11-9};
357*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = ShiftedRm{8-7};
358*9880d681SAndroid Build Coastguard Worker}
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Workerclass T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin,
361*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
362*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
363*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
364*9880d681SAndroid Build Coastguard Worker  bits<12> ShiftedRm;
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
367*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = ShiftedRm{3-0};
368*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = ShiftedRm{6-5};
369*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = ShiftedRm{11-9};
370*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = ShiftedRm{8-7};
371*9880d681SAndroid Build Coastguard Worker}
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Workerclass T2TwoReg<dag oops, dag iops, InstrItinClass itin,
374*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
375*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
376*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
377*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
380*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
381*9880d681SAndroid Build Coastguard Worker}
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Workerclass T2sTwoReg<dag oops, dag iops, InstrItinClass itin,
384*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
385*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
386*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
387*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
390*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
391*9880d681SAndroid Build Coastguard Worker}
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Workerclass T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin,
394*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
395*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
396*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
397*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
400*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
401*9880d681SAndroid Build Coastguard Worker}
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Workerclass T2TwoRegImm<dag oops, dag iops, InstrItinClass itin,
405*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
406*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
407*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
408*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
409*9880d681SAndroid Build Coastguard Worker  bits<12> imm;
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
412*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
413*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
414*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
415*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
416*9880d681SAndroid Build Coastguard Worker}
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Workerclass T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin,
419*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
420*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
421*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
422*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
423*9880d681SAndroid Build Coastguard Worker  bits<12> imm;
424*9880d681SAndroid Build Coastguard Worker
425*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
426*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
427*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
428*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
429*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
430*9880d681SAndroid Build Coastguard Worker}
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Workerclass T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
433*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
434*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
435*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
436*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
437*9880d681SAndroid Build Coastguard Worker  bits<5> imm;
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
440*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
441*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{4-2};
442*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = imm{1-0};
443*9880d681SAndroid Build Coastguard Worker}
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Workerclass T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin,
446*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
447*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
448*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
449*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
450*9880d681SAndroid Build Coastguard Worker  bits<5> imm;
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
453*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
454*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{4-2};
455*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = imm{1-0};
456*9880d681SAndroid Build Coastguard Worker}
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Workerclass T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
459*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
460*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
461*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
462*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
463*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
466*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
467*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
468*9880d681SAndroid Build Coastguard Worker}
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Workerclass T2ThreeRegNoP<dag oops, dag iops, InstrItinClass itin,
471*9880d681SAndroid Build Coastguard Worker           string asm, list<dag> pattern>
472*9880d681SAndroid Build Coastguard Worker  : T2XI<oops, iops, itin, asm, pattern> {
473*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
474*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
475*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
478*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
479*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
480*9880d681SAndroid Build Coastguard Worker}
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Workerclass T2sThreeReg<dag oops, dag iops, InstrItinClass itin,
483*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
484*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
485*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
486*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
487*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
490*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
491*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
492*9880d681SAndroid Build Coastguard Worker}
493*9880d681SAndroid Build Coastguard Worker
494*9880d681SAndroid Build Coastguard Workerclass T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
495*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
496*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
497*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
498*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
499*9880d681SAndroid Build Coastguard Worker  bits<12> ShiftedRm;
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
502*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
503*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = ShiftedRm{3-0};
504*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = ShiftedRm{6-5};
505*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = ShiftedRm{11-9};
506*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = ShiftedRm{8-7};
507*9880d681SAndroid Build Coastguard Worker}
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Workerclass T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
510*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
511*9880d681SAndroid Build Coastguard Worker  : T2sI<oops, iops, itin, opc, asm, pattern> {
512*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
513*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
514*9880d681SAndroid Build Coastguard Worker  bits<12> ShiftedRm;
515*9880d681SAndroid Build Coastguard Worker
516*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
517*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
518*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = ShiftedRm{3-0};
519*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = ShiftedRm{6-5};
520*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = ShiftedRm{11-9};
521*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = ShiftedRm{8-7};
522*9880d681SAndroid Build Coastguard Worker}
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Workerclass T2FourReg<dag oops, dag iops, InstrItinClass itin,
525*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
526*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
527*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
528*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
529*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
530*9880d681SAndroid Build Coastguard Worker  bits<4> Ra;
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
533*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Ra;
534*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
535*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
536*9880d681SAndroid Build Coastguard Worker}
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Workerclass T2MulLong<bits<3> opc22_20, bits<4> opc7_4,
539*9880d681SAndroid Build Coastguard Worker                dag oops, dag iops, InstrItinClass itin,
540*9880d681SAndroid Build Coastguard Worker                string opc, string asm, list<dag> pattern>
541*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
542*9880d681SAndroid Build Coastguard Worker  bits<4> RdLo;
543*9880d681SAndroid Build Coastguard Worker  bits<4> RdHi;
544*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
545*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker  let Inst{31-23} = 0b111110111;
548*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opc22_20;
549*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
550*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = RdLo;
551*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = RdHi;
552*9880d681SAndroid Build Coastguard Worker  let Inst{7-4}   = opc7_4;
553*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
554*9880d681SAndroid Build Coastguard Worker}
555*9880d681SAndroid Build Coastguard Workerclass T2MlaLong<bits<3> opc22_20, bits<4> opc7_4,
556*9880d681SAndroid Build Coastguard Worker                dag oops, dag iops, InstrItinClass itin,
557*9880d681SAndroid Build Coastguard Worker                string opc, string asm, list<dag> pattern>
558*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
559*9880d681SAndroid Build Coastguard Worker  bits<4> RdLo;
560*9880d681SAndroid Build Coastguard Worker  bits<4> RdHi;
561*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
562*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker  let Inst{31-23} = 0b111110111;
565*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opc22_20;
566*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
567*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = RdLo;
568*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = RdHi;
569*9880d681SAndroid Build Coastguard Worker  let Inst{7-4}   = opc7_4;
570*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
571*9880d681SAndroid Build Coastguard Worker}
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker
574*9880d681SAndroid Build Coastguard Worker/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
575*9880d681SAndroid Build Coastguard Worker/// binary operation that produces a value. These are predicable and can be
576*9880d681SAndroid Build Coastguard Worker/// changed to modify CPSR.
577*9880d681SAndroid Build Coastguard Workermulticlass T2I_bin_irs<bits<4> opcod, string opc,
578*9880d681SAndroid Build Coastguard Worker                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
579*9880d681SAndroid Build Coastguard Worker                     SDPatternOperator opnode, bit Commutable = 0,
580*9880d681SAndroid Build Coastguard Worker                     string wide = ""> {
581*9880d681SAndroid Build Coastguard Worker   // shifted imm
582*9880d681SAndroid Build Coastguard Worker   def ri : T2sTwoRegImm<
583*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii,
584*9880d681SAndroid Build Coastguard Worker                 opc, "\t$Rd, $Rn, $imm",
585*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>,
586*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU, ReadALU]> {
587*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
588*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
589*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
590*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
591*9880d681SAndroid Build Coastguard Worker   }
592*9880d681SAndroid Build Coastguard Worker   // register
593*9880d681SAndroid Build Coastguard Worker   def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir,
594*9880d681SAndroid Build Coastguard Worker                 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"),
595*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
596*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU, ReadALU, ReadALU]> {
597*9880d681SAndroid Build Coastguard Worker     let isCommutable = Commutable;
598*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
599*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
600*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
601*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
602*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
603*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
604*9880d681SAndroid Build Coastguard Worker   }
605*9880d681SAndroid Build Coastguard Worker   // shifted register
606*9880d681SAndroid Build Coastguard Worker   def rs : T2sTwoRegShiftedReg<
607*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis,
608*9880d681SAndroid Build Coastguard Worker                 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"),
609*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>,
610*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALUsi, ReadALU]>  {
611*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
612*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
613*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
614*9880d681SAndroid Build Coastguard Worker   }
615*9880d681SAndroid Build Coastguard Worker  // Assembly aliases for optional destination operand when it's the same
616*9880d681SAndroid Build Coastguard Worker  // as the source operand.
617*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p} $Rdn, $imm"),
618*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn,
619*9880d681SAndroid Build Coastguard Worker                                                    t2_so_imm:$imm, pred:$p,
620*9880d681SAndroid Build Coastguard Worker                                                    cc_out:$s)>;
621*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $Rm"),
622*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn,
623*9880d681SAndroid Build Coastguard Worker                                                    rGPR:$Rm, pred:$p,
624*9880d681SAndroid Build Coastguard Worker                                                    cc_out:$s)>;
625*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $shift"),
626*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn,
627*9880d681SAndroid Build Coastguard Worker                                                    t2_so_reg:$shift, pred:$p,
628*9880d681SAndroid Build Coastguard Worker                                                    cc_out:$s)>;
629*9880d681SAndroid Build Coastguard Worker}
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
632*9880d681SAndroid Build Coastguard Worker//  the ".w" suffix to indicate that they are wide.
633*9880d681SAndroid Build Coastguard Workermulticlass T2I_bin_w_irs<bits<4> opcod, string opc,
634*9880d681SAndroid Build Coastguard Worker                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
635*9880d681SAndroid Build Coastguard Worker                     SDPatternOperator opnode, bit Commutable = 0> :
636*9880d681SAndroid Build Coastguard Worker    T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w"> {
637*9880d681SAndroid Build Coastguard Worker  // Assembler aliases w/ the ".w" suffix.
638*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rd, $Rn, $imm"),
639*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p,
640*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
641*9880d681SAndroid Build Coastguard Worker  // Assembler aliases w/o the ".w" suffix.
642*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"),
643*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p,
644*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
645*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $shift"),
646*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rs") rGPR:$Rd, rGPR:$Rn, t2_so_reg:$shift,
647*9880d681SAndroid Build Coastguard Worker                                    pred:$p, cc_out:$s)>;
648*9880d681SAndroid Build Coastguard Worker
649*9880d681SAndroid Build Coastguard Worker  // and with the optional destination operand, too.
650*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rdn, $imm"),
651*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm,
652*9880d681SAndroid Build Coastguard Worker                                    pred:$p, cc_out:$s)>;
653*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"),
654*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p,
655*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
656*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $shift"),
657*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$shift,
658*9880d681SAndroid Build Coastguard Worker                                    pred:$p, cc_out:$s)>;
659*9880d681SAndroid Build Coastguard Worker}
660*9880d681SAndroid Build Coastguard Worker
661*9880d681SAndroid Build Coastguard Worker/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
662*9880d681SAndroid Build Coastguard Worker/// reversed.  The 'rr' form is only defined for the disassembler; for codegen
663*9880d681SAndroid Build Coastguard Worker/// it is equivalent to the T2I_bin_irs counterpart.
664*9880d681SAndroid Build Coastguard Workermulticlass T2I_rbin_irs<bits<4> opcod, string opc, SDNode opnode> {
665*9880d681SAndroid Build Coastguard Worker   // shifted imm
666*9880d681SAndroid Build Coastguard Worker   def ri : T2sTwoRegImm<
667*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
668*9880d681SAndroid Build Coastguard Worker                 opc, ".w\t$Rd, $Rn, $imm",
669*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]>,
670*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU, ReadALU]> {
671*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
672*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
673*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
674*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
675*9880d681SAndroid Build Coastguard Worker   }
676*9880d681SAndroid Build Coastguard Worker   // register
677*9880d681SAndroid Build Coastguard Worker   def rr : T2sThreeReg<
678*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
679*9880d681SAndroid Build Coastguard Worker                 opc, "\t$Rd, $Rn, $Rm",
680*9880d681SAndroid Build Coastguard Worker                 [/* For disassembly only; pattern left blank */]>,
681*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU, ReadALU, ReadALU]> {
682*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
683*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
684*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
685*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
686*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
687*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
688*9880d681SAndroid Build Coastguard Worker   }
689*9880d681SAndroid Build Coastguard Worker   // shifted register
690*9880d681SAndroid Build Coastguard Worker   def rs : T2sTwoRegShiftedReg<
691*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
692*9880d681SAndroid Build Coastguard Worker                 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm",
693*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]>,
694*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALUsi, ReadALU]> {
695*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
696*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
697*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
698*9880d681SAndroid Build Coastguard Worker   }
699*9880d681SAndroid Build Coastguard Worker}
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
702*9880d681SAndroid Build Coastguard Worker/// instruction modifies the CPSR register.
703*9880d681SAndroid Build Coastguard Worker///
704*9880d681SAndroid Build Coastguard Worker/// These opcodes will be converted to the real non-S opcodes by
705*9880d681SAndroid Build Coastguard Worker/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
706*9880d681SAndroid Build Coastguard Workerlet hasPostISelHook = 1, Defs = [CPSR] in {
707*9880d681SAndroid Build Coastguard Workermulticlass T2I_bin_s_irs<InstrItinClass iii, InstrItinClass iir,
708*9880d681SAndroid Build Coastguard Worker                         InstrItinClass iis, SDNode opnode,
709*9880d681SAndroid Build Coastguard Worker                         bit Commutable = 0> {
710*9880d681SAndroid Build Coastguard Worker   // shifted imm
711*9880d681SAndroid Build Coastguard Worker   def ri : t2PseudoInst<(outs rGPR:$Rd),
712*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rn, t2_so_imm:$imm, pred:$p),
713*9880d681SAndroid Build Coastguard Worker                         4, iii,
714*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
715*9880d681SAndroid Build Coastguard Worker                                                t2_so_imm:$imm))]>,
716*9880d681SAndroid Build Coastguard Worker            Sched<[WriteALU, ReadALU]>;
717*9880d681SAndroid Build Coastguard Worker   // register
718*9880d681SAndroid Build Coastguard Worker   def rr : t2PseudoInst<(outs rGPR:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm, pred:$p),
719*9880d681SAndroid Build Coastguard Worker                         4, iir,
720*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
721*9880d681SAndroid Build Coastguard Worker                                                rGPR:$Rm))]>,
722*9880d681SAndroid Build Coastguard Worker            Sched<[WriteALU, ReadALU, ReadALU]> {
723*9880d681SAndroid Build Coastguard Worker     let isCommutable = Commutable;
724*9880d681SAndroid Build Coastguard Worker   }
725*9880d681SAndroid Build Coastguard Worker   // shifted register
726*9880d681SAndroid Build Coastguard Worker   def rs : t2PseudoInst<(outs rGPR:$Rd),
727*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p),
728*9880d681SAndroid Build Coastguard Worker                         4, iis,
729*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn,
730*9880d681SAndroid Build Coastguard Worker                                                t2_so_reg:$ShiftedRm))]>,
731*9880d681SAndroid Build Coastguard Worker            Sched<[WriteALUsi, ReadALUsr]>;
732*9880d681SAndroid Build Coastguard Worker}
733*9880d681SAndroid Build Coastguard Worker}
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker/// T2I_rbin_s_is -  Same as T2I_bin_s_irs, except selection DAG
736*9880d681SAndroid Build Coastguard Worker/// operands are reversed.
737*9880d681SAndroid Build Coastguard Workerlet hasPostISelHook = 1, Defs = [CPSR] in {
738*9880d681SAndroid Build Coastguard Workermulticlass T2I_rbin_s_is<SDNode opnode> {
739*9880d681SAndroid Build Coastguard Worker   // shifted imm
740*9880d681SAndroid Build Coastguard Worker   def ri : t2PseudoInst<(outs rGPR:$Rd),
741*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rn, t2_so_imm:$imm, pred:$p),
742*9880d681SAndroid Build Coastguard Worker                         4, IIC_iALUi,
743*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm,
744*9880d681SAndroid Build Coastguard Worker                                                rGPR:$Rn))]>,
745*9880d681SAndroid Build Coastguard Worker            Sched<[WriteALU, ReadALU]>;
746*9880d681SAndroid Build Coastguard Worker   // shifted register
747*9880d681SAndroid Build Coastguard Worker   def rs : t2PseudoInst<(outs rGPR:$Rd),
748*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p),
749*9880d681SAndroid Build Coastguard Worker                         4, IIC_iALUsi,
750*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm,
751*9880d681SAndroid Build Coastguard Worker                                                rGPR:$Rn))]>,
752*9880d681SAndroid Build Coastguard Worker            Sched<[WriteALUsi, ReadALU]>;
753*9880d681SAndroid Build Coastguard Worker}
754*9880d681SAndroid Build Coastguard Worker}
755*9880d681SAndroid Build Coastguard Worker
756*9880d681SAndroid Build Coastguard Worker/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
757*9880d681SAndroid Build Coastguard Worker/// patterns for a binary operation that produces a value.
758*9880d681SAndroid Build Coastguard Workermulticlass T2I_bin_ii12rs<bits<3> op23_21, string opc, SDNode opnode,
759*9880d681SAndroid Build Coastguard Worker                          bit Commutable = 0> {
760*9880d681SAndroid Build Coastguard Worker   // shifted imm
761*9880d681SAndroid Build Coastguard Worker   // The register-immediate version is re-materializable. This is useful
762*9880d681SAndroid Build Coastguard Worker   // in particular for taking the address of a local.
763*9880d681SAndroid Build Coastguard Worker   let isReMaterializable = 1 in {
764*9880d681SAndroid Build Coastguard Worker   def ri : T2sTwoRegImm<
765*9880d681SAndroid Build Coastguard Worker               (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi,
766*9880d681SAndroid Build Coastguard Worker               opc, ".w\t$Rd, $Rn, $imm",
767*9880d681SAndroid Build Coastguard Worker               [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>,
768*9880d681SAndroid Build Coastguard Worker               Sched<[WriteALU, ReadALU]> {
769*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
770*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
771*9880d681SAndroid Build Coastguard Worker     let Inst{24} = 1;
772*9880d681SAndroid Build Coastguard Worker     let Inst{23-21} = op23_21;
773*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
774*9880d681SAndroid Build Coastguard Worker   }
775*9880d681SAndroid Build Coastguard Worker   }
776*9880d681SAndroid Build Coastguard Worker   // 12-bit imm
777*9880d681SAndroid Build Coastguard Worker   def ri12 : T2I<
778*9880d681SAndroid Build Coastguard Worker                  (outs GPRnopc:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
779*9880d681SAndroid Build Coastguard Worker                  !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
780*9880d681SAndroid Build Coastguard Worker                  [(set GPRnopc:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>,
781*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteALU, ReadALU]> {
782*9880d681SAndroid Build Coastguard Worker     bits<4> Rd;
783*9880d681SAndroid Build Coastguard Worker     bits<4> Rn;
784*9880d681SAndroid Build Coastguard Worker     bits<12> imm;
785*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
786*9880d681SAndroid Build Coastguard Worker     let Inst{26} = imm{11};
787*9880d681SAndroid Build Coastguard Worker     let Inst{25-24} = 0b10;
788*9880d681SAndroid Build Coastguard Worker     let Inst{23-21} = op23_21;
789*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 0; // The S bit.
790*9880d681SAndroid Build Coastguard Worker     let Inst{19-16} = Rn;
791*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
792*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = imm{10-8};
793*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = Rd;
794*9880d681SAndroid Build Coastguard Worker     let Inst{7-0} = imm{7-0};
795*9880d681SAndroid Build Coastguard Worker   }
796*9880d681SAndroid Build Coastguard Worker   // register
797*9880d681SAndroid Build Coastguard Worker   def rr : T2sThreeReg<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm),
798*9880d681SAndroid Build Coastguard Worker                 IIC_iALUr, opc, ".w\t$Rd, $Rn, $Rm",
799*9880d681SAndroid Build Coastguard Worker                 [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, rGPR:$Rm))]>,
800*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU, ReadALU, ReadALU]> {
801*9880d681SAndroid Build Coastguard Worker     let isCommutable = Commutable;
802*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
803*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
804*9880d681SAndroid Build Coastguard Worker     let Inst{24} = 1;
805*9880d681SAndroid Build Coastguard Worker     let Inst{23-21} = op23_21;
806*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
807*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
808*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
809*9880d681SAndroid Build Coastguard Worker   }
810*9880d681SAndroid Build Coastguard Worker   // shifted register
811*9880d681SAndroid Build Coastguard Worker   def rs : T2sTwoRegShiftedReg<
812*9880d681SAndroid Build Coastguard Worker                 (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm),
813*9880d681SAndroid Build Coastguard Worker                 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
814*9880d681SAndroid Build Coastguard Worker              [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>,
815*9880d681SAndroid Build Coastguard Worker              Sched<[WriteALUsi, ReadALU]> {
816*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
817*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
818*9880d681SAndroid Build Coastguard Worker     let Inst{24} = 1;
819*9880d681SAndroid Build Coastguard Worker     let Inst{23-21} = op23_21;
820*9880d681SAndroid Build Coastguard Worker   }
821*9880d681SAndroid Build Coastguard Worker}
822*9880d681SAndroid Build Coastguard Worker
823*9880d681SAndroid Build Coastguard Worker/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
824*9880d681SAndroid Build Coastguard Worker/// for a binary operation that produces a value and use the carry
825*9880d681SAndroid Build Coastguard Worker/// bit. It's not predicable.
826*9880d681SAndroid Build Coastguard Workerlet Defs = [CPSR], Uses = [CPSR] in {
827*9880d681SAndroid Build Coastguard Workermulticlass T2I_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode,
828*9880d681SAndroid Build Coastguard Worker                             bit Commutable = 0> {
829*9880d681SAndroid Build Coastguard Worker   // shifted imm
830*9880d681SAndroid Build Coastguard Worker   def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm),
831*9880d681SAndroid Build Coastguard Worker                 IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
832*9880d681SAndroid Build Coastguard Worker               [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_imm:$imm, CPSR))]>,
833*9880d681SAndroid Build Coastguard Worker                 Requires<[IsThumb2]>, Sched<[WriteALU, ReadALU]> {
834*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
835*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
836*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
837*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
838*9880d681SAndroid Build Coastguard Worker   }
839*9880d681SAndroid Build Coastguard Worker   // register
840*9880d681SAndroid Build Coastguard Worker   def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr,
841*9880d681SAndroid Build Coastguard Worker                 opc, ".w\t$Rd, $Rn, $Rm",
842*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, rGPR:$Rm, CPSR))]>,
843*9880d681SAndroid Build Coastguard Worker                 Requires<[IsThumb2]>, Sched<[WriteALU, ReadALU, ReadALU]> {
844*9880d681SAndroid Build Coastguard Worker     let isCommutable = Commutable;
845*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
846*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
847*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
848*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
849*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
850*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
851*9880d681SAndroid Build Coastguard Worker   }
852*9880d681SAndroid Build Coastguard Worker   // shifted register
853*9880d681SAndroid Build Coastguard Worker   def rs : T2sTwoRegShiftedReg<
854*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
855*9880d681SAndroid Build Coastguard Worker                 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm",
856*9880d681SAndroid Build Coastguard Worker         [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm, CPSR))]>,
857*9880d681SAndroid Build Coastguard Worker                 Requires<[IsThumb2]>, Sched<[WriteALUsi, ReadALU]> {
858*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
859*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
860*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
861*9880d681SAndroid Build Coastguard Worker   }
862*9880d681SAndroid Build Coastguard Worker}
863*9880d681SAndroid Build Coastguard Worker}
864*9880d681SAndroid Build Coastguard Worker
865*9880d681SAndroid Build Coastguard Worker/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
866*9880d681SAndroid Build Coastguard Worker//  rotate operation that produces a value.
867*9880d681SAndroid Build Coastguard Workermulticlass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, SDNode opnode> {
868*9880d681SAndroid Build Coastguard Worker   // 5-bit imm
869*9880d681SAndroid Build Coastguard Worker   def ri : T2sTwoRegShiftImm<
870*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rm, ty:$imm), IIC_iMOVsi,
871*9880d681SAndroid Build Coastguard Worker                 opc, ".w\t$Rd, $Rm, $imm",
872*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode rGPR:$Rm, (i32 ty:$imm)))]>,
873*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU]> {
874*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
875*9880d681SAndroid Build Coastguard Worker     let Inst{26-21} = 0b010010;
876*9880d681SAndroid Build Coastguard Worker     let Inst{19-16} = 0b1111; // Rn
877*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = opcod;
878*9880d681SAndroid Build Coastguard Worker   }
879*9880d681SAndroid Build Coastguard Worker   // register
880*9880d681SAndroid Build Coastguard Worker   def rr : T2sThreeReg<
881*9880d681SAndroid Build Coastguard Worker                 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr,
882*9880d681SAndroid Build Coastguard Worker                 opc, ".w\t$Rd, $Rn, $Rm",
883*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>,
884*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU]> {
885*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11111;
886*9880d681SAndroid Build Coastguard Worker     let Inst{26-23} = 0b0100;
887*9880d681SAndroid Build Coastguard Worker     let Inst{22-21} = opcod;
888*9880d681SAndroid Build Coastguard Worker     let Inst{15-12} = 0b1111;
889*9880d681SAndroid Build Coastguard Worker     let Inst{7-4} = 0b0000;
890*9880d681SAndroid Build Coastguard Worker   }
891*9880d681SAndroid Build Coastguard Worker
892*9880d681SAndroid Build Coastguard Worker  // Optional destination register
893*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $imm"),
894*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p,
895*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
896*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $Rm"),
897*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p,
898*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
899*9880d681SAndroid Build Coastguard Worker
900*9880d681SAndroid Build Coastguard Worker  // Assembler aliases w/o the ".w" suffix.
901*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $imm"),
902*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, ty:$imm, pred:$p,
903*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
904*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"),
905*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p,
906*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker  // and with the optional destination operand, too.
909*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $imm"),
910*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p,
911*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
912*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"),
913*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p,
914*9880d681SAndroid Build Coastguard Worker                                    cc_out:$s)>;
915*9880d681SAndroid Build Coastguard Worker}
916*9880d681SAndroid Build Coastguard Worker
917*9880d681SAndroid Build Coastguard Worker/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
918*9880d681SAndroid Build Coastguard Worker/// patterns. Similar to T2I_bin_irs except the instruction does not produce
919*9880d681SAndroid Build Coastguard Worker/// a explicit result, only implicitly set CPSR.
920*9880d681SAndroid Build Coastguard Workermulticlass T2I_cmp_irs<bits<4> opcod, string opc,
921*9880d681SAndroid Build Coastguard Worker                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
922*9880d681SAndroid Build Coastguard Worker                     SDPatternOperator opnode> {
923*9880d681SAndroid Build Coastguard Workerlet isCompare = 1, Defs = [CPSR] in {
924*9880d681SAndroid Build Coastguard Worker   // shifted imm
925*9880d681SAndroid Build Coastguard Worker   def ri : T2OneRegCmpImm<
926*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), iii,
927*9880d681SAndroid Build Coastguard Worker                opc, ".w\t$Rn, $imm",
928*9880d681SAndroid Build Coastguard Worker                [(opnode GPRnopc:$Rn, t2_so_imm:$imm)]>, Sched<[WriteCMP]> {
929*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
930*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
931*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
932*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
933*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
934*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
935*9880d681SAndroid Build Coastguard Worker   }
936*9880d681SAndroid Build Coastguard Worker   // register
937*9880d681SAndroid Build Coastguard Worker   def rr : T2TwoRegCmp<
938*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, rGPR:$Rm), iir,
939*9880d681SAndroid Build Coastguard Worker                opc, ".w\t$Rn, $Rm",
940*9880d681SAndroid Build Coastguard Worker                [(opnode GPRnopc:$Rn, rGPR:$Rm)]>, Sched<[WriteCMP]> {
941*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
942*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
943*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
944*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
945*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
946*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
947*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
948*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
949*9880d681SAndroid Build Coastguard Worker   }
950*9880d681SAndroid Build Coastguard Worker   // shifted register
951*9880d681SAndroid Build Coastguard Worker   def rs : T2OneRegCmpShiftedReg<
952*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), iis,
953*9880d681SAndroid Build Coastguard Worker                opc, ".w\t$Rn, $ShiftedRm",
954*9880d681SAndroid Build Coastguard Worker                [(opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]>,
955*9880d681SAndroid Build Coastguard Worker                Sched<[WriteCMPsi]> {
956*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
957*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
958*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
959*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
960*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
961*9880d681SAndroid Build Coastguard Worker   }
962*9880d681SAndroid Build Coastguard Worker}
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker  // Assembler aliases w/o the ".w" suffix.
965*9880d681SAndroid Build Coastguard Worker  // No alias here for 'rr' version as not all instantiations of this
966*9880d681SAndroid Build Coastguard Worker  // multiclass want one (CMP in particular, does not).
967*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $imm"),
968*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"ri") GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>;
969*9880d681SAndroid Build Coastguard Worker  def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $shift"),
970*9880d681SAndroid Build Coastguard Worker     (!cast<Instruction>(NAME#"rs") GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>;
971*9880d681SAndroid Build Coastguard Worker}
972*9880d681SAndroid Build Coastguard Worker
973*9880d681SAndroid Build Coastguard Worker/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
974*9880d681SAndroid Build Coastguard Workermulticlass T2I_ld<bit signed, bits<2> opcod, string opc,
975*9880d681SAndroid Build Coastguard Worker                  InstrItinClass iii, InstrItinClass iis, RegisterClass target,
976*9880d681SAndroid Build Coastguard Worker                  PatFrag opnode> {
977*9880d681SAndroid Build Coastguard Worker  def i12 : T2Ii12<(outs target:$Rt), (ins t2addrmode_imm12:$addr), iii,
978*9880d681SAndroid Build Coastguard Worker                   opc, ".w\t$Rt, $addr",
979*9880d681SAndroid Build Coastguard Worker                   [(set target:$Rt, (opnode t2addrmode_imm12:$addr))]> {
980*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
981*9880d681SAndroid Build Coastguard Worker    bits<17> addr;
982*9880d681SAndroid Build Coastguard Worker    let Inst{31-25} = 0b1111100;
983*9880d681SAndroid Build Coastguard Worker    let Inst{24} = signed;
984*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 1;
985*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
986*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1; // load
987*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{16-13}; // Rn
988*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
989*9880d681SAndroid Build Coastguard Worker    let Inst{11-0}  = addr{11-0};  // imm
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadImm12";
992*9880d681SAndroid Build Coastguard Worker  }
993*9880d681SAndroid Build Coastguard Worker  def i8  : T2Ii8 <(outs target:$Rt), (ins t2addrmode_negimm8:$addr), iii,
994*9880d681SAndroid Build Coastguard Worker                   opc, "\t$Rt, $addr",
995*9880d681SAndroid Build Coastguard Worker                   [(set target:$Rt, (opnode t2addrmode_negimm8:$addr))]> {
996*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
997*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
998*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
999*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1000*9880d681SAndroid Build Coastguard Worker    let Inst{24} = signed;
1001*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 0;
1002*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1003*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1; // load
1004*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{12-9}; // Rn
1005*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
1006*9880d681SAndroid Build Coastguard Worker    let Inst{11} = 1;
1007*9880d681SAndroid Build Coastguard Worker    // Offset: index==TRUE, wback==FALSE
1008*9880d681SAndroid Build Coastguard Worker    let Inst{10} = 1; // The P bit.
1009*9880d681SAndroid Build Coastguard Worker    let Inst{9}     = addr{8};    // U
1010*9880d681SAndroid Build Coastguard Worker    let Inst{8} = 0; // The W bit.
1011*9880d681SAndroid Build Coastguard Worker    let Inst{7-0}   = addr{7-0};  // imm
1012*9880d681SAndroid Build Coastguard Worker
1013*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadImm8";
1014*9880d681SAndroid Build Coastguard Worker  }
1015*9880d681SAndroid Build Coastguard Worker  def s   : T2Iso <(outs target:$Rt), (ins t2addrmode_so_reg:$addr), iis,
1016*9880d681SAndroid Build Coastguard Worker                   opc, ".w\t$Rt, $addr",
1017*9880d681SAndroid Build Coastguard Worker                   [(set target:$Rt, (opnode t2addrmode_so_reg:$addr))]> {
1018*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
1019*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1020*9880d681SAndroid Build Coastguard Worker    let Inst{24} = signed;
1021*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 0;
1022*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1023*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1; // load
1024*9880d681SAndroid Build Coastguard Worker    let Inst{11-6} = 0b000000;
1025*9880d681SAndroid Build Coastguard Worker
1026*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
1027*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Worker    bits<10> addr;
1030*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{9-6}; // Rn
1031*9880d681SAndroid Build Coastguard Worker    let Inst{3-0}   = addr{5-2}; // Rm
1032*9880d681SAndroid Build Coastguard Worker    let Inst{5-4}   = addr{1-0}; // imm
1033*9880d681SAndroid Build Coastguard Worker
1034*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadShift";
1035*9880d681SAndroid Build Coastguard Worker  }
1036*9880d681SAndroid Build Coastguard Worker
1037*9880d681SAndroid Build Coastguard Worker  // pci variant is very similar to i12, but supports negative offsets
1038*9880d681SAndroid Build Coastguard Worker  // from the PC.
1039*9880d681SAndroid Build Coastguard Worker  def pci : T2Ipc <(outs target:$Rt), (ins t2ldrlabel:$addr), iii,
1040*9880d681SAndroid Build Coastguard Worker                   opc, ".w\t$Rt, $addr",
1041*9880d681SAndroid Build Coastguard Worker                   [(set target:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
1042*9880d681SAndroid Build Coastguard Worker    let isReMaterializable = 1;
1043*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
1044*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1045*9880d681SAndroid Build Coastguard Worker    let Inst{24} = signed;
1046*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1047*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1; // load
1048*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = 0b1111; // Rn
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
1051*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt{3-0};
1052*9880d681SAndroid Build Coastguard Worker
1053*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
1054*9880d681SAndroid Build Coastguard Worker    let Inst{23} = addr{12}; // add = (U == '1')
1055*9880d681SAndroid Build Coastguard Worker    let Inst{11-0}  = addr{11-0};
1056*9880d681SAndroid Build Coastguard Worker
1057*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadLabel";
1058*9880d681SAndroid Build Coastguard Worker  }
1059*9880d681SAndroid Build Coastguard Worker}
1060*9880d681SAndroid Build Coastguard Worker
1061*9880d681SAndroid Build Coastguard Worker/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
1062*9880d681SAndroid Build Coastguard Workermulticlass T2I_st<bits<2> opcod, string opc,
1063*9880d681SAndroid Build Coastguard Worker                  InstrItinClass iii, InstrItinClass iis, RegisterClass target,
1064*9880d681SAndroid Build Coastguard Worker                  PatFrag opnode> {
1065*9880d681SAndroid Build Coastguard Worker  def i12 : T2Ii12<(outs), (ins target:$Rt, t2addrmode_imm12:$addr), iii,
1066*9880d681SAndroid Build Coastguard Worker                   opc, ".w\t$Rt, $addr",
1067*9880d681SAndroid Build Coastguard Worker                   [(opnode target:$Rt, t2addrmode_imm12:$addr)]> {
1068*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
1069*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0001;
1070*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1071*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 0; // !load
1072*9880d681SAndroid Build Coastguard Worker
1073*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
1074*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
1075*9880d681SAndroid Build Coastguard Worker
1076*9880d681SAndroid Build Coastguard Worker    bits<17> addr;
1077*9880d681SAndroid Build Coastguard Worker    let addr{12}    = 1;           // add = TRUE
1078*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{16-13}; // Rn
1079*9880d681SAndroid Build Coastguard Worker    let Inst{23}    = addr{12};    // U
1080*9880d681SAndroid Build Coastguard Worker    let Inst{11-0}  = addr{11-0};  // imm
1081*9880d681SAndroid Build Coastguard Worker  }
1082*9880d681SAndroid Build Coastguard Worker  def i8  : T2Ii8 <(outs), (ins target:$Rt, t2addrmode_negimm8:$addr), iii,
1083*9880d681SAndroid Build Coastguard Worker                   opc, "\t$Rt, $addr",
1084*9880d681SAndroid Build Coastguard Worker                   [(opnode target:$Rt, t2addrmode_negimm8:$addr)]> {
1085*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
1086*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0000;
1087*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1088*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 0; // !load
1089*9880d681SAndroid Build Coastguard Worker    let Inst{11} = 1;
1090*9880d681SAndroid Build Coastguard Worker    // Offset: index==TRUE, wback==FALSE
1091*9880d681SAndroid Build Coastguard Worker    let Inst{10} = 1; // The P bit.
1092*9880d681SAndroid Build Coastguard Worker    let Inst{8} = 0; // The W bit.
1093*9880d681SAndroid Build Coastguard Worker
1094*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
1095*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
1096*9880d681SAndroid Build Coastguard Worker
1097*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
1098*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{12-9}; // Rn
1099*9880d681SAndroid Build Coastguard Worker    let Inst{9}     = addr{8};    // U
1100*9880d681SAndroid Build Coastguard Worker    let Inst{7-0}   = addr{7-0};  // imm
1101*9880d681SAndroid Build Coastguard Worker  }
1102*9880d681SAndroid Build Coastguard Worker  def s   : T2Iso <(outs), (ins target:$Rt, t2addrmode_so_reg:$addr), iis,
1103*9880d681SAndroid Build Coastguard Worker                   opc, ".w\t$Rt, $addr",
1104*9880d681SAndroid Build Coastguard Worker                   [(opnode target:$Rt, t2addrmode_so_reg:$addr)]> {
1105*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
1106*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0000;
1107*9880d681SAndroid Build Coastguard Worker    let Inst{22-21} = opcod;
1108*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 0; // !load
1109*9880d681SAndroid Build Coastguard Worker    let Inst{11-6} = 0b000000;
1110*9880d681SAndroid Build Coastguard Worker
1111*9880d681SAndroid Build Coastguard Worker    bits<4> Rt;
1112*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = Rt;
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Worker    bits<10> addr;
1115*9880d681SAndroid Build Coastguard Worker    let Inst{19-16}   = addr{9-6}; // Rn
1116*9880d681SAndroid Build Coastguard Worker    let Inst{3-0} = addr{5-2}; // Rm
1117*9880d681SAndroid Build Coastguard Worker    let Inst{5-4}   = addr{1-0}; // imm
1118*9880d681SAndroid Build Coastguard Worker  }
1119*9880d681SAndroid Build Coastguard Worker}
1120*9880d681SAndroid Build Coastguard Worker
1121*9880d681SAndroid Build Coastguard Worker/// T2I_ext_rrot - A unary operation with two forms: one whose operand is a
1122*9880d681SAndroid Build Coastguard Worker/// register and one whose operand is a register rotated by 8/16/24.
1123*9880d681SAndroid Build Coastguard Workerclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode>
1124*9880d681SAndroid Build Coastguard Worker  : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
1125*9880d681SAndroid Build Coastguard Worker             opc, ".w\t$Rd, $Rm$rot",
1126*9880d681SAndroid Build Coastguard Worker             [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1127*9880d681SAndroid Build Coastguard Worker             Requires<[IsThumb2]> {
1128*9880d681SAndroid Build Coastguard Worker   let Inst{31-27} = 0b11111;
1129*9880d681SAndroid Build Coastguard Worker   let Inst{26-23} = 0b0100;
1130*9880d681SAndroid Build Coastguard Worker   let Inst{22-20} = opcod;
1131*9880d681SAndroid Build Coastguard Worker   let Inst{19-16} = 0b1111; // Rn
1132*9880d681SAndroid Build Coastguard Worker   let Inst{15-12} = 0b1111;
1133*9880d681SAndroid Build Coastguard Worker   let Inst{7} = 1;
1134*9880d681SAndroid Build Coastguard Worker
1135*9880d681SAndroid Build Coastguard Worker   bits<2> rot;
1136*9880d681SAndroid Build Coastguard Worker   let Inst{5-4} = rot{1-0}; // rotate
1137*9880d681SAndroid Build Coastguard Worker}
1138*9880d681SAndroid Build Coastguard Worker
1139*9880d681SAndroid Build Coastguard Worker// UXTB16 - Requres T2ExtractPack, does not need the .w qualifier.
1140*9880d681SAndroid Build Coastguard Workerclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode>
1141*9880d681SAndroid Build Coastguard Worker  : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot),
1142*9880d681SAndroid Build Coastguard Worker             IIC_iEXTr, opc, "\t$Rd, $Rm$rot",
1143*9880d681SAndroid Build Coastguard Worker            [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
1144*9880d681SAndroid Build Coastguard Worker          Requires<[HasT2ExtractPack, IsThumb2]> {
1145*9880d681SAndroid Build Coastguard Worker  bits<2> rot;
1146*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1147*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0100;
1148*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opcod;
1149*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
1150*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
1151*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 1;
1152*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = rot;
1153*9880d681SAndroid Build Coastguard Worker}
1154*9880d681SAndroid Build Coastguard Worker
1155*9880d681SAndroid Build Coastguard Worker// SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern
1156*9880d681SAndroid Build Coastguard Worker// supported yet.
1157*9880d681SAndroid Build Coastguard Workerclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc>
1158*9880d681SAndroid Build Coastguard Worker  : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
1159*9880d681SAndroid Build Coastguard Worker             opc, "\t$Rd, $Rm$rot", []>,
1160*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasT2ExtractPack]> {
1161*9880d681SAndroid Build Coastguard Worker  bits<2> rot;
1162*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1163*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0100;
1164*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opcod;
1165*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
1166*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
1167*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 1;
1168*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = rot;
1169*9880d681SAndroid Build Coastguard Worker}
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Worker/// T2I_exta_rrot - A binary operation with two forms: one whose operand is a
1172*9880d681SAndroid Build Coastguard Worker/// register and one whose operand is a register rotated by 8/16/24.
1173*9880d681SAndroid Build Coastguard Workerclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode>
1174*9880d681SAndroid Build Coastguard Worker  : T2ThreeReg<(outs rGPR:$Rd),
1175*9880d681SAndroid Build Coastguard Worker               (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
1176*9880d681SAndroid Build Coastguard Worker               IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot",
1177*9880d681SAndroid Build Coastguard Worker             [(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm,rot_imm:$rot)))]>,
1178*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]> {
1179*9880d681SAndroid Build Coastguard Worker  bits<2> rot;
1180*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1181*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0100;
1182*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opcod;
1183*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
1184*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 1;
1185*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = rot;
1186*9880d681SAndroid Build Coastguard Worker}
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Workerclass T2I_exta_rrot_np<bits<3> opcod, string opc>
1189*9880d681SAndroid Build Coastguard Worker  : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot),
1190*9880d681SAndroid Build Coastguard Worker               IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", []>,
1191*9880d681SAndroid Build Coastguard Worker               Requires<[HasT2ExtractPack, IsThumb2]> {
1192*9880d681SAndroid Build Coastguard Worker  bits<2> rot;
1193*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1194*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0100;
1195*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = opcod;
1196*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
1197*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 1;
1198*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = rot;
1199*9880d681SAndroid Build Coastguard Worker}
1200*9880d681SAndroid Build Coastguard Worker
1201*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1202*9880d681SAndroid Build Coastguard Worker// Instructions
1203*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1204*9880d681SAndroid Build Coastguard Worker
1205*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1206*9880d681SAndroid Build Coastguard Worker//  Miscellaneous Instructions.
1207*9880d681SAndroid Build Coastguard Worker//
1208*9880d681SAndroid Build Coastguard Worker
1209*9880d681SAndroid Build Coastguard Workerclass T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin,
1210*9880d681SAndroid Build Coastguard Worker           string asm, list<dag> pattern>
1211*9880d681SAndroid Build Coastguard Worker  : T2XI<oops, iops, itin, asm, pattern> {
1212*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
1213*9880d681SAndroid Build Coastguard Worker  bits<12> label;
1214*9880d681SAndroid Build Coastguard Worker
1215*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
1216*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = label{11};
1217*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = label{10-8};
1218*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = label{7-0};
1219*9880d681SAndroid Build Coastguard Worker}
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker// LEApcrel - Load a pc-relative address into a register without offending the
1222*9880d681SAndroid Build Coastguard Worker// assembler.
1223*9880d681SAndroid Build Coastguard Workerdef t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
1224*9880d681SAndroid Build Coastguard Worker              (ins t2adrlabel:$addr, pred:$p),
1225*9880d681SAndroid Build Coastguard Worker              IIC_iALUi, "adr{$p}.w\t$Rd, $addr", []>,
1226*9880d681SAndroid Build Coastguard Worker              Sched<[WriteALU, ReadALU]> {
1227*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
1228*9880d681SAndroid Build Coastguard Worker  let Inst{25-24} = 0b10;
1229*9880d681SAndroid Build Coastguard Worker  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
1230*9880d681SAndroid Build Coastguard Worker  let Inst{22} = 0;
1231*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0;
1232*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
1233*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
1234*9880d681SAndroid Build Coastguard Worker
1235*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
1236*9880d681SAndroid Build Coastguard Worker  bits<13> addr;
1237*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rd;
1238*9880d681SAndroid Build Coastguard Worker  let Inst{23}    = addr{12};
1239*9880d681SAndroid Build Coastguard Worker  let Inst{21}    = addr{12};
1240*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = addr{11};
1241*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = addr{10-8};
1242*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = addr{7-0};
1243*9880d681SAndroid Build Coastguard Worker
1244*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2Adr";
1245*9880d681SAndroid Build Coastguard Worker}
1246*9880d681SAndroid Build Coastguard Worker
1247*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isReMaterializable = 1 in
1248*9880d681SAndroid Build Coastguard Workerdef t2LEApcrel   : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
1249*9880d681SAndroid Build Coastguard Worker                                4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>;
1250*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1 in
1251*9880d681SAndroid Build Coastguard Workerdef t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd),
1252*9880d681SAndroid Build Coastguard Worker                                (ins i32imm:$label, pred:$p),
1253*9880d681SAndroid Build Coastguard Worker                                4, IIC_iALUi,
1254*9880d681SAndroid Build Coastguard Worker                                []>, Sched<[WriteALU, ReadALU]>;
1255*9880d681SAndroid Build Coastguard Worker
1256*9880d681SAndroid Build Coastguard Worker
1257*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1258*9880d681SAndroid Build Coastguard Worker//  Load / store Instructions.
1259*9880d681SAndroid Build Coastguard Worker//
1260*9880d681SAndroid Build Coastguard Worker
1261*9880d681SAndroid Build Coastguard Worker// Load
1262*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, isReMaterializable = 1  in
1263*9880d681SAndroid Build Coastguard Workerdefm t2LDR   : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si, GPR, load>;
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker// Loads with zero extension
1266*9880d681SAndroid Build Coastguard Workerdefm t2LDRH  : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1267*9880d681SAndroid Build Coastguard Worker                      GPRnopc, zextloadi16>;
1268*9880d681SAndroid Build Coastguard Workerdefm t2LDRB  : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1269*9880d681SAndroid Build Coastguard Worker                      GPRnopc, zextloadi8>;
1270*9880d681SAndroid Build Coastguard Worker
1271*9880d681SAndroid Build Coastguard Worker// Loads with sign extension
1272*9880d681SAndroid Build Coastguard Workerdefm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1273*9880d681SAndroid Build Coastguard Worker                      GPRnopc, sextloadi16>;
1274*9880d681SAndroid Build Coastguard Workerdefm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si,
1275*9880d681SAndroid Build Coastguard Worker                      GPRnopc, sextloadi8>;
1276*9880d681SAndroid Build Coastguard Worker
1277*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
1278*9880d681SAndroid Build Coastguard Worker// Load doubleword
1279*9880d681SAndroid Build Coastguard Workerdef t2LDRDi8  : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
1280*9880d681SAndroid Build Coastguard Worker                        (ins t2addrmode_imm8s4:$addr),
1281*9880d681SAndroid Build Coastguard Worker                        IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", "", []>;
1282*9880d681SAndroid Build Coastguard Worker} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1
1283*9880d681SAndroid Build Coastguard Worker
1284*9880d681SAndroid Build Coastguard Worker// zextload i1 -> zextload i8
1285*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
1286*9880d681SAndroid Build Coastguard Worker            (t2LDRBi12  t2addrmode_imm12:$addr)>;
1287*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(zextloadi1 t2addrmode_negimm8:$addr),
1288*9880d681SAndroid Build Coastguard Worker            (t2LDRBi8   t2addrmode_negimm8:$addr)>;
1289*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
1290*9880d681SAndroid Build Coastguard Worker            (t2LDRBs    t2addrmode_so_reg:$addr)>;
1291*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
1292*9880d681SAndroid Build Coastguard Worker            (t2LDRBpci  tconstpool:$addr)>;
1293*9880d681SAndroid Build Coastguard Worker
1294*9880d681SAndroid Build Coastguard Worker// extload -> zextload
1295*9880d681SAndroid Build Coastguard Worker// FIXME: Reduce the number of patterns by legalizing extload to zextload
1296*9880d681SAndroid Build Coastguard Worker// earlier?
1297*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi1  t2addrmode_imm12:$addr),
1298*9880d681SAndroid Build Coastguard Worker            (t2LDRBi12  t2addrmode_imm12:$addr)>;
1299*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi1  t2addrmode_negimm8:$addr),
1300*9880d681SAndroid Build Coastguard Worker            (t2LDRBi8   t2addrmode_negimm8:$addr)>;
1301*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi1  t2addrmode_so_reg:$addr),
1302*9880d681SAndroid Build Coastguard Worker            (t2LDRBs    t2addrmode_so_reg:$addr)>;
1303*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi1  (ARMWrapper tconstpool:$addr)),
1304*9880d681SAndroid Build Coastguard Worker            (t2LDRBpci  tconstpool:$addr)>;
1305*9880d681SAndroid Build Coastguard Worker
1306*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi8  t2addrmode_imm12:$addr),
1307*9880d681SAndroid Build Coastguard Worker            (t2LDRBi12  t2addrmode_imm12:$addr)>;
1308*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi8  t2addrmode_negimm8:$addr),
1309*9880d681SAndroid Build Coastguard Worker            (t2LDRBi8   t2addrmode_negimm8:$addr)>;
1310*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi8  t2addrmode_so_reg:$addr),
1311*9880d681SAndroid Build Coastguard Worker            (t2LDRBs    t2addrmode_so_reg:$addr)>;
1312*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi8  (ARMWrapper tconstpool:$addr)),
1313*9880d681SAndroid Build Coastguard Worker            (t2LDRBpci  tconstpool:$addr)>;
1314*9880d681SAndroid Build Coastguard Worker
1315*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
1316*9880d681SAndroid Build Coastguard Worker            (t2LDRHi12  t2addrmode_imm12:$addr)>;
1317*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi16 t2addrmode_negimm8:$addr),
1318*9880d681SAndroid Build Coastguard Worker            (t2LDRHi8   t2addrmode_negimm8:$addr)>;
1319*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
1320*9880d681SAndroid Build Coastguard Worker            (t2LDRHs    t2addrmode_so_reg:$addr)>;
1321*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
1322*9880d681SAndroid Build Coastguard Worker            (t2LDRHpci  tconstpool:$addr)>;
1323*9880d681SAndroid Build Coastguard Worker
1324*9880d681SAndroid Build Coastguard Worker// FIXME: The destination register of the loads and stores can't be PC, but
1325*9880d681SAndroid Build Coastguard Worker//        can be SP. We need another regclass (similar to rGPR) to represent
1326*9880d681SAndroid Build Coastguard Worker//        that. Not a pressing issue since these are selected manually,
1327*9880d681SAndroid Build Coastguard Worker//        not via pattern.
1328*9880d681SAndroid Build Coastguard Worker
1329*9880d681SAndroid Build Coastguard Worker// Indexed loads
1330*9880d681SAndroid Build Coastguard Worker
1331*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, hasSideEffects = 0 in {
1332*9880d681SAndroid Build Coastguard Workerdef t2LDR_PRE  : T2Ipreldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1333*9880d681SAndroid Build Coastguard Worker                            (ins t2addrmode_imm8_pre:$addr),
1334*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iLoad_iu,
1335*9880d681SAndroid Build Coastguard Worker                            "ldr", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1336*9880d681SAndroid Build Coastguard Worker
1337*9880d681SAndroid Build Coastguard Workerdef t2LDR_POST : T2Ipostldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1338*9880d681SAndroid Build Coastguard Worker                          (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset),
1339*9880d681SAndroid Build Coastguard Worker                          AddrModeT2_i8, IndexModePost, IIC_iLoad_iu,
1340*9880d681SAndroid Build Coastguard Worker                          "ldr", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>;
1341*9880d681SAndroid Build Coastguard Worker
1342*9880d681SAndroid Build Coastguard Workerdef t2LDRB_PRE : T2Ipreldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1343*9880d681SAndroid Build Coastguard Worker                            (ins t2addrmode_imm8_pre:$addr),
1344*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1345*9880d681SAndroid Build Coastguard Worker                            "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1346*9880d681SAndroid Build Coastguard Worker
1347*9880d681SAndroid Build Coastguard Workerdef t2LDRB_POST : T2Ipostldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1348*9880d681SAndroid Build Coastguard Worker                          (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset),
1349*9880d681SAndroid Build Coastguard Worker                          AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1350*9880d681SAndroid Build Coastguard Worker                          "ldrb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>;
1351*9880d681SAndroid Build Coastguard Worker
1352*9880d681SAndroid Build Coastguard Workerdef t2LDRH_PRE : T2Ipreldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1353*9880d681SAndroid Build Coastguard Worker                            (ins t2addrmode_imm8_pre:$addr),
1354*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1355*9880d681SAndroid Build Coastguard Worker                            "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
1356*9880d681SAndroid Build Coastguard Worker
1357*9880d681SAndroid Build Coastguard Workerdef t2LDRH_POST : T2Ipostldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1358*9880d681SAndroid Build Coastguard Worker                          (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset),
1359*9880d681SAndroid Build Coastguard Worker                          AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1360*9880d681SAndroid Build Coastguard Worker                          "ldrh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>;
1361*9880d681SAndroid Build Coastguard Worker
1362*9880d681SAndroid Build Coastguard Workerdef t2LDRSB_PRE : T2Ipreldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1363*9880d681SAndroid Build Coastguard Worker                            (ins t2addrmode_imm8_pre:$addr),
1364*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1365*9880d681SAndroid Build Coastguard Worker                            "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb",
1366*9880d681SAndroid Build Coastguard Worker                            []>;
1367*9880d681SAndroid Build Coastguard Worker
1368*9880d681SAndroid Build Coastguard Workerdef t2LDRSB_POST : T2Ipostldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1369*9880d681SAndroid Build Coastguard Worker                          (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset),
1370*9880d681SAndroid Build Coastguard Worker                          AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1371*9880d681SAndroid Build Coastguard Worker                          "ldrsb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>;
1372*9880d681SAndroid Build Coastguard Worker
1373*9880d681SAndroid Build Coastguard Workerdef t2LDRSH_PRE : T2Ipreldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
1374*9880d681SAndroid Build Coastguard Worker                            (ins t2addrmode_imm8_pre:$addr),
1375*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu,
1376*9880d681SAndroid Build Coastguard Worker                            "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb",
1377*9880d681SAndroid Build Coastguard Worker                            []>;
1378*9880d681SAndroid Build Coastguard Worker
1379*9880d681SAndroid Build Coastguard Workerdef t2LDRSH_POST : T2Ipostldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
1380*9880d681SAndroid Build Coastguard Worker                          (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset),
1381*9880d681SAndroid Build Coastguard Worker                          AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu,
1382*9880d681SAndroid Build Coastguard Worker                          "ldrsh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>;
1383*9880d681SAndroid Build Coastguard Worker} // mayLoad = 1, hasSideEffects = 0
1384*9880d681SAndroid Build Coastguard Worker
1385*9880d681SAndroid Build Coastguard Worker// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110).
1386*9880d681SAndroid Build Coastguard Worker// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
1387*9880d681SAndroid Build Coastguard Workerclass T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
1388*9880d681SAndroid Build Coastguard Worker  : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc,
1389*9880d681SAndroid Build Coastguard Worker          "\t$Rt, $addr", []> {
1390*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
1391*9880d681SAndroid Build Coastguard Worker  bits<13> addr;
1392*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1393*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b00;
1394*9880d681SAndroid Build Coastguard Worker  let Inst{24} = signed;
1395*9880d681SAndroid Build Coastguard Worker  let Inst{23} = 0;
1396*9880d681SAndroid Build Coastguard Worker  let Inst{22-21} = type;
1397*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 1; // load
1398*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr{12-9};
1399*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
1400*9880d681SAndroid Build Coastguard Worker  let Inst{11} = 1;
1401*9880d681SAndroid Build Coastguard Worker  let Inst{10-8} = 0b110; // PUW.
1402*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = addr{7-0};
1403*9880d681SAndroid Build Coastguard Worker
1404*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2LoadT";
1405*9880d681SAndroid Build Coastguard Worker}
1406*9880d681SAndroid Build Coastguard Worker
1407*9880d681SAndroid Build Coastguard Workerdef t2LDRT   : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
1408*9880d681SAndroid Build Coastguard Workerdef t2LDRBT  : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>;
1409*9880d681SAndroid Build Coastguard Workerdef t2LDRHT  : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>;
1410*9880d681SAndroid Build Coastguard Workerdef t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>;
1411*9880d681SAndroid Build Coastguard Workerdef t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>;
1412*9880d681SAndroid Build Coastguard Worker
1413*9880d681SAndroid Build Coastguard Workerclass T2Ildacq<bits<4> bits23_20, bits<2> bit54, dag oops, dag iops,
1414*9880d681SAndroid Build Coastguard Worker               string opc, string asm, list<dag> pattern>
1415*9880d681SAndroid Build Coastguard Worker  : Thumb2I<oops, iops, AddrModeNone, 4, NoItinerary,
1416*9880d681SAndroid Build Coastguard Worker            opc, asm, "", pattern>, Requires<[IsThumb, HasAcquireRelease]> {
1417*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
1418*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
1419*9880d681SAndroid Build Coastguard Worker
1420*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
1421*9880d681SAndroid Build Coastguard Worker  let Inst{26-24} = 0b000;
1422*9880d681SAndroid Build Coastguard Worker  let Inst{23-20} = bits23_20;
1423*9880d681SAndroid Build Coastguard Worker  let Inst{11-6} = 0b111110;
1424*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = bit54;
1425*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b1111;
1426*9880d681SAndroid Build Coastguard Worker
1427*9880d681SAndroid Build Coastguard Worker  // Encode instruction operands
1428*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
1429*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
1430*9880d681SAndroid Build Coastguard Worker}
1431*9880d681SAndroid Build Coastguard Worker
1432*9880d681SAndroid Build Coastguard Workerdef t2LDA : T2Ildacq<0b1101, 0b10, (outs rGPR:$Rt),
1433*9880d681SAndroid Build Coastguard Worker                     (ins addr_offset_none:$addr), "lda", "\t$Rt, $addr", []>;
1434*9880d681SAndroid Build Coastguard Workerdef t2LDAB : T2Ildacq<0b1101, 0b00, (outs rGPR:$Rt),
1435*9880d681SAndroid Build Coastguard Worker                      (ins addr_offset_none:$addr), "ldab", "\t$Rt, $addr", []>;
1436*9880d681SAndroid Build Coastguard Workerdef t2LDAH : T2Ildacq<0b1101, 0b01, (outs rGPR:$Rt),
1437*9880d681SAndroid Build Coastguard Worker                      (ins addr_offset_none:$addr), "ldah", "\t$Rt, $addr", []>;
1438*9880d681SAndroid Build Coastguard Worker
1439*9880d681SAndroid Build Coastguard Worker// Store
1440*9880d681SAndroid Build Coastguard Workerdefm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si, GPR, store>;
1441*9880d681SAndroid Build Coastguard Workerdefm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si,
1442*9880d681SAndroid Build Coastguard Worker                   rGPR, truncstorei8>;
1443*9880d681SAndroid Build Coastguard Workerdefm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
1444*9880d681SAndroid Build Coastguard Worker                   rGPR, truncstorei16>;
1445*9880d681SAndroid Build Coastguard Worker
1446*9880d681SAndroid Build Coastguard Worker// Store doubleword
1447*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in
1448*9880d681SAndroid Build Coastguard Workerdef t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
1449*9880d681SAndroid Build Coastguard Worker                       (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4:$addr),
1450*9880d681SAndroid Build Coastguard Worker               IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", "", []>;
1451*9880d681SAndroid Build Coastguard Worker
1452*9880d681SAndroid Build Coastguard Worker// Indexed stores
1453*9880d681SAndroid Build Coastguard Worker
1454*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, hasSideEffects = 0 in {
1455*9880d681SAndroid Build Coastguard Workerdef t2STR_PRE  : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb),
1456*9880d681SAndroid Build Coastguard Worker                            (ins GPRnopc:$Rt, t2addrmode_imm8_pre:$addr),
1457*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1458*9880d681SAndroid Build Coastguard Worker                            "str", "\t$Rt, $addr!",
1459*9880d681SAndroid Build Coastguard Worker                            "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>;
1460*9880d681SAndroid Build Coastguard Worker
1461*9880d681SAndroid Build Coastguard Workerdef t2STRH_PRE  : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb),
1462*9880d681SAndroid Build Coastguard Worker                            (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr),
1463*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iStore_iu,
1464*9880d681SAndroid Build Coastguard Worker                        "strh", "\t$Rt, $addr!",
1465*9880d681SAndroid Build Coastguard Worker                        "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>;
1466*9880d681SAndroid Build Coastguard Worker
1467*9880d681SAndroid Build Coastguard Workerdef t2STRB_PRE  : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb),
1468*9880d681SAndroid Build Coastguard Worker                            (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr),
1469*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu,
1470*9880d681SAndroid Build Coastguard Worker                        "strb", "\t$Rt, $addr!",
1471*9880d681SAndroid Build Coastguard Worker                        "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>;
1472*9880d681SAndroid Build Coastguard Worker} // mayStore = 1, hasSideEffects = 0
1473*9880d681SAndroid Build Coastguard Worker
1474*9880d681SAndroid Build Coastguard Workerdef t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb),
1475*9880d681SAndroid Build Coastguard Worker                            (ins GPRnopc:$Rt, addr_offset_none:$Rn,
1476*9880d681SAndroid Build Coastguard Worker                                 t2am_imm8_offset:$offset),
1477*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePost, IIC_iStore_iu,
1478*9880d681SAndroid Build Coastguard Worker                          "str", "\t$Rt, $Rn$offset",
1479*9880d681SAndroid Build Coastguard Worker                          "$Rn = $Rn_wb,@earlyclobber $Rn_wb",
1480*9880d681SAndroid Build Coastguard Worker             [(set GPRnopc:$Rn_wb,
1481*9880d681SAndroid Build Coastguard Worker                  (post_store GPRnopc:$Rt, addr_offset_none:$Rn,
1482*9880d681SAndroid Build Coastguard Worker                              t2am_imm8_offset:$offset))]>;
1483*9880d681SAndroid Build Coastguard Worker
1484*9880d681SAndroid Build Coastguard Workerdef t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb),
1485*9880d681SAndroid Build Coastguard Worker                            (ins rGPR:$Rt, addr_offset_none:$Rn,
1486*9880d681SAndroid Build Coastguard Worker                                 t2am_imm8_offset:$offset),
1487*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1488*9880d681SAndroid Build Coastguard Worker                         "strh", "\t$Rt, $Rn$offset",
1489*9880d681SAndroid Build Coastguard Worker                         "$Rn = $Rn_wb,@earlyclobber $Rn_wb",
1490*9880d681SAndroid Build Coastguard Worker       [(set GPRnopc:$Rn_wb,
1491*9880d681SAndroid Build Coastguard Worker             (post_truncsti16 rGPR:$Rt, addr_offset_none:$Rn,
1492*9880d681SAndroid Build Coastguard Worker                              t2am_imm8_offset:$offset))]>;
1493*9880d681SAndroid Build Coastguard Worker
1494*9880d681SAndroid Build Coastguard Workerdef t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb),
1495*9880d681SAndroid Build Coastguard Worker                            (ins rGPR:$Rt, addr_offset_none:$Rn,
1496*9880d681SAndroid Build Coastguard Worker                                 t2am_imm8_offset:$offset),
1497*9880d681SAndroid Build Coastguard Worker                            AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu,
1498*9880d681SAndroid Build Coastguard Worker                         "strb", "\t$Rt, $Rn$offset",
1499*9880d681SAndroid Build Coastguard Worker                         "$Rn = $Rn_wb,@earlyclobber $Rn_wb",
1500*9880d681SAndroid Build Coastguard Worker        [(set GPRnopc:$Rn_wb,
1501*9880d681SAndroid Build Coastguard Worker              (post_truncsti8 rGPR:$Rt, addr_offset_none:$Rn,
1502*9880d681SAndroid Build Coastguard Worker                              t2am_imm8_offset:$offset))]>;
1503*9880d681SAndroid Build Coastguard Worker
1504*9880d681SAndroid Build Coastguard Worker// Pseudo-instructions for pattern matching the pre-indexed stores. We can't
1505*9880d681SAndroid Build Coastguard Worker// put the patterns on the instruction definitions directly as ISel wants
1506*9880d681SAndroid Build Coastguard Worker// the address base and offset to be separate operands, not a single
1507*9880d681SAndroid Build Coastguard Worker// complex operand like we represent the instructions themselves. The
1508*9880d681SAndroid Build Coastguard Worker// pseudos map between the two.
1509*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1,
1510*9880d681SAndroid Build Coastguard Worker    Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in {
1511*9880d681SAndroid Build Coastguard Workerdef t2STR_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
1512*9880d681SAndroid Build Coastguard Worker               (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
1513*9880d681SAndroid Build Coastguard Worker               4, IIC_iStore_ru,
1514*9880d681SAndroid Build Coastguard Worker      [(set GPRnopc:$Rn_wb,
1515*9880d681SAndroid Build Coastguard Worker            (pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
1516*9880d681SAndroid Build Coastguard Workerdef t2STRB_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
1517*9880d681SAndroid Build Coastguard Worker               (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
1518*9880d681SAndroid Build Coastguard Worker               4, IIC_iStore_ru,
1519*9880d681SAndroid Build Coastguard Worker      [(set GPRnopc:$Rn_wb,
1520*9880d681SAndroid Build Coastguard Worker            (pre_truncsti8 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
1521*9880d681SAndroid Build Coastguard Workerdef t2STRH_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb),
1522*9880d681SAndroid Build Coastguard Worker               (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p),
1523*9880d681SAndroid Build Coastguard Worker               4, IIC_iStore_ru,
1524*9880d681SAndroid Build Coastguard Worker      [(set GPRnopc:$Rn_wb,
1525*9880d681SAndroid Build Coastguard Worker            (pre_truncsti16 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>;
1526*9880d681SAndroid Build Coastguard Worker}
1527*9880d681SAndroid Build Coastguard Worker
1528*9880d681SAndroid Build Coastguard Worker// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly
1529*9880d681SAndroid Build Coastguard Worker// only.
1530*9880d681SAndroid Build Coastguard Worker// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4
1531*9880d681SAndroid Build Coastguard Workerclass T2IstT<bits<2> type, string opc, InstrItinClass ii>
1532*9880d681SAndroid Build Coastguard Worker  : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
1533*9880d681SAndroid Build Coastguard Worker          "\t$Rt, $addr", []> {
1534*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
1535*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b00;
1536*9880d681SAndroid Build Coastguard Worker  let Inst{24} = 0; // not signed
1537*9880d681SAndroid Build Coastguard Worker  let Inst{23} = 0;
1538*9880d681SAndroid Build Coastguard Worker  let Inst{22-21} = type;
1539*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0; // store
1540*9880d681SAndroid Build Coastguard Worker  let Inst{11} = 1;
1541*9880d681SAndroid Build Coastguard Worker  let Inst{10-8} = 0b110; // PUW
1542*9880d681SAndroid Build Coastguard Worker
1543*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
1544*9880d681SAndroid Build Coastguard Worker  bits<13> addr;
1545*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
1546*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr{12-9};
1547*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = addr{7-0};
1548*9880d681SAndroid Build Coastguard Worker}
1549*9880d681SAndroid Build Coastguard Worker
1550*9880d681SAndroid Build Coastguard Workerdef t2STRT   : T2IstT<0b10, "strt", IIC_iStore_i>;
1551*9880d681SAndroid Build Coastguard Workerdef t2STRBT  : T2IstT<0b00, "strbt", IIC_iStore_bh_i>;
1552*9880d681SAndroid Build Coastguard Workerdef t2STRHT  : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
1553*9880d681SAndroid Build Coastguard Worker
1554*9880d681SAndroid Build Coastguard Worker// ldrd / strd pre / post variants
1555*9880d681SAndroid Build Coastguard Worker
1556*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
1557*9880d681SAndroid Build Coastguard Workerdef t2LDRD_PRE  : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb),
1558*9880d681SAndroid Build Coastguard Worker                 (ins t2addrmode_imm8s4_pre:$addr), IIC_iLoad_d_ru,
1559*9880d681SAndroid Build Coastguard Worker                 "ldrd", "\t$Rt, $Rt2, $addr!", "$addr.base = $wb", []> {
1560*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2LDRDPreInstruction";
1561*9880d681SAndroid Build Coastguard Worker}
1562*9880d681SAndroid Build Coastguard Worker
1563*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
1564*9880d681SAndroid Build Coastguard Workerdef t2LDRD_POST : T2Ii8s4post<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb),
1565*9880d681SAndroid Build Coastguard Worker                 (ins addr_offset_none:$addr, t2am_imm8s4_offset:$imm),
1566*9880d681SAndroid Build Coastguard Worker                 IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr$imm",
1567*9880d681SAndroid Build Coastguard Worker                 "$addr.base = $wb", []>;
1568*9880d681SAndroid Build Coastguard Worker
1569*9880d681SAndroid Build Coastguard Workerlet mayStore = 1 in
1570*9880d681SAndroid Build Coastguard Workerdef t2STRD_PRE  : T2Ii8s4<1, 1, 0, (outs GPR:$wb),
1571*9880d681SAndroid Build Coastguard Worker                 (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4_pre:$addr),
1572*9880d681SAndroid Build Coastguard Worker                 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr!",
1573*9880d681SAndroid Build Coastguard Worker                 "$addr.base = $wb", []> {
1574*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2STRDPreInstruction";
1575*9880d681SAndroid Build Coastguard Worker}
1576*9880d681SAndroid Build Coastguard Worker
1577*9880d681SAndroid Build Coastguard Workerlet mayStore = 1 in
1578*9880d681SAndroid Build Coastguard Workerdef t2STRD_POST : T2Ii8s4post<0, 1, 0, (outs GPR:$wb),
1579*9880d681SAndroid Build Coastguard Worker                 (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr,
1580*9880d681SAndroid Build Coastguard Worker                      t2am_imm8s4_offset:$imm),
1581*9880d681SAndroid Build Coastguard Worker                 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr$imm",
1582*9880d681SAndroid Build Coastguard Worker                 "$addr.base = $wb", []>;
1583*9880d681SAndroid Build Coastguard Worker
1584*9880d681SAndroid Build Coastguard Workerclass T2Istrrel<bits<2> bit54, dag oops, dag iops,
1585*9880d681SAndroid Build Coastguard Worker                string opc, string asm, list<dag> pattern>
1586*9880d681SAndroid Build Coastguard Worker  : Thumb2I<oops, iops, AddrModeNone, 4, NoItinerary, opc,
1587*9880d681SAndroid Build Coastguard Worker            asm, "", pattern>, Requires<[IsThumb, HasAcquireRelease]> {
1588*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
1589*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
1590*9880d681SAndroid Build Coastguard Worker
1591*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
1592*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0001100;
1593*9880d681SAndroid Build Coastguard Worker  let Inst{11-6} = 0b111110;
1594*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = bit54;
1595*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b1111;
1596*9880d681SAndroid Build Coastguard Worker
1597*9880d681SAndroid Build Coastguard Worker  // Encode instruction operands
1598*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
1599*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
1600*9880d681SAndroid Build Coastguard Worker}
1601*9880d681SAndroid Build Coastguard Worker
1602*9880d681SAndroid Build Coastguard Workerdef t2STL  : T2Istrrel<0b10, (outs), (ins rGPR:$Rt, addr_offset_none:$addr),
1603*9880d681SAndroid Build Coastguard Worker                       "stl", "\t$Rt, $addr", []>;
1604*9880d681SAndroid Build Coastguard Workerdef t2STLB : T2Istrrel<0b00, (outs), (ins rGPR:$Rt, addr_offset_none:$addr),
1605*9880d681SAndroid Build Coastguard Worker                       "stlb", "\t$Rt, $addr", []>;
1606*9880d681SAndroid Build Coastguard Workerdef t2STLH : T2Istrrel<0b01, (outs), (ins rGPR:$Rt, addr_offset_none:$addr),
1607*9880d681SAndroid Build Coastguard Worker                       "stlh", "\t$Rt, $addr", []>;
1608*9880d681SAndroid Build Coastguard Worker
1609*9880d681SAndroid Build Coastguard Worker// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
1610*9880d681SAndroid Build Coastguard Worker// data/instruction access.
1611*9880d681SAndroid Build Coastguard Worker// instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
1612*9880d681SAndroid Build Coastguard Worker// (prefetch 1) -> (preload 2),  (prefetch 2) -> (preload 1).
1613*9880d681SAndroid Build Coastguard Workermulticlass T2Ipl<bits<1> write, bits<1> instr, string opc> {
1614*9880d681SAndroid Build Coastguard Worker
1615*9880d681SAndroid Build Coastguard Worker  def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
1616*9880d681SAndroid Build Coastguard Worker                "\t$addr",
1617*9880d681SAndroid Build Coastguard Worker              [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]>,
1618*9880d681SAndroid Build Coastguard Worker              Sched<[WritePreLd]> {
1619*9880d681SAndroid Build Coastguard Worker    let Inst{31-25} = 0b1111100;
1620*9880d681SAndroid Build Coastguard Worker    let Inst{24} = instr;
1621*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 1;
1622*9880d681SAndroid Build Coastguard Worker    let Inst{22} = 0;
1623*9880d681SAndroid Build Coastguard Worker    let Inst{21} = write;
1624*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1;
1625*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111;
1626*9880d681SAndroid Build Coastguard Worker
1627*9880d681SAndroid Build Coastguard Worker    bits<17> addr;
1628*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{16-13}; // Rn
1629*9880d681SAndroid Build Coastguard Worker    let Inst{11-0}  = addr{11-0};  // imm12
1630*9880d681SAndroid Build Coastguard Worker
1631*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadImm12";
1632*9880d681SAndroid Build Coastguard Worker  }
1633*9880d681SAndroid Build Coastguard Worker
1634*9880d681SAndroid Build Coastguard Worker  def i8 : T2Ii8<(outs), (ins t2addrmode_negimm8:$addr), IIC_Preload, opc,
1635*9880d681SAndroid Build Coastguard Worker                "\t$addr",
1636*9880d681SAndroid Build Coastguard Worker            [(ARMPreload t2addrmode_negimm8:$addr, (i32 write), (i32 instr))]>,
1637*9880d681SAndroid Build Coastguard Worker            Sched<[WritePreLd]> {
1638*9880d681SAndroid Build Coastguard Worker    let Inst{31-25} = 0b1111100;
1639*9880d681SAndroid Build Coastguard Worker    let Inst{24} = instr;
1640*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 0; // U = 0
1641*9880d681SAndroid Build Coastguard Worker    let Inst{22} = 0;
1642*9880d681SAndroid Build Coastguard Worker    let Inst{21} = write;
1643*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1;
1644*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111;
1645*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = 0b1100;
1646*9880d681SAndroid Build Coastguard Worker
1647*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
1648*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{12-9}; // Rn
1649*9880d681SAndroid Build Coastguard Worker    let Inst{7-0}   = addr{7-0};  // imm8
1650*9880d681SAndroid Build Coastguard Worker
1651*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadImm8";
1652*9880d681SAndroid Build Coastguard Worker  }
1653*9880d681SAndroid Build Coastguard Worker
1654*9880d681SAndroid Build Coastguard Worker  def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
1655*9880d681SAndroid Build Coastguard Worker               "\t$addr",
1656*9880d681SAndroid Build Coastguard Worker             [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]>,
1657*9880d681SAndroid Build Coastguard Worker             Sched<[WritePreLd]> {
1658*9880d681SAndroid Build Coastguard Worker    let Inst{31-25} = 0b1111100;
1659*9880d681SAndroid Build Coastguard Worker    let Inst{24} = instr;
1660*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 0; // add = TRUE for T1
1661*9880d681SAndroid Build Coastguard Worker    let Inst{22} = 0;
1662*9880d681SAndroid Build Coastguard Worker    let Inst{21} = write;
1663*9880d681SAndroid Build Coastguard Worker    let Inst{20} = 1;
1664*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111;
1665*9880d681SAndroid Build Coastguard Worker    let Inst{11-6} = 0b000000;
1666*9880d681SAndroid Build Coastguard Worker
1667*9880d681SAndroid Build Coastguard Worker    bits<10> addr;
1668*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{9-6}; // Rn
1669*9880d681SAndroid Build Coastguard Worker    let Inst{3-0}   = addr{5-2}; // Rm
1670*9880d681SAndroid Build Coastguard Worker    let Inst{5-4}   = addr{1-0}; // imm2
1671*9880d681SAndroid Build Coastguard Worker
1672*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeT2LoadShift";
1673*9880d681SAndroid Build Coastguard Worker  }
1674*9880d681SAndroid Build Coastguard Worker}
1675*9880d681SAndroid Build Coastguard Worker
1676*9880d681SAndroid Build Coastguard Workerdefm t2PLD    : T2Ipl<0, 0, "pld">,  Requires<[IsThumb2]>;
1677*9880d681SAndroid Build Coastguard Workerdefm t2PLDW   : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
1678*9880d681SAndroid Build Coastguard Workerdefm t2PLI    : T2Ipl<0, 1, "pli">,  Requires<[IsThumb2,HasV7]>;
1679*9880d681SAndroid Build Coastguard Worker
1680*9880d681SAndroid Build Coastguard Worker// pci variant is very similar to i12, but supports negative offsets
1681*9880d681SAndroid Build Coastguard Worker// from the PC. Only PLD and PLI have pci variants (not PLDW)
1682*9880d681SAndroid Build Coastguard Workerclass T2Iplpci<bits<1> inst, string opc> : T2Iso<(outs), (ins t2ldrlabel:$addr),
1683*9880d681SAndroid Build Coastguard Worker               IIC_Preload, opc, "\t$addr",
1684*9880d681SAndroid Build Coastguard Worker               [(ARMPreload (ARMWrapper tconstpool:$addr),
1685*9880d681SAndroid Build Coastguard Worker                (i32 0), (i32 inst))]>, Sched<[WritePreLd]> {
1686*9880d681SAndroid Build Coastguard Worker  let Inst{31-25} = 0b1111100;
1687*9880d681SAndroid Build Coastguard Worker  let Inst{24} = inst;
1688*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b001;
1689*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111;
1690*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
1691*9880d681SAndroid Build Coastguard Worker
1692*9880d681SAndroid Build Coastguard Worker  bits<13> addr;
1693*9880d681SAndroid Build Coastguard Worker  let Inst{23}   = addr{12};   // add = (U == '1')
1694*9880d681SAndroid Build Coastguard Worker  let Inst{11-0} = addr{11-0}; // imm12
1695*9880d681SAndroid Build Coastguard Worker
1696*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2LoadLabel";
1697*9880d681SAndroid Build Coastguard Worker}
1698*9880d681SAndroid Build Coastguard Worker
1699*9880d681SAndroid Build Coastguard Workerdef t2PLDpci : T2Iplpci<0, "pld">,  Requires<[IsThumb2]>;
1700*9880d681SAndroid Build Coastguard Workerdef t2PLIpci : T2Iplpci<1, "pli">,  Requires<[IsThumb2,HasV7]>;
1701*9880d681SAndroid Build Coastguard Worker
1702*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1703*9880d681SAndroid Build Coastguard Worker//  Load / store multiple Instructions.
1704*9880d681SAndroid Build Coastguard Worker//
1705*9880d681SAndroid Build Coastguard Worker
1706*9880d681SAndroid Build Coastguard Workermulticlass thumb2_ld_mult<string asm, InstrItinClass itin,
1707*9880d681SAndroid Build Coastguard Worker                            InstrItinClass itin_upd, bit L_bit> {
1708*9880d681SAndroid Build Coastguard Worker  def IA :
1709*9880d681SAndroid Build Coastguard Worker    T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1710*9880d681SAndroid Build Coastguard Worker         itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
1711*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1712*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1713*9880d681SAndroid Build Coastguard Worker
1714*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1715*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1716*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b01;     // Increment After
1717*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1718*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 0;        // No writeback
1719*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1720*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1721*9880d681SAndroid Build Coastguard Worker    let Inst{15-0}  = regs;
1722*9880d681SAndroid Build Coastguard Worker  }
1723*9880d681SAndroid Build Coastguard Worker  def IA_UPD :
1724*9880d681SAndroid Build Coastguard Worker    T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1725*9880d681SAndroid Build Coastguard Worker          itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1726*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1727*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1728*9880d681SAndroid Build Coastguard Worker
1729*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1730*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1731*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b01;     // Increment After
1732*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1733*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 1;        // Writeback
1734*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1735*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1736*9880d681SAndroid Build Coastguard Worker    let Inst{15-0}  = regs;
1737*9880d681SAndroid Build Coastguard Worker  }
1738*9880d681SAndroid Build Coastguard Worker  def DB :
1739*9880d681SAndroid Build Coastguard Worker    T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1740*9880d681SAndroid Build Coastguard Worker         itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> {
1741*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1742*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1743*9880d681SAndroid Build Coastguard Worker
1744*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1745*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1746*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b10;     // Decrement Before
1747*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1748*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 0;        // No writeback
1749*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1750*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1751*9880d681SAndroid Build Coastguard Worker    let Inst{15-0}  = regs;
1752*9880d681SAndroid Build Coastguard Worker  }
1753*9880d681SAndroid Build Coastguard Worker  def DB_UPD :
1754*9880d681SAndroid Build Coastguard Worker    T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1755*9880d681SAndroid Build Coastguard Worker          itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1756*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1757*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1758*9880d681SAndroid Build Coastguard Worker
1759*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1760*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1761*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b10;     // Decrement Before
1762*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1763*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 1;        // Writeback
1764*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1765*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1766*9880d681SAndroid Build Coastguard Worker    let Inst{15-0}  = regs;
1767*9880d681SAndroid Build Coastguard Worker  }
1768*9880d681SAndroid Build Coastguard Worker}
1769*9880d681SAndroid Build Coastguard Worker
1770*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in {
1771*9880d681SAndroid Build Coastguard Worker
1772*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in
1773*9880d681SAndroid Build Coastguard Workerdefm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>;
1774*9880d681SAndroid Build Coastguard Worker
1775*9880d681SAndroid Build Coastguard Workermulticlass thumb2_st_mult<string asm, InstrItinClass itin,
1776*9880d681SAndroid Build Coastguard Worker                            InstrItinClass itin_upd, bit L_bit> {
1777*9880d681SAndroid Build Coastguard Worker  def IA :
1778*9880d681SAndroid Build Coastguard Worker    T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1779*9880d681SAndroid Build Coastguard Worker         itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
1780*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1781*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1782*9880d681SAndroid Build Coastguard Worker
1783*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1784*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1785*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b01;     // Increment After
1786*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1787*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 0;        // No writeback
1788*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1789*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1790*9880d681SAndroid Build Coastguard Worker    let Inst{15}    = 0;
1791*9880d681SAndroid Build Coastguard Worker    let Inst{14}    = regs{14};
1792*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0;
1793*9880d681SAndroid Build Coastguard Worker    let Inst{12-0}  = regs{12-0};
1794*9880d681SAndroid Build Coastguard Worker  }
1795*9880d681SAndroid Build Coastguard Worker  def IA_UPD :
1796*9880d681SAndroid Build Coastguard Worker    T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1797*9880d681SAndroid Build Coastguard Worker          itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
1798*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1799*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1800*9880d681SAndroid Build Coastguard Worker
1801*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1802*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1803*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b01;     // Increment After
1804*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1805*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 1;        // Writeback
1806*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1807*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1808*9880d681SAndroid Build Coastguard Worker    let Inst{15}    = 0;
1809*9880d681SAndroid Build Coastguard Worker    let Inst{14}    = regs{14};
1810*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0;
1811*9880d681SAndroid Build Coastguard Worker    let Inst{12-0}  = regs{12-0};
1812*9880d681SAndroid Build Coastguard Worker  }
1813*9880d681SAndroid Build Coastguard Worker  def DB :
1814*9880d681SAndroid Build Coastguard Worker    T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1815*9880d681SAndroid Build Coastguard Worker         itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> {
1816*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1817*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1818*9880d681SAndroid Build Coastguard Worker
1819*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1820*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1821*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b10;     // Decrement Before
1822*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1823*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 0;        // No writeback
1824*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1825*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1826*9880d681SAndroid Build Coastguard Worker    let Inst{15}    = 0;
1827*9880d681SAndroid Build Coastguard Worker    let Inst{14}    = regs{14};
1828*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0;
1829*9880d681SAndroid Build Coastguard Worker    let Inst{12-0}  = regs{12-0};
1830*9880d681SAndroid Build Coastguard Worker  }
1831*9880d681SAndroid Build Coastguard Worker  def DB_UPD :
1832*9880d681SAndroid Build Coastguard Worker    T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
1833*9880d681SAndroid Build Coastguard Worker          itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
1834*9880d681SAndroid Build Coastguard Worker    bits<4>  Rn;
1835*9880d681SAndroid Build Coastguard Worker    bits<16> regs;
1836*9880d681SAndroid Build Coastguard Worker
1837*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11101;
1838*9880d681SAndroid Build Coastguard Worker    let Inst{26-25} = 0b00;
1839*9880d681SAndroid Build Coastguard Worker    let Inst{24-23} = 0b10;     // Decrement Before
1840*9880d681SAndroid Build Coastguard Worker    let Inst{22}    = 0;
1841*9880d681SAndroid Build Coastguard Worker    let Inst{21}    = 1;        // Writeback
1842*9880d681SAndroid Build Coastguard Worker    let Inst{20}    = L_bit;
1843*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = Rn;
1844*9880d681SAndroid Build Coastguard Worker    let Inst{15}    = 0;
1845*9880d681SAndroid Build Coastguard Worker    let Inst{14}    = regs{14};
1846*9880d681SAndroid Build Coastguard Worker    let Inst{13}    = 0;
1847*9880d681SAndroid Build Coastguard Worker    let Inst{12-0}  = regs{12-0};
1848*9880d681SAndroid Build Coastguard Worker  }
1849*9880d681SAndroid Build Coastguard Worker}
1850*9880d681SAndroid Build Coastguard Worker
1851*9880d681SAndroid Build Coastguard Worker
1852*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in
1853*9880d681SAndroid Build Coastguard Workerdefm t2STM : thumb2_st_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>;
1854*9880d681SAndroid Build Coastguard Worker
1855*9880d681SAndroid Build Coastguard Worker} // hasSideEffects
1856*9880d681SAndroid Build Coastguard Worker
1857*9880d681SAndroid Build Coastguard Worker
1858*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1859*9880d681SAndroid Build Coastguard Worker//  Move Instructions.
1860*9880d681SAndroid Build Coastguard Worker//
1861*9880d681SAndroid Build Coastguard Worker
1862*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
1863*9880d681SAndroid Build Coastguard Workerdef t2MOVr : T2sTwoReg<(outs GPRnopc:$Rd), (ins GPR:$Rm), IIC_iMOVr,
1864*9880d681SAndroid Build Coastguard Worker                   "mov", ".w\t$Rd, $Rm", []>, Sched<[WriteALU]> {
1865*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
1866*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
1867*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
1868*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
1869*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000;
1870*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000;
1871*9880d681SAndroid Build Coastguard Worker}
1872*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mov${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm,
1873*9880d681SAndroid Build Coastguard Worker                                                pred:$p, zero_reg)>;
1874*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"movs${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm,
1875*9880d681SAndroid Build Coastguard Worker                                                 pred:$p, CPSR)>;
1876*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"movs${p} $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm,
1877*9880d681SAndroid Build Coastguard Worker                                               pred:$p, CPSR)>;
1878*9880d681SAndroid Build Coastguard Worker
1879*9880d681SAndroid Build Coastguard Worker// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
1880*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
1881*9880d681SAndroid Build Coastguard Worker    AddedComplexity = 1 in
1882*9880d681SAndroid Build Coastguard Workerdef t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
1883*9880d681SAndroid Build Coastguard Worker                   "mov", ".w\t$Rd, $imm",
1884*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, t2_so_imm:$imm)]>, Sched<[WriteALU]> {
1885*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
1886*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 0;
1887*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
1888*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
1889*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
1890*9880d681SAndroid Build Coastguard Worker}
1891*9880d681SAndroid Build Coastguard Worker
1892*9880d681SAndroid Build Coastguard Worker// cc_out is handled as part of the explicit mnemonic in the parser for 'mov'.
1893*9880d681SAndroid Build Coastguard Worker// Use aliases to get that to play nice here.
1894*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"movs${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
1895*9880d681SAndroid Build Coastguard Worker                                                pred:$p, CPSR)>;
1896*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"movs${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
1897*9880d681SAndroid Build Coastguard Worker                                                pred:$p, CPSR)>;
1898*9880d681SAndroid Build Coastguard Worker
1899*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mov${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
1900*9880d681SAndroid Build Coastguard Worker                                                 pred:$p, zero_reg)>;
1901*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mov${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
1902*9880d681SAndroid Build Coastguard Worker                                               pred:$p, zero_reg)>;
1903*9880d681SAndroid Build Coastguard Worker
1904*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
1905*9880d681SAndroid Build Coastguard Workerdef t2MOVi16 : T2I<(outs rGPR:$Rd), (ins imm0_65535_expr:$imm), IIC_iMOVi,
1906*9880d681SAndroid Build Coastguard Worker                   "movw", "\t$Rd, $imm",
1907*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, imm0_65535:$imm)]>, Sched<[WriteALU]>,
1908*9880d681SAndroid Build Coastguard Worker                   Requires<[IsThumb, HasV8MBaseline]> {
1909*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
1910*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 1;
1911*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
1912*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0; // The S bit.
1913*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
1914*9880d681SAndroid Build Coastguard Worker
1915*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
1916*9880d681SAndroid Build Coastguard Worker  bits<16> imm;
1917*9880d681SAndroid Build Coastguard Worker
1918*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
1919*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = imm{15-12};
1920*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
1921*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
1922*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
1923*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2MOVTWInstruction";
1924*9880d681SAndroid Build Coastguard Worker}
1925*9880d681SAndroid Build Coastguard Worker
1926*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov${p} $Rd, $imm",
1927*9880d681SAndroid Build Coastguard Worker                (t2MOVi16 rGPR:$Rd, imm256_65535_expr:$imm, pred:$p), 0>,
1928*9880d681SAndroid Build Coastguard Worker                Requires<[IsThumb, HasV8MBaseline]>;
1929*9880d681SAndroid Build Coastguard Worker
1930*9880d681SAndroid Build Coastguard Workerdef t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1931*9880d681SAndroid Build Coastguard Worker                                (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
1932*9880d681SAndroid Build Coastguard Worker
1933*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $Rd" in {
1934*9880d681SAndroid Build Coastguard Workerdef t2MOVTi16 : T2I<(outs rGPR:$Rd),
1935*9880d681SAndroid Build Coastguard Worker                    (ins rGPR:$src, imm0_65535_expr:$imm), IIC_iMOVi,
1936*9880d681SAndroid Build Coastguard Worker                    "movt", "\t$Rd, $imm",
1937*9880d681SAndroid Build Coastguard Worker                    [(set rGPR:$Rd,
1938*9880d681SAndroid Build Coastguard Worker                          (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]>,
1939*9880d681SAndroid Build Coastguard Worker                          Sched<[WriteALU]>,
1940*9880d681SAndroid Build Coastguard Worker                          Requires<[IsThumb, HasV8MBaseline]> {
1941*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
1942*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 1;
1943*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0110;
1944*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0; // The S bit.
1945*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
1946*9880d681SAndroid Build Coastguard Worker
1947*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
1948*9880d681SAndroid Build Coastguard Worker  bits<16> imm;
1949*9880d681SAndroid Build Coastguard Worker
1950*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
1951*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = imm{15-12};
1952*9880d681SAndroid Build Coastguard Worker  let Inst{26}    = imm{11};
1953*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = imm{10-8};
1954*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = imm{7-0};
1955*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2MOVTWInstruction";
1956*9880d681SAndroid Build Coastguard Worker}
1957*9880d681SAndroid Build Coastguard Worker
1958*9880d681SAndroid Build Coastguard Workerdef t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
1959*9880d681SAndroid Build Coastguard Worker                     (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
1960*9880d681SAndroid Build Coastguard Worker                     Sched<[WriteALU]>, Requires<[IsThumb, HasV8MBaseline]>;
1961*9880d681SAndroid Build Coastguard Worker} // Constraints
1962*9880d681SAndroid Build Coastguard Worker
1963*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
1964*9880d681SAndroid Build Coastguard Worker
1965*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1966*9880d681SAndroid Build Coastguard Worker//  Extend Instructions.
1967*9880d681SAndroid Build Coastguard Worker//
1968*9880d681SAndroid Build Coastguard Worker
1969*9880d681SAndroid Build Coastguard Worker// Sign extenders
1970*9880d681SAndroid Build Coastguard Worker
1971*9880d681SAndroid Build Coastguard Workerdef t2SXTB  : T2I_ext_rrot<0b100, "sxtb",
1972*9880d681SAndroid Build Coastguard Worker                              UnOpFrag<(sext_inreg node:$Src, i8)>>;
1973*9880d681SAndroid Build Coastguard Workerdef t2SXTH  : T2I_ext_rrot<0b000, "sxth",
1974*9880d681SAndroid Build Coastguard Worker                              UnOpFrag<(sext_inreg node:$Src, i16)>>;
1975*9880d681SAndroid Build Coastguard Workerdef t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">;
1976*9880d681SAndroid Build Coastguard Worker
1977*9880d681SAndroid Build Coastguard Workerdef t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
1978*9880d681SAndroid Build Coastguard Worker                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
1979*9880d681SAndroid Build Coastguard Workerdef t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
1980*9880d681SAndroid Build Coastguard Worker                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
1981*9880d681SAndroid Build Coastguard Workerdef t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">;
1982*9880d681SAndroid Build Coastguard Worker
1983*9880d681SAndroid Build Coastguard Worker// A simple right-shift can also be used in most cases (the exception is the
1984*9880d681SAndroid Build Coastguard Worker// SXTH operations with a rotate of 24: there the non-contiguous bits are
1985*9880d681SAndroid Build Coastguard Worker// relevant).
1986*9880d681SAndroid Build Coastguard Workerdef : Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, rot_imm:$rot), i8)),
1987*9880d681SAndroid Build Coastguard Worker          (t2SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>,
1988*9880d681SAndroid Build Coastguard Worker      Requires<[HasT2ExtractPack, IsThumb2]>;
1989*9880d681SAndroid Build Coastguard Workerdef : Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, imm8_or_16:$rot), i16)),
1990*9880d681SAndroid Build Coastguard Worker          (t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>,
1991*9880d681SAndroid Build Coastguard Worker      Requires<[HasT2ExtractPack, IsThumb2]>;
1992*9880d681SAndroid Build Coastguard Worker
1993*9880d681SAndroid Build Coastguard Worker// Zero extenders
1994*9880d681SAndroid Build Coastguard Worker
1995*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 16 in {
1996*9880d681SAndroid Build Coastguard Workerdef t2UXTB   : T2I_ext_rrot<0b101, "uxtb",
1997*9880d681SAndroid Build Coastguard Worker                               UnOpFrag<(and node:$Src, 0x000000FF)>>;
1998*9880d681SAndroid Build Coastguard Workerdef t2UXTH   : T2I_ext_rrot<0b001, "uxth",
1999*9880d681SAndroid Build Coastguard Worker                               UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
2000*9880d681SAndroid Build Coastguard Workerdef t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
2001*9880d681SAndroid Build Coastguard Worker                                   UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
2002*9880d681SAndroid Build Coastguard Worker
2003*9880d681SAndroid Build Coastguard Worker// FIXME: This pattern incorrectly assumes the shl operator is a rotate.
2004*9880d681SAndroid Build Coastguard Worker//        The transformation should probably be done as a combiner action
2005*9880d681SAndroid Build Coastguard Worker//        instead so we can include a check for masking back in the upper
2006*9880d681SAndroid Build Coastguard Worker//        eight bits of the source into the lower eight bits of the result.
2007*9880d681SAndroid Build Coastguard Worker//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
2008*9880d681SAndroid Build Coastguard Worker//            (t2UXTB16 rGPR:$Src, 3)>,
2009*9880d681SAndroid Build Coastguard Worker//          Requires<[HasT2ExtractPack, IsThumb2]>;
2010*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
2011*9880d681SAndroid Build Coastguard Worker            (t2UXTB16 rGPR:$Src, 1)>,
2012*9880d681SAndroid Build Coastguard Worker        Requires<[HasT2ExtractPack, IsThumb2]>;
2013*9880d681SAndroid Build Coastguard Worker
2014*9880d681SAndroid Build Coastguard Workerdef t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
2015*9880d681SAndroid Build Coastguard Worker                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
2016*9880d681SAndroid Build Coastguard Workerdef t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
2017*9880d681SAndroid Build Coastguard Worker                           BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
2018*9880d681SAndroid Build Coastguard Workerdef t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">;
2019*9880d681SAndroid Build Coastguard Worker
2020*9880d681SAndroid Build Coastguard Workerdef : Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), 0xFF)),
2021*9880d681SAndroid Build Coastguard Worker          (t2UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>,
2022*9880d681SAndroid Build Coastguard Worker      Requires<[HasT2ExtractPack, IsThumb2]>;
2023*9880d681SAndroid Build Coastguard Workerdef : Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), 0xFFFF)),
2024*9880d681SAndroid Build Coastguard Worker          (t2UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>,
2025*9880d681SAndroid Build Coastguard Worker      Requires<[HasT2ExtractPack, IsThumb2]>;
2026*9880d681SAndroid Build Coastguard Worker}
2027*9880d681SAndroid Build Coastguard Worker
2028*9880d681SAndroid Build Coastguard Worker
2029*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2030*9880d681SAndroid Build Coastguard Worker//  Arithmetic Instructions.
2031*9880d681SAndroid Build Coastguard Worker//
2032*9880d681SAndroid Build Coastguard Worker
2033*9880d681SAndroid Build Coastguard Workerdefm t2ADD  : T2I_bin_ii12rs<0b000, "add", add, 1>;
2034*9880d681SAndroid Build Coastguard Workerdefm t2SUB  : T2I_bin_ii12rs<0b101, "sub", sub>;
2035*9880d681SAndroid Build Coastguard Worker
2036*9880d681SAndroid Build Coastguard Worker// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
2037*9880d681SAndroid Build Coastguard Worker//
2038*9880d681SAndroid Build Coastguard Worker// Currently, t2ADDS/t2SUBS are pseudo opcodes that exist only in the
2039*9880d681SAndroid Build Coastguard Worker// selection DAG. They are "lowered" to real t2ADD/t2SUB opcodes by
2040*9880d681SAndroid Build Coastguard Worker// AdjustInstrPostInstrSelection where we determine whether or not to
2041*9880d681SAndroid Build Coastguard Worker// set the "s" bit based on CPSR liveness.
2042*9880d681SAndroid Build Coastguard Worker//
2043*9880d681SAndroid Build Coastguard Worker// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen
2044*9880d681SAndroid Build Coastguard Worker// support for an optional CPSR definition that corresponds to the DAG
2045*9880d681SAndroid Build Coastguard Worker// node's second value. We can then eliminate the implicit def of CPSR.
2046*9880d681SAndroid Build Coastguard Workerdefm t2ADDS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, ARMaddc, 1>;
2047*9880d681SAndroid Build Coastguard Workerdefm t2SUBS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, ARMsubc>;
2048*9880d681SAndroid Build Coastguard Worker
2049*9880d681SAndroid Build Coastguard Workerlet hasPostISelHook = 1 in {
2050*9880d681SAndroid Build Coastguard Workerdefm t2ADC  : T2I_adde_sube_irs<0b1010, "adc", ARMadde, 1>;
2051*9880d681SAndroid Build Coastguard Workerdefm t2SBC  : T2I_adde_sube_irs<0b1011, "sbc", ARMsube>;
2052*9880d681SAndroid Build Coastguard Worker}
2053*9880d681SAndroid Build Coastguard Worker
2054*9880d681SAndroid Build Coastguard Worker// RSB
2055*9880d681SAndroid Build Coastguard Workerdefm t2RSB  : T2I_rbin_irs  <0b1110, "rsb", sub>;
2056*9880d681SAndroid Build Coastguard Worker
2057*9880d681SAndroid Build Coastguard Worker// FIXME: Eliminate them if we can write def : Pat patterns which defines
2058*9880d681SAndroid Build Coastguard Worker// CPSR and the implicit def of CPSR is not needed.
2059*9880d681SAndroid Build Coastguard Workerdefm t2RSBS : T2I_rbin_s_is <ARMsubc>;
2060*9880d681SAndroid Build Coastguard Worker
2061*9880d681SAndroid Build Coastguard Worker// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
2062*9880d681SAndroid Build Coastguard Worker// The assume-no-carry-in form uses the negation of the input since add/sub
2063*9880d681SAndroid Build Coastguard Worker// assume opposite meanings of the carry flag (i.e., carry == !borrow).
2064*9880d681SAndroid Build Coastguard Worker// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
2065*9880d681SAndroid Build Coastguard Worker// details.
2066*9880d681SAndroid Build Coastguard Worker// The AddedComplexity preferences the first variant over the others since
2067*9880d681SAndroid Build Coastguard Worker// it can be shrunk to a 16-bit wide encoding, while the others cannot.
2068*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in
2069*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add        GPR:$src, imm1_255_neg:$imm),
2070*9880d681SAndroid Build Coastguard Worker            (t2SUBri    GPR:$src, imm1_255_neg:$imm)>;
2071*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add        GPR:$src, t2_so_imm_neg:$imm),
2072*9880d681SAndroid Build Coastguard Worker            (t2SUBri    GPR:$src, t2_so_imm_neg:$imm)>;
2073*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add        GPR:$src, imm0_4095_neg:$imm),
2074*9880d681SAndroid Build Coastguard Worker            (t2SUBri12  GPR:$src, imm0_4095_neg:$imm)>;
2075*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add        GPR:$src, imm0_65535_neg:$imm),
2076*9880d681SAndroid Build Coastguard Worker            (t2SUBrr    GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>;
2077*9880d681SAndroid Build Coastguard Worker
2078*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in
2079*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMaddc    rGPR:$src, imm1_255_neg:$imm),
2080*9880d681SAndroid Build Coastguard Worker            (t2SUBSri   rGPR:$src, imm1_255_neg:$imm)>;
2081*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMaddc    rGPR:$src, t2_so_imm_neg:$imm),
2082*9880d681SAndroid Build Coastguard Worker            (t2SUBSri   rGPR:$src, t2_so_imm_neg:$imm)>;
2083*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMaddc    rGPR:$src, imm0_65535_neg:$imm),
2084*9880d681SAndroid Build Coastguard Worker            (t2SUBSrr   rGPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>;
2085*9880d681SAndroid Build Coastguard Worker// The with-carry-in form matches bitwise not instead of the negation.
2086*9880d681SAndroid Build Coastguard Worker// Effectively, the inverse interpretation of the carry flag already accounts
2087*9880d681SAndroid Build Coastguard Worker// for part of the negation.
2088*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in
2089*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMadde    rGPR:$src, imm0_255_not:$imm, CPSR),
2090*9880d681SAndroid Build Coastguard Worker            (t2SBCri    rGPR:$src, imm0_255_not:$imm)>;
2091*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMadde    rGPR:$src, t2_so_imm_not:$imm, CPSR),
2092*9880d681SAndroid Build Coastguard Worker            (t2SBCri    rGPR:$src, t2_so_imm_not:$imm)>;
2093*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMadde    rGPR:$src, imm0_65535_neg:$imm, CPSR),
2094*9880d681SAndroid Build Coastguard Worker            (t2SBCrr    rGPR:$src, (t2MOVi16 (imm_not_XFORM imm:$imm)))>;
2095*9880d681SAndroid Build Coastguard Worker
2096*9880d681SAndroid Build Coastguard Worker// Select Bytes -- for disassembly only
2097*9880d681SAndroid Build Coastguard Worker
2098*9880d681SAndroid Build Coastguard Workerdef t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
2099*9880d681SAndroid Build Coastguard Worker                NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []>,
2100*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2101*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2102*9880d681SAndroid Build Coastguard Worker  let Inst{26-24} = 0b010;
2103*9880d681SAndroid Build Coastguard Worker  let Inst{23} = 0b1;
2104*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b010;
2105*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2106*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 0b1;
2107*9880d681SAndroid Build Coastguard Worker  let Inst{6-4} = 0b000;
2108*9880d681SAndroid Build Coastguard Worker}
2109*9880d681SAndroid Build Coastguard Worker
2110*9880d681SAndroid Build Coastguard Worker// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
2111*9880d681SAndroid Build Coastguard Worker// And Miscellaneous operations -- for disassembly only
2112*9880d681SAndroid Build Coastguard Workerclass T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc,
2113*9880d681SAndroid Build Coastguard Worker              list<dag> pat = [/* For disassembly only; pattern left blank */],
2114*9880d681SAndroid Build Coastguard Worker              dag iops = (ins rGPR:$Rn, rGPR:$Rm),
2115*9880d681SAndroid Build Coastguard Worker              string asm = "\t$Rd, $Rn, $Rm">
2116*9880d681SAndroid Build Coastguard Worker  : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat>,
2117*9880d681SAndroid Build Coastguard Worker    Requires<[IsThumb2, HasDSP]> {
2118*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2119*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0101;
2120*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = op22_20;
2121*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2122*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = op7_4;
2123*9880d681SAndroid Build Coastguard Worker
2124*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
2125*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
2126*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
2127*9880d681SAndroid Build Coastguard Worker
2128*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
2129*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
2130*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rm;
2131*9880d681SAndroid Build Coastguard Worker}
2132*9880d681SAndroid Build Coastguard Worker
2133*9880d681SAndroid Build Coastguard Worker// Saturating add/subtract -- for disassembly only
2134*9880d681SAndroid Build Coastguard Worker
2135*9880d681SAndroid Build Coastguard Workerdef t2QADD    : T2I_pam<0b000, 0b1000, "qadd",
2136*9880d681SAndroid Build Coastguard Worker                        [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))],
2137*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
2138*9880d681SAndroid Build Coastguard Workerdef t2QADD16  : T2I_pam<0b001, 0b0001, "qadd16">;
2139*9880d681SAndroid Build Coastguard Workerdef t2QADD8   : T2I_pam<0b000, 0b0001, "qadd8">;
2140*9880d681SAndroid Build Coastguard Workerdef t2QASX    : T2I_pam<0b010, 0b0001, "qasx">;
2141*9880d681SAndroid Build Coastguard Workerdef t2QDADD   : T2I_pam<0b000, 0b1001, "qdadd", [],
2142*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
2143*9880d681SAndroid Build Coastguard Workerdef t2QDSUB   : T2I_pam<0b000, 0b1011, "qdsub", [],
2144*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
2145*9880d681SAndroid Build Coastguard Workerdef t2QSAX    : T2I_pam<0b110, 0b0001, "qsax">;
2146*9880d681SAndroid Build Coastguard Workerdef t2QSUB    : T2I_pam<0b000, 0b1010, "qsub",
2147*9880d681SAndroid Build Coastguard Worker                        [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))],
2148*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">;
2149*9880d681SAndroid Build Coastguard Workerdef t2QSUB16  : T2I_pam<0b101, 0b0001, "qsub16">;
2150*9880d681SAndroid Build Coastguard Workerdef t2QSUB8   : T2I_pam<0b100, 0b0001, "qsub8">;
2151*9880d681SAndroid Build Coastguard Workerdef t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
2152*9880d681SAndroid Build Coastguard Workerdef t2UQADD8  : T2I_pam<0b000, 0b0101, "uqadd8">;
2153*9880d681SAndroid Build Coastguard Workerdef t2UQASX   : T2I_pam<0b010, 0b0101, "uqasx">;
2154*9880d681SAndroid Build Coastguard Workerdef t2UQSAX   : T2I_pam<0b110, 0b0101, "uqsax">;
2155*9880d681SAndroid Build Coastguard Workerdef t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
2156*9880d681SAndroid Build Coastguard Workerdef t2UQSUB8  : T2I_pam<0b100, 0b0101, "uqsub8">;
2157*9880d681SAndroid Build Coastguard Worker
2158*9880d681SAndroid Build Coastguard Worker// Signed/Unsigned add/subtract -- for disassembly only
2159*9880d681SAndroid Build Coastguard Worker
2160*9880d681SAndroid Build Coastguard Workerdef t2SASX    : T2I_pam<0b010, 0b0000, "sasx">;
2161*9880d681SAndroid Build Coastguard Workerdef t2SADD16  : T2I_pam<0b001, 0b0000, "sadd16">;
2162*9880d681SAndroid Build Coastguard Workerdef t2SADD8   : T2I_pam<0b000, 0b0000, "sadd8">;
2163*9880d681SAndroid Build Coastguard Workerdef t2SSAX    : T2I_pam<0b110, 0b0000, "ssax">;
2164*9880d681SAndroid Build Coastguard Workerdef t2SSUB16  : T2I_pam<0b101, 0b0000, "ssub16">;
2165*9880d681SAndroid Build Coastguard Workerdef t2SSUB8   : T2I_pam<0b100, 0b0000, "ssub8">;
2166*9880d681SAndroid Build Coastguard Workerdef t2UASX    : T2I_pam<0b010, 0b0100, "uasx">;
2167*9880d681SAndroid Build Coastguard Workerdef t2UADD16  : T2I_pam<0b001, 0b0100, "uadd16">;
2168*9880d681SAndroid Build Coastguard Workerdef t2UADD8   : T2I_pam<0b000, 0b0100, "uadd8">;
2169*9880d681SAndroid Build Coastguard Workerdef t2USAX    : T2I_pam<0b110, 0b0100, "usax">;
2170*9880d681SAndroid Build Coastguard Workerdef t2USUB16  : T2I_pam<0b101, 0b0100, "usub16">;
2171*9880d681SAndroid Build Coastguard Workerdef t2USUB8   : T2I_pam<0b100, 0b0100, "usub8">;
2172*9880d681SAndroid Build Coastguard Worker
2173*9880d681SAndroid Build Coastguard Worker// Signed/Unsigned halving add/subtract -- for disassembly only
2174*9880d681SAndroid Build Coastguard Worker
2175*9880d681SAndroid Build Coastguard Workerdef t2SHASX   : T2I_pam<0b010, 0b0010, "shasx">;
2176*9880d681SAndroid Build Coastguard Workerdef t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
2177*9880d681SAndroid Build Coastguard Workerdef t2SHADD8  : T2I_pam<0b000, 0b0010, "shadd8">;
2178*9880d681SAndroid Build Coastguard Workerdef t2SHSAX   : T2I_pam<0b110, 0b0010, "shsax">;
2179*9880d681SAndroid Build Coastguard Workerdef t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
2180*9880d681SAndroid Build Coastguard Workerdef t2SHSUB8  : T2I_pam<0b100, 0b0010, "shsub8">;
2181*9880d681SAndroid Build Coastguard Workerdef t2UHASX   : T2I_pam<0b010, 0b0110, "uhasx">;
2182*9880d681SAndroid Build Coastguard Workerdef t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
2183*9880d681SAndroid Build Coastguard Workerdef t2UHADD8  : T2I_pam<0b000, 0b0110, "uhadd8">;
2184*9880d681SAndroid Build Coastguard Workerdef t2UHSAX   : T2I_pam<0b110, 0b0110, "uhsax">;
2185*9880d681SAndroid Build Coastguard Workerdef t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
2186*9880d681SAndroid Build Coastguard Workerdef t2UHSUB8  : T2I_pam<0b100, 0b0110, "uhsub8">;
2187*9880d681SAndroid Build Coastguard Worker
2188*9880d681SAndroid Build Coastguard Worker// Helper class for disassembly only
2189*9880d681SAndroid Build Coastguard Worker// A6.3.16 & A6.3.17
2190*9880d681SAndroid Build Coastguard Worker// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
2191*9880d681SAndroid Build Coastguard Workerclass T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
2192*9880d681SAndroid Build Coastguard Worker  dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
2193*9880d681SAndroid Build Coastguard Worker  : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2194*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2195*9880d681SAndroid Build Coastguard Worker  let Inst{26-24} = 0b011;
2196*9880d681SAndroid Build Coastguard Worker  let Inst{23}    = long;
2197*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = op22_20;
2198*9880d681SAndroid Build Coastguard Worker  let Inst{7-4}   = op7_4;
2199*9880d681SAndroid Build Coastguard Worker}
2200*9880d681SAndroid Build Coastguard Worker
2201*9880d681SAndroid Build Coastguard Workerclass T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops,
2202*9880d681SAndroid Build Coastguard Worker  dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern>
2203*9880d681SAndroid Build Coastguard Worker  : T2FourReg<oops, iops, itin, opc, asm, pattern> {
2204*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2205*9880d681SAndroid Build Coastguard Worker  let Inst{26-24} = 0b011;
2206*9880d681SAndroid Build Coastguard Worker  let Inst{23}    = long;
2207*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = op22_20;
2208*9880d681SAndroid Build Coastguard Worker  let Inst{7-4}   = op7_4;
2209*9880d681SAndroid Build Coastguard Worker}
2210*9880d681SAndroid Build Coastguard Worker
2211*9880d681SAndroid Build Coastguard Worker// Unsigned Sum of Absolute Differences [and Accumulate].
2212*9880d681SAndroid Build Coastguard Workerdef t2USAD8   : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
2213*9880d681SAndroid Build Coastguard Worker                                           (ins rGPR:$Rn, rGPR:$Rm),
2214*9880d681SAndroid Build Coastguard Worker                        NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []>,
2215*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2216*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2217*9880d681SAndroid Build Coastguard Worker}
2218*9880d681SAndroid Build Coastguard Workerdef t2USADA8  : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd),
2219*9880d681SAndroid Build Coastguard Worker                       (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary,
2220*9880d681SAndroid Build Coastguard Worker                        "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>,
2221*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2222*9880d681SAndroid Build Coastguard Worker
2223*9880d681SAndroid Build Coastguard Worker// Signed/Unsigned saturate.
2224*9880d681SAndroid Build Coastguard Workerclass T2SatI<dag oops, dag iops, InstrItinClass itin,
2225*9880d681SAndroid Build Coastguard Worker           string opc, string asm, list<dag> pattern>
2226*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern> {
2227*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
2228*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
2229*9880d681SAndroid Build Coastguard Worker  bits<5> sat_imm;
2230*9880d681SAndroid Build Coastguard Worker  bits<7> sh;
2231*9880d681SAndroid Build Coastguard Worker
2232*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
2233*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
2234*9880d681SAndroid Build Coastguard Worker  let Inst{4-0}   = sat_imm;
2235*9880d681SAndroid Build Coastguard Worker  let Inst{21}    = sh{5};
2236*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = sh{4-2};
2237*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = sh{1-0};
2238*9880d681SAndroid Build Coastguard Worker}
2239*9880d681SAndroid Build Coastguard Worker
2240*9880d681SAndroid Build Coastguard Workerdef t2SSAT: T2SatI<
2241*9880d681SAndroid Build Coastguard Worker              (outs rGPR:$Rd),
2242*9880d681SAndroid Build Coastguard Worker              (ins imm1_32:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
2243*9880d681SAndroid Build Coastguard Worker              NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
2244*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2245*9880d681SAndroid Build Coastguard Worker  let Inst{25-22} = 0b1100;
2246*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0;
2247*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2248*9880d681SAndroid Build Coastguard Worker  let Inst{5}  = 0;
2249*9880d681SAndroid Build Coastguard Worker}
2250*9880d681SAndroid Build Coastguard Worker
2251*9880d681SAndroid Build Coastguard Workerdef t2SSAT16: T2SatI<
2252*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary,
2253*9880d681SAndroid Build Coastguard Worker                "ssat16", "\t$Rd, $sat_imm, $Rn", []>,
2254*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2255*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2256*9880d681SAndroid Build Coastguard Worker  let Inst{25-22} = 0b1100;
2257*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0;
2258*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2259*9880d681SAndroid Build Coastguard Worker  let Inst{21} = 1;        // sh = '1'
2260*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000; // imm3 = '000'
2261*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = 0b00;    // imm2 = '00'
2262*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = 0b00;
2263*9880d681SAndroid Build Coastguard Worker}
2264*9880d681SAndroid Build Coastguard Worker
2265*9880d681SAndroid Build Coastguard Workerdef t2USAT: T2SatI<
2266*9880d681SAndroid Build Coastguard Worker               (outs rGPR:$Rd),
2267*9880d681SAndroid Build Coastguard Worker               (ins imm0_31:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
2268*9880d681SAndroid Build Coastguard Worker                NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
2269*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2270*9880d681SAndroid Build Coastguard Worker  let Inst{25-22} = 0b1110;
2271*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0;
2272*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2273*9880d681SAndroid Build Coastguard Worker}
2274*9880d681SAndroid Build Coastguard Worker
2275*9880d681SAndroid Build Coastguard Workerdef t2USAT16: T2SatI<(outs rGPR:$Rd), (ins imm0_15:$sat_imm, rGPR:$Rn),
2276*9880d681SAndroid Build Coastguard Worker                     NoItinerary,
2277*9880d681SAndroid Build Coastguard Worker                     "usat16", "\t$Rd, $sat_imm, $Rn", []>,
2278*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2279*9880d681SAndroid Build Coastguard Worker  let Inst{31-22} = 0b1111001110;
2280*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0;
2281*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2282*9880d681SAndroid Build Coastguard Worker  let Inst{21} = 1;        // sh = '1'
2283*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000; // imm3 = '000'
2284*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = 0b00;    // imm2 = '00'
2285*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = 0b00;
2286*9880d681SAndroid Build Coastguard Worker}
2287*9880d681SAndroid Build Coastguard Worker
2288*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(int_arm_ssat GPR:$a, imm1_32:$pos), (t2SSAT imm1_32:$pos, GPR:$a, 0)>;
2289*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(int_arm_usat GPR:$a, imm0_31:$pos), (t2USAT imm0_31:$pos, GPR:$a, 0)>;
2290*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMssatnoshift GPRnopc:$Rn, imm0_31:$imm),
2291*9880d681SAndroid Build Coastguard Worker             (t2SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>;
2292*9880d681SAndroid Build Coastguard Worker
2293*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2294*9880d681SAndroid Build Coastguard Worker//  Shift and rotate Instructions.
2295*9880d681SAndroid Build Coastguard Worker//
2296*9880d681SAndroid Build Coastguard Worker
2297*9880d681SAndroid Build Coastguard Workerdefm t2LSL  : T2I_sh_ir<0b00, "lsl", imm0_31, shl>;
2298*9880d681SAndroid Build Coastguard Workerdefm t2LSR  : T2I_sh_ir<0b01, "lsr", imm_sr,  srl>;
2299*9880d681SAndroid Build Coastguard Workerdefm t2ASR  : T2I_sh_ir<0b10, "asr", imm_sr,  sra>;
2300*9880d681SAndroid Build Coastguard Workerdefm t2ROR  : T2I_sh_ir<0b11, "ror", imm0_31, rotr>;
2301*9880d681SAndroid Build Coastguard Worker
2302*9880d681SAndroid Build Coastguard Worker// (rotr x, (and y, 0x...1f)) ==> (ROR x, y)
2303*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(rotr rGPR:$lhs, (and rGPR:$rhs, lo5AllOne)),
2304*9880d681SAndroid Build Coastguard Worker            (t2RORrr rGPR:$lhs, rGPR:$rhs)>;
2305*9880d681SAndroid Build Coastguard Worker
2306*9880d681SAndroid Build Coastguard Workerlet Uses = [CPSR] in {
2307*9880d681SAndroid Build Coastguard Workerdef t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2308*9880d681SAndroid Build Coastguard Worker                   "rrx", "\t$Rd, $Rm",
2309*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]>, Sched<[WriteALU]> {
2310*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
2311*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
2312*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
2313*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
2314*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000;
2315*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0011;
2316*9880d681SAndroid Build Coastguard Worker}
2317*9880d681SAndroid Build Coastguard Worker}
2318*9880d681SAndroid Build Coastguard Worker
2319*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, Defs = [CPSR] in {
2320*9880d681SAndroid Build Coastguard Workerdef t2MOVsrl_flag : T2TwoRegShiftImm<
2321*9880d681SAndroid Build Coastguard Worker                        (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2322*9880d681SAndroid Build Coastguard Worker                        "lsrs", ".w\t$Rd, $Rm, #1",
2323*9880d681SAndroid Build Coastguard Worker                        [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]>,
2324*9880d681SAndroid Build Coastguard Worker                        Sched<[WriteALU]> {
2325*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
2326*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
2327*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
2328*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 1; // The S bit.
2329*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
2330*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = 0b01; // Shift type.
2331*9880d681SAndroid Build Coastguard Worker  // Shift amount = Inst{14-12:7-6} = 1.
2332*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000;
2333*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = 0b01;
2334*9880d681SAndroid Build Coastguard Worker}
2335*9880d681SAndroid Build Coastguard Workerdef t2MOVsra_flag : T2TwoRegShiftImm<
2336*9880d681SAndroid Build Coastguard Worker                        (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi,
2337*9880d681SAndroid Build Coastguard Worker                        "asrs", ".w\t$Rd, $Rm, #1",
2338*9880d681SAndroid Build Coastguard Worker                        [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]>,
2339*9880d681SAndroid Build Coastguard Worker                        Sched<[WriteALU]> {
2340*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
2341*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
2342*9880d681SAndroid Build Coastguard Worker  let Inst{24-21} = 0b0010;
2343*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 1; // The S bit.
2344*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
2345*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = 0b10; // Shift type.
2346*9880d681SAndroid Build Coastguard Worker  // Shift amount = Inst{14-12:7-6} = 1.
2347*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b000;
2348*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = 0b01;
2349*9880d681SAndroid Build Coastguard Worker}
2350*9880d681SAndroid Build Coastguard Worker}
2351*9880d681SAndroid Build Coastguard Worker
2352*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2353*9880d681SAndroid Build Coastguard Worker//  Bitwise Instructions.
2354*9880d681SAndroid Build Coastguard Worker//
2355*9880d681SAndroid Build Coastguard Worker
2356*9880d681SAndroid Build Coastguard Workerdefm t2AND  : T2I_bin_w_irs<0b0000, "and",
2357*9880d681SAndroid Build Coastguard Worker                            IIC_iBITi, IIC_iBITr, IIC_iBITsi, and, 1>;
2358*9880d681SAndroid Build Coastguard Workerdefm t2ORR  : T2I_bin_w_irs<0b0010, "orr",
2359*9880d681SAndroid Build Coastguard Worker                            IIC_iBITi, IIC_iBITr, IIC_iBITsi, or, 1>;
2360*9880d681SAndroid Build Coastguard Workerdefm t2EOR  : T2I_bin_w_irs<0b0100, "eor",
2361*9880d681SAndroid Build Coastguard Worker                            IIC_iBITi, IIC_iBITr, IIC_iBITsi, xor, 1>;
2362*9880d681SAndroid Build Coastguard Worker
2363*9880d681SAndroid Build Coastguard Workerdefm t2BIC  : T2I_bin_w_irs<0b0001, "bic",
2364*9880d681SAndroid Build Coastguard Worker                            IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2365*9880d681SAndroid Build Coastguard Worker                            BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
2366*9880d681SAndroid Build Coastguard Worker
2367*9880d681SAndroid Build Coastguard Workerclass T2BitFI<dag oops, dag iops, InstrItinClass itin,
2368*9880d681SAndroid Build Coastguard Worker              string opc, string asm, list<dag> pattern>
2369*9880d681SAndroid Build Coastguard Worker    : T2I<oops, iops, itin, opc, asm, pattern> {
2370*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
2371*9880d681SAndroid Build Coastguard Worker  bits<5> msb;
2372*9880d681SAndroid Build Coastguard Worker  bits<5> lsb;
2373*9880d681SAndroid Build Coastguard Worker
2374*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
2375*9880d681SAndroid Build Coastguard Worker  let Inst{4-0}   = msb{4-0};
2376*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = lsb{4-2};
2377*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = lsb{1-0};
2378*9880d681SAndroid Build Coastguard Worker}
2379*9880d681SAndroid Build Coastguard Worker
2380*9880d681SAndroid Build Coastguard Workerclass T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin,
2381*9880d681SAndroid Build Coastguard Worker              string opc, string asm, list<dag> pattern>
2382*9880d681SAndroid Build Coastguard Worker    : T2BitFI<oops, iops, itin, opc, asm, pattern> {
2383*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
2384*9880d681SAndroid Build Coastguard Worker
2385*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
2386*9880d681SAndroid Build Coastguard Worker}
2387*9880d681SAndroid Build Coastguard Worker
2388*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $Rd" in
2389*9880d681SAndroid Build Coastguard Workerdef t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
2390*9880d681SAndroid Build Coastguard Worker                IIC_iUNAsi, "bfc", "\t$Rd, $imm",
2391*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> {
2392*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2393*9880d681SAndroid Build Coastguard Worker  let Inst{26} = 0; // should be 0.
2394*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 1;
2395*9880d681SAndroid Build Coastguard Worker  let Inst{24-20} = 0b10110;
2396*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111; // Rn
2397*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2398*9880d681SAndroid Build Coastguard Worker  let Inst{5} = 0; // should be 0.
2399*9880d681SAndroid Build Coastguard Worker
2400*9880d681SAndroid Build Coastguard Worker  bits<10> imm;
2401*9880d681SAndroid Build Coastguard Worker  let msb{4-0} = imm{9-5};
2402*9880d681SAndroid Build Coastguard Worker  let lsb{4-0} = imm{4-0};
2403*9880d681SAndroid Build Coastguard Worker}
2404*9880d681SAndroid Build Coastguard Worker
2405*9880d681SAndroid Build Coastguard Workerdef t2SBFX: T2TwoRegBitFI<
2406*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
2407*9880d681SAndroid Build Coastguard Worker                 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2408*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2409*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 1;
2410*9880d681SAndroid Build Coastguard Worker  let Inst{24-20} = 0b10100;
2411*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2412*9880d681SAndroid Build Coastguard Worker}
2413*9880d681SAndroid Build Coastguard Worker
2414*9880d681SAndroid Build Coastguard Workerdef t2UBFX: T2TwoRegBitFI<
2415*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
2416*9880d681SAndroid Build Coastguard Worker                 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
2417*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
2418*9880d681SAndroid Build Coastguard Worker  let Inst{25} = 1;
2419*9880d681SAndroid Build Coastguard Worker  let Inst{24-20} = 0b11100;
2420*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0;
2421*9880d681SAndroid Build Coastguard Worker}
2422*9880d681SAndroid Build Coastguard Worker
2423*9880d681SAndroid Build Coastguard Worker// A8.8.247  UDF - Undefined (Encoding T2)
2424*9880d681SAndroid Build Coastguard Workerdef t2UDF : T2XI<(outs), (ins imm0_65535:$imm16), IIC_Br, "udf.w\t$imm16",
2425*9880d681SAndroid Build Coastguard Worker                 [(int_arm_undefined imm0_65535:$imm16)]> {
2426*9880d681SAndroid Build Coastguard Worker  bits<16> imm16;
2427*9880d681SAndroid Build Coastguard Worker  let Inst{31-29} = 0b111;
2428*9880d681SAndroid Build Coastguard Worker  let Inst{28-27} = 0b10;
2429*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b1111111;
2430*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = imm16{15-12};
2431*9880d681SAndroid Build Coastguard Worker  let Inst{15} = 0b1;
2432*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = 0b010;
2433*9880d681SAndroid Build Coastguard Worker  let Inst{11-0} = imm16{11-0};
2434*9880d681SAndroid Build Coastguard Worker}
2435*9880d681SAndroid Build Coastguard Worker
2436*9880d681SAndroid Build Coastguard Worker// A8.6.18  BFI - Bitfield insert (Encoding T1)
2437*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $Rd" in {
2438*9880d681SAndroid Build Coastguard Worker  def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
2439*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
2440*9880d681SAndroid Build Coastguard Worker                  IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
2441*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
2442*9880d681SAndroid Build Coastguard Worker                                   bf_inv_mask_imm:$imm))]> {
2443*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11110;
2444*9880d681SAndroid Build Coastguard Worker    let Inst{26} = 0; // should be 0.
2445*9880d681SAndroid Build Coastguard Worker    let Inst{25} = 1;
2446*9880d681SAndroid Build Coastguard Worker    let Inst{24-20} = 0b10110;
2447*9880d681SAndroid Build Coastguard Worker    let Inst{15} = 0;
2448*9880d681SAndroid Build Coastguard Worker    let Inst{5} = 0; // should be 0.
2449*9880d681SAndroid Build Coastguard Worker
2450*9880d681SAndroid Build Coastguard Worker    bits<10> imm;
2451*9880d681SAndroid Build Coastguard Worker    let msb{4-0} = imm{9-5};
2452*9880d681SAndroid Build Coastguard Worker    let lsb{4-0} = imm{4-0};
2453*9880d681SAndroid Build Coastguard Worker  }
2454*9880d681SAndroid Build Coastguard Worker}
2455*9880d681SAndroid Build Coastguard Worker
2456*9880d681SAndroid Build Coastguard Workerdefm t2ORN  : T2I_bin_irs<0b0011, "orn",
2457*9880d681SAndroid Build Coastguard Worker                          IIC_iBITi, IIC_iBITr, IIC_iBITsi,
2458*9880d681SAndroid Build Coastguard Worker                          BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">;
2459*9880d681SAndroid Build Coastguard Worker
2460*9880d681SAndroid Build Coastguard Worker/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
2461*9880d681SAndroid Build Coastguard Worker/// unary operation that produces a value. These are predicable and can be
2462*9880d681SAndroid Build Coastguard Worker/// changed to modify CPSR.
2463*9880d681SAndroid Build Coastguard Workermulticlass T2I_un_irs<bits<4> opcod, string opc,
2464*9880d681SAndroid Build Coastguard Worker                     InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
2465*9880d681SAndroid Build Coastguard Worker                      PatFrag opnode,
2466*9880d681SAndroid Build Coastguard Worker                      bit Cheap = 0, bit ReMat = 0, bit MoveImm = 0> {
2467*9880d681SAndroid Build Coastguard Worker   // shifted imm
2468*9880d681SAndroid Build Coastguard Worker   def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii,
2469*9880d681SAndroid Build Coastguard Worker                opc, "\t$Rd, $imm",
2470*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]>, Sched<[WriteALU]> {
2471*9880d681SAndroid Build Coastguard Worker     let isAsCheapAsAMove = Cheap;
2472*9880d681SAndroid Build Coastguard Worker     let isReMaterializable = ReMat;
2473*9880d681SAndroid Build Coastguard Worker     let isMoveImm = MoveImm;
2474*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
2475*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
2476*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
2477*9880d681SAndroid Build Coastguard Worker     let Inst{19-16} = 0b1111; // Rn
2478*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
2479*9880d681SAndroid Build Coastguard Worker   }
2480*9880d681SAndroid Build Coastguard Worker   // register
2481*9880d681SAndroid Build Coastguard Worker   def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir,
2482*9880d681SAndroid Build Coastguard Worker                opc, ".w\t$Rd, $Rm",
2483*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (opnode rGPR:$Rm))]>, Sched<[WriteALU]> {
2484*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
2485*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
2486*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
2487*9880d681SAndroid Build Coastguard Worker     let Inst{19-16} = 0b1111; // Rn
2488*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
2489*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
2490*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
2491*9880d681SAndroid Build Coastguard Worker   }
2492*9880d681SAndroid Build Coastguard Worker   // shifted register
2493*9880d681SAndroid Build Coastguard Worker   def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis,
2494*9880d681SAndroid Build Coastguard Worker                opc, ".w\t$Rd, $ShiftedRm",
2495*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]>,
2496*9880d681SAndroid Build Coastguard Worker                Sched<[WriteALU]> {
2497*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
2498*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
2499*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = opcod;
2500*9880d681SAndroid Build Coastguard Worker     let Inst{19-16} = 0b1111; // Rn
2501*9880d681SAndroid Build Coastguard Worker   }
2502*9880d681SAndroid Build Coastguard Worker}
2503*9880d681SAndroid Build Coastguard Worker
2504*9880d681SAndroid Build Coastguard Worker// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
2505*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in
2506*9880d681SAndroid Build Coastguard Workerdefm t2MVN  : T2I_un_irs <0b0011, "mvn",
2507*9880d681SAndroid Build Coastguard Worker                          IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi,
2508*9880d681SAndroid Build Coastguard Worker                          not, 1, 1, 1>;
2509*9880d681SAndroid Build Coastguard Worker
2510*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in
2511*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and     rGPR:$src, t2_so_imm_not:$imm),
2512*9880d681SAndroid Build Coastguard Worker            (t2BICri rGPR:$src, t2_so_imm_not:$imm)>;
2513*9880d681SAndroid Build Coastguard Worker
2514*9880d681SAndroid Build Coastguard Worker// top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise
2515*9880d681SAndroid Build Coastguard Workerdef top16Zero: PatLeaf<(i32 rGPR:$src), [{
2516*9880d681SAndroid Build Coastguard Worker  return CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16));
2517*9880d681SAndroid Build Coastguard Worker  }]>;
2518*9880d681SAndroid Build Coastguard Worker
2519*9880d681SAndroid Build Coastguard Worker// so_imm_notSext is needed instead of so_imm_not, as the value of imm
2520*9880d681SAndroid Build Coastguard Worker// will match the extended, not the original bitWidth for $src.
2521*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and top16Zero:$src, t2_so_imm_notSext:$imm),
2522*9880d681SAndroid Build Coastguard Worker            (t2BICri rGPR:$src, t2_so_imm_notSext:$imm)>;
2523*9880d681SAndroid Build Coastguard Worker
2524*9880d681SAndroid Build Coastguard Worker
2525*9880d681SAndroid Build Coastguard Worker// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
2526*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or      rGPR:$src, t2_so_imm_not:$imm),
2527*9880d681SAndroid Build Coastguard Worker            (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>,
2528*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb2]>;
2529*9880d681SAndroid Build Coastguard Worker
2530*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(t2_so_imm_not:$src),
2531*9880d681SAndroid Build Coastguard Worker            (t2MVNi t2_so_imm_not:$src)>;
2532*9880d681SAndroid Build Coastguard Worker
2533*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2534*9880d681SAndroid Build Coastguard Worker//  Multiply Instructions.
2535*9880d681SAndroid Build Coastguard Worker//
2536*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
2537*9880d681SAndroid Build Coastguard Workerdef t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2538*9880d681SAndroid Build Coastguard Worker                "mul", "\t$Rd, $Rn, $Rm",
2539*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> {
2540*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2541*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2542*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b000;
2543*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2544*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000; // Multiply
2545*9880d681SAndroid Build Coastguard Worker}
2546*9880d681SAndroid Build Coastguard Worker
2547*9880d681SAndroid Build Coastguard Workerdef t2MLA: T2FourReg<
2548*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2549*9880d681SAndroid Build Coastguard Worker                "mla", "\t$Rd, $Rn, $Rm, $Ra",
2550*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]>,
2551*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, UseMulOps]> {
2552*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2553*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2554*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b000;
2555*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000; // Multiply
2556*9880d681SAndroid Build Coastguard Worker}
2557*9880d681SAndroid Build Coastguard Worker
2558*9880d681SAndroid Build Coastguard Workerdef t2MLS: T2FourReg<
2559*9880d681SAndroid Build Coastguard Worker                (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2560*9880d681SAndroid Build Coastguard Worker                "mls", "\t$Rd, $Rn, $Rm, $Ra",
2561*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]>,
2562*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, UseMulOps]> {
2563*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2564*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2565*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b000;
2566*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0001; // Multiply and Subtract
2567*9880d681SAndroid Build Coastguard Worker}
2568*9880d681SAndroid Build Coastguard Worker
2569*9880d681SAndroid Build Coastguard Worker// Extra precision multiplies with low / high results
2570*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in {
2571*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in {
2572*9880d681SAndroid Build Coastguard Workerdef t2SMULL : T2MulLong<0b000, 0b0000,
2573*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$RdLo, rGPR:$RdHi),
2574*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2575*9880d681SAndroid Build Coastguard Worker                   "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2576*9880d681SAndroid Build Coastguard Worker
2577*9880d681SAndroid Build Coastguard Workerdef t2UMULL : T2MulLong<0b010, 0b0000,
2578*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$RdLo, rGPR:$RdHi),
2579*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64,
2580*9880d681SAndroid Build Coastguard Worker                   "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
2581*9880d681SAndroid Build Coastguard Worker} // isCommutable
2582*9880d681SAndroid Build Coastguard Worker
2583*9880d681SAndroid Build Coastguard Worker// Multiply + accumulate
2584*9880d681SAndroid Build Coastguard Workerdef t2SMLAL : T2MlaLong<0b100, 0b0000,
2585*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$RdLo, rGPR:$RdHi),
2586*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
2587*9880d681SAndroid Build Coastguard Worker                  "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2588*9880d681SAndroid Build Coastguard Worker                  RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">;
2589*9880d681SAndroid Build Coastguard Worker
2590*9880d681SAndroid Build Coastguard Workerdef t2UMLAL : T2MlaLong<0b110, 0b0000,
2591*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$RdLo, rGPR:$RdHi),
2592*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
2593*9880d681SAndroid Build Coastguard Worker                  "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2594*9880d681SAndroid Build Coastguard Worker                  RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">;
2595*9880d681SAndroid Build Coastguard Worker
2596*9880d681SAndroid Build Coastguard Workerdef t2UMAAL : T2MulLong<0b110, 0b0110,
2597*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$RdLo, rGPR:$RdHi),
2598*9880d681SAndroid Build Coastguard Worker                  (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64,
2599*9880d681SAndroid Build Coastguard Worker                  "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
2600*9880d681SAndroid Build Coastguard Worker          RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">,
2601*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2602*9880d681SAndroid Build Coastguard Worker} // hasSideEffects
2603*9880d681SAndroid Build Coastguard Worker
2604*9880d681SAndroid Build Coastguard Worker// Rounding variants of the below included for disassembly only
2605*9880d681SAndroid Build Coastguard Worker
2606*9880d681SAndroid Build Coastguard Worker// Most significant word multiply
2607*9880d681SAndroid Build Coastguard Workerdef t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2608*9880d681SAndroid Build Coastguard Worker                  "smmul", "\t$Rd, $Rn, $Rm",
2609*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]>,
2610*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2611*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2612*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2613*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b101;
2614*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2615*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2616*9880d681SAndroid Build Coastguard Worker}
2617*9880d681SAndroid Build Coastguard Worker
2618*9880d681SAndroid Build Coastguard Workerdef t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32,
2619*9880d681SAndroid Build Coastguard Worker                  "smmulr", "\t$Rd, $Rn, $Rm", []>,
2620*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2621*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2622*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2623*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b101;
2624*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2625*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2626*9880d681SAndroid Build Coastguard Worker}
2627*9880d681SAndroid Build Coastguard Worker
2628*9880d681SAndroid Build Coastguard Workerdef t2SMMLA : T2FourReg<
2629*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2630*9880d681SAndroid Build Coastguard Worker                "smmla", "\t$Rd, $Rn, $Rm, $Ra",
2631*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>,
2632*9880d681SAndroid Build Coastguard Worker              Requires<[IsThumb2, HasDSP, UseMulOps]> {
2633*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2634*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2635*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b101;
2636*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2637*9880d681SAndroid Build Coastguard Worker}
2638*9880d681SAndroid Build Coastguard Worker
2639*9880d681SAndroid Build Coastguard Workerdef t2SMMLAR: T2FourReg<
2640*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2641*9880d681SAndroid Build Coastguard Worker                  "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>,
2642*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2643*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2644*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2645*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b101;
2646*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2647*9880d681SAndroid Build Coastguard Worker}
2648*9880d681SAndroid Build Coastguard Worker
2649*9880d681SAndroid Build Coastguard Workerdef t2SMMLS: T2FourReg<
2650*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2651*9880d681SAndroid Build Coastguard Worker                "smmls", "\t$Rd, $Rn, $Rm, $Ra",
2652*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>,
2653*9880d681SAndroid Build Coastguard Worker             Requires<[IsThumb2, HasDSP, UseMulOps]> {
2654*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2655*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2656*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b110;
2657*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0)
2658*9880d681SAndroid Build Coastguard Worker}
2659*9880d681SAndroid Build Coastguard Worker
2660*9880d681SAndroid Build Coastguard Workerdef t2SMMLSR:T2FourReg<
2661*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32,
2662*9880d681SAndroid Build Coastguard Worker                "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>,
2663*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2664*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2665*9880d681SAndroid Build Coastguard Worker  let Inst{26-23} = 0b0110;
2666*9880d681SAndroid Build Coastguard Worker  let Inst{22-20} = 0b110;
2667*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1)
2668*9880d681SAndroid Build Coastguard Worker}
2669*9880d681SAndroid Build Coastguard Worker
2670*9880d681SAndroid Build Coastguard Workermulticlass T2I_smul<string opc, SDNode opnode> {
2671*9880d681SAndroid Build Coastguard Worker  def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2672*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
2673*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2674*9880d681SAndroid Build Coastguard Worker                                      (sext_inreg rGPR:$Rm, i16)))]>,
2675*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2676*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2677*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2678*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2679*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2680*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2681*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b00;
2682*9880d681SAndroid Build Coastguard Worker  }
2683*9880d681SAndroid Build Coastguard Worker
2684*9880d681SAndroid Build Coastguard Worker  def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2685*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
2686*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16),
2687*9880d681SAndroid Build Coastguard Worker                                      (sra rGPR:$Rm, (i32 16))))]>,
2688*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2689*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2690*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2691*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2692*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2693*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2694*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b01;
2695*9880d681SAndroid Build Coastguard Worker  }
2696*9880d681SAndroid Build Coastguard Worker
2697*9880d681SAndroid Build Coastguard Worker  def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2698*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
2699*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2700*9880d681SAndroid Build Coastguard Worker                                      (sext_inreg rGPR:$Rm, i16)))]>,
2701*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2702*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2703*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2704*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2705*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2706*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2707*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b10;
2708*9880d681SAndroid Build Coastguard Worker  }
2709*9880d681SAndroid Build Coastguard Worker
2710*9880d681SAndroid Build Coastguard Worker  def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2711*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
2712*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)),
2713*9880d681SAndroid Build Coastguard Worker                                      (sra rGPR:$Rm, (i32 16))))]>,
2714*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2715*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2716*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2717*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2718*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2719*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2720*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b11;
2721*9880d681SAndroid Build Coastguard Worker  }
2722*9880d681SAndroid Build Coastguard Worker
2723*9880d681SAndroid Build Coastguard Worker  def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2724*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
2725*9880d681SAndroid Build Coastguard Worker              []>,
2726*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2727*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2728*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2729*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b011;
2730*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2731*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2732*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b00;
2733*9880d681SAndroid Build Coastguard Worker  }
2734*9880d681SAndroid Build Coastguard Worker
2735*9880d681SAndroid Build Coastguard Worker  def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16,
2736*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
2737*9880d681SAndroid Build Coastguard Worker              []>,
2738*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2739*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2740*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2741*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b011;
2742*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate)
2743*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2744*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b01;
2745*9880d681SAndroid Build Coastguard Worker  }
2746*9880d681SAndroid Build Coastguard Worker}
2747*9880d681SAndroid Build Coastguard Worker
2748*9880d681SAndroid Build Coastguard Worker
2749*9880d681SAndroid Build Coastguard Workermulticlass T2I_smla<string opc, SDNode opnode> {
2750*9880d681SAndroid Build Coastguard Worker  def BB : T2FourReg<
2751*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2752*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
2753*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (add rGPR:$Ra,
2754*9880d681SAndroid Build Coastguard Worker                               (opnode (sext_inreg rGPR:$Rn, i16),
2755*9880d681SAndroid Build Coastguard Worker                                       (sext_inreg rGPR:$Rm, i16))))]>,
2756*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2757*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2758*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2759*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2760*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2761*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b00;
2762*9880d681SAndroid Build Coastguard Worker  }
2763*9880d681SAndroid Build Coastguard Worker
2764*9880d681SAndroid Build Coastguard Worker  def BT : T2FourReg<
2765*9880d681SAndroid Build Coastguard Worker       (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2766*9880d681SAndroid Build Coastguard Worker             !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
2767*9880d681SAndroid Build Coastguard Worker             [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16),
2768*9880d681SAndroid Build Coastguard Worker                                                 (sra rGPR:$Rm, (i32 16)))))]>,
2769*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2770*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2771*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2772*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2773*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2774*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b01;
2775*9880d681SAndroid Build Coastguard Worker  }
2776*9880d681SAndroid Build Coastguard Worker
2777*9880d681SAndroid Build Coastguard Worker  def TB : T2FourReg<
2778*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2779*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
2780*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2781*9880d681SAndroid Build Coastguard Worker                                               (sext_inreg rGPR:$Rm, i16))))]>,
2782*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2783*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2784*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2785*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2786*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2787*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b10;
2788*9880d681SAndroid Build Coastguard Worker  }
2789*9880d681SAndroid Build Coastguard Worker
2790*9880d681SAndroid Build Coastguard Worker  def TT : T2FourReg<
2791*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2792*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
2793*9880d681SAndroid Build Coastguard Worker             [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)),
2794*9880d681SAndroid Build Coastguard Worker                                                 (sra rGPR:$Rm, (i32 16)))))]>,
2795*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2796*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2797*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2798*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b001;
2799*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2800*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b11;
2801*9880d681SAndroid Build Coastguard Worker  }
2802*9880d681SAndroid Build Coastguard Worker
2803*9880d681SAndroid Build Coastguard Worker  def WB : T2FourReg<
2804*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2805*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
2806*9880d681SAndroid Build Coastguard Worker              []>,
2807*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2808*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2809*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2810*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b011;
2811*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2812*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b00;
2813*9880d681SAndroid Build Coastguard Worker  }
2814*9880d681SAndroid Build Coastguard Worker
2815*9880d681SAndroid Build Coastguard Worker  def WT : T2FourReg<
2816*9880d681SAndroid Build Coastguard Worker        (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16,
2817*9880d681SAndroid Build Coastguard Worker              !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
2818*9880d681SAndroid Build Coastguard Worker              []>,
2819*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2, HasDSP, UseMulOps]> {
2820*9880d681SAndroid Build Coastguard Worker    let Inst{31-27} = 0b11111;
2821*9880d681SAndroid Build Coastguard Worker    let Inst{26-23} = 0b0110;
2822*9880d681SAndroid Build Coastguard Worker    let Inst{22-20} = 0b011;
2823*9880d681SAndroid Build Coastguard Worker    let Inst{7-6} = 0b00;
2824*9880d681SAndroid Build Coastguard Worker    let Inst{5-4} = 0b01;
2825*9880d681SAndroid Build Coastguard Worker  }
2826*9880d681SAndroid Build Coastguard Worker}
2827*9880d681SAndroid Build Coastguard Worker
2828*9880d681SAndroid Build Coastguard Workerdefm t2SMUL : T2I_smul<"smul", mul>;
2829*9880d681SAndroid Build Coastguard Workerdefm t2SMLA : T2I_smla<"smla", mul>;
2830*9880d681SAndroid Build Coastguard Worker
2831*9880d681SAndroid Build Coastguard Worker// Halfword multiple accumulate long: SMLAL<x><y>
2832*9880d681SAndroid Build Coastguard Workerdef t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd),
2833*9880d681SAndroid Build Coastguard Worker         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm",
2834*9880d681SAndroid Build Coastguard Worker           [/* For disassembly only; pattern left blank */]>,
2835*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2836*9880d681SAndroid Build Coastguard Workerdef t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd),
2837*9880d681SAndroid Build Coastguard Worker         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm",
2838*9880d681SAndroid Build Coastguard Worker           [/* For disassembly only; pattern left blank */]>,
2839*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2840*9880d681SAndroid Build Coastguard Workerdef t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd),
2841*9880d681SAndroid Build Coastguard Worker         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm",
2842*9880d681SAndroid Build Coastguard Worker           [/* For disassembly only; pattern left blank */]>,
2843*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2844*9880d681SAndroid Build Coastguard Workerdef t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd),
2845*9880d681SAndroid Build Coastguard Worker         (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm",
2846*9880d681SAndroid Build Coastguard Worker           [/* For disassembly only; pattern left blank */]>,
2847*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2848*9880d681SAndroid Build Coastguard Worker
2849*9880d681SAndroid Build Coastguard Worker// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
2850*9880d681SAndroid Build Coastguard Workerdef t2SMUAD: T2ThreeReg_mac<
2851*9880d681SAndroid Build Coastguard Worker            0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2852*9880d681SAndroid Build Coastguard Worker            IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []>,
2853*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2854*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2855*9880d681SAndroid Build Coastguard Worker}
2856*9880d681SAndroid Build Coastguard Workerdef t2SMUADX:T2ThreeReg_mac<
2857*9880d681SAndroid Build Coastguard Worker            0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2858*9880d681SAndroid Build Coastguard Worker            IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []>,
2859*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2860*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2861*9880d681SAndroid Build Coastguard Worker}
2862*9880d681SAndroid Build Coastguard Workerdef t2SMUSD: T2ThreeReg_mac<
2863*9880d681SAndroid Build Coastguard Worker            0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2864*9880d681SAndroid Build Coastguard Worker            IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []>,
2865*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2866*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2867*9880d681SAndroid Build Coastguard Worker}
2868*9880d681SAndroid Build Coastguard Workerdef t2SMUSDX:T2ThreeReg_mac<
2869*9880d681SAndroid Build Coastguard Worker            0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm),
2870*9880d681SAndroid Build Coastguard Worker            IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []>,
2871*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]> {
2872*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2873*9880d681SAndroid Build Coastguard Worker}
2874*9880d681SAndroid Build Coastguard Workerdef t2SMLAD   : T2FourReg_mac<
2875*9880d681SAndroid Build Coastguard Worker            0, 0b010, 0b0000, (outs rGPR:$Rd),
2876*9880d681SAndroid Build Coastguard Worker            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad",
2877*9880d681SAndroid Build Coastguard Worker            "\t$Rd, $Rn, $Rm, $Ra", []>,
2878*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2879*9880d681SAndroid Build Coastguard Workerdef t2SMLADX  : T2FourReg_mac<
2880*9880d681SAndroid Build Coastguard Worker            0, 0b010, 0b0001, (outs rGPR:$Rd),
2881*9880d681SAndroid Build Coastguard Worker            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx",
2882*9880d681SAndroid Build Coastguard Worker            "\t$Rd, $Rn, $Rm, $Ra", []>,
2883*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2884*9880d681SAndroid Build Coastguard Workerdef t2SMLSD   : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd),
2885*9880d681SAndroid Build Coastguard Worker            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd",
2886*9880d681SAndroid Build Coastguard Worker            "\t$Rd, $Rn, $Rm, $Ra", []>,
2887*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2888*9880d681SAndroid Build Coastguard Workerdef t2SMLSDX  : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd),
2889*9880d681SAndroid Build Coastguard Worker            (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx",
2890*9880d681SAndroid Build Coastguard Worker            "\t$Rd, $Rn, $Rm, $Ra", []>,
2891*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2892*9880d681SAndroid Build Coastguard Workerdef t2SMLALD  : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2893*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, "smlald",
2894*9880d681SAndroid Build Coastguard Worker                        "\t$Ra, $Rd, $Rn, $Rm", []>,
2895*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2896*9880d681SAndroid Build Coastguard Workerdef t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2897*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaldx",
2898*9880d681SAndroid Build Coastguard Worker                        "\t$Ra, $Rd, $Rn, $Rm", []>,
2899*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2900*9880d681SAndroid Build Coastguard Workerdef t2SMLSLD  : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd),
2901*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlsld",
2902*9880d681SAndroid Build Coastguard Worker                        "\t$Ra, $Rd, $Rn, $Rm", []>,
2903*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2904*9880d681SAndroid Build Coastguard Workerdef t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd),
2905*9880d681SAndroid Build Coastguard Worker                        (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx",
2906*9880d681SAndroid Build Coastguard Worker                        "\t$Ra, $Rd, $Rn, $Rm", []>,
2907*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, HasDSP]>;
2908*9880d681SAndroid Build Coastguard Worker
2909*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2910*9880d681SAndroid Build Coastguard Worker//  Division Instructions.
2911*9880d681SAndroid Build Coastguard Worker//  Signed and unsigned division on v7-M
2912*9880d681SAndroid Build Coastguard Worker//
2913*9880d681SAndroid Build Coastguard Workerdef t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iDIV,
2914*9880d681SAndroid Build Coastguard Worker                 "sdiv", "\t$Rd, $Rn, $Rm",
2915*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>,
2916*9880d681SAndroid Build Coastguard Worker                 Requires<[HasDivide, IsThumb, HasV8MBaseline]> {
2917*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2918*9880d681SAndroid Build Coastguard Worker  let Inst{26-21} = 0b011100;
2919*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0b1;
2920*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2921*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b1111;
2922*9880d681SAndroid Build Coastguard Worker}
2923*9880d681SAndroid Build Coastguard Worker
2924*9880d681SAndroid Build Coastguard Workerdef t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iDIV,
2925*9880d681SAndroid Build Coastguard Worker                 "udiv", "\t$Rd, $Rn, $Rm",
2926*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>,
2927*9880d681SAndroid Build Coastguard Worker                 Requires<[HasDivide, IsThumb, HasV8MBaseline]> {
2928*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2929*9880d681SAndroid Build Coastguard Worker  let Inst{26-21} = 0b011101;
2930*9880d681SAndroid Build Coastguard Worker  let Inst{20} = 0b1;
2931*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2932*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b1111;
2933*9880d681SAndroid Build Coastguard Worker}
2934*9880d681SAndroid Build Coastguard Worker
2935*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2936*9880d681SAndroid Build Coastguard Worker//  Misc. Arithmetic Instructions.
2937*9880d681SAndroid Build Coastguard Worker//
2938*9880d681SAndroid Build Coastguard Worker
2939*9880d681SAndroid Build Coastguard Workerclass T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
2940*9880d681SAndroid Build Coastguard Worker      InstrItinClass itin, string opc, string asm, list<dag> pattern>
2941*9880d681SAndroid Build Coastguard Worker  : T2ThreeReg<oops, iops, itin, opc, asm, pattern> {
2942*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
2943*9880d681SAndroid Build Coastguard Worker  let Inst{26-22} = 0b01010;
2944*9880d681SAndroid Build Coastguard Worker  let Inst{21-20} = op1;
2945*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
2946*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = 0b10;
2947*9880d681SAndroid Build Coastguard Worker  let Inst{5-4} = op2;
2948*9880d681SAndroid Build Coastguard Worker  let Rn{3-0} = Rm;
2949*9880d681SAndroid Build Coastguard Worker}
2950*9880d681SAndroid Build Coastguard Worker
2951*9880d681SAndroid Build Coastguard Workerdef t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2952*9880d681SAndroid Build Coastguard Worker                    "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>,
2953*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteALU]>;
2954*9880d681SAndroid Build Coastguard Worker
2955*9880d681SAndroid Build Coastguard Workerdef t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2956*9880d681SAndroid Build Coastguard Worker                      "rbit", "\t$Rd, $Rm",
2957*9880d681SAndroid Build Coastguard Worker                      [(set rGPR:$Rd, (bitreverse rGPR:$Rm))]>,
2958*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteALU]>;
2959*9880d681SAndroid Build Coastguard Worker
2960*9880d681SAndroid Build Coastguard Workerdef t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2961*9880d681SAndroid Build Coastguard Worker                 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>,
2962*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU]>;
2963*9880d681SAndroid Build Coastguard Worker
2964*9880d681SAndroid Build Coastguard Workerdef t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2965*9880d681SAndroid Build Coastguard Worker                       "rev16", ".w\t$Rd, $Rm",
2966*9880d681SAndroid Build Coastguard Worker                [(set rGPR:$Rd, (rotr (bswap rGPR:$Rm), (i32 16)))]>,
2967*9880d681SAndroid Build Coastguard Worker                Sched<[WriteALU]>;
2968*9880d681SAndroid Build Coastguard Worker
2969*9880d681SAndroid Build Coastguard Workerdef t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr,
2970*9880d681SAndroid Build Coastguard Worker                       "revsh", ".w\t$Rd, $Rm",
2971*9880d681SAndroid Build Coastguard Worker                 [(set rGPR:$Rd, (sra (bswap rGPR:$Rm), (i32 16)))]>,
2972*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteALU]>;
2973*9880d681SAndroid Build Coastguard Worker
2974*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (sra (shl rGPR:$Rm, (i32 24)), (i32 16)),
2975*9880d681SAndroid Build Coastguard Worker                (and (srl rGPR:$Rm, (i32 8)), 0xFF)),
2976*9880d681SAndroid Build Coastguard Worker            (t2REVSH rGPR:$Rm)>;
2977*9880d681SAndroid Build Coastguard Worker
2978*9880d681SAndroid Build Coastguard Workerdef t2PKHBT : T2ThreeReg<
2979*9880d681SAndroid Build Coastguard Worker            (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_lsl_amt:$sh),
2980*9880d681SAndroid Build Coastguard Worker                  IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
2981*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
2982*9880d681SAndroid Build Coastguard Worker                                      (and (shl rGPR:$Rm, pkh_lsl_amt:$sh),
2983*9880d681SAndroid Build Coastguard Worker                                           0xFFFF0000)))]>,
2984*9880d681SAndroid Build Coastguard Worker                  Requires<[HasT2ExtractPack, IsThumb2]>,
2985*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteALUsi, ReadALU]> {
2986*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
2987*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
2988*9880d681SAndroid Build Coastguard Worker  let Inst{24-20} = 0b01100;
2989*9880d681SAndroid Build Coastguard Worker  let Inst{5} = 0; // BT form
2990*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 0;
2991*9880d681SAndroid Build Coastguard Worker
2992*9880d681SAndroid Build Coastguard Worker  bits<5> sh;
2993*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = sh{4-2};
2994*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = sh{1-0};
2995*9880d681SAndroid Build Coastguard Worker}
2996*9880d681SAndroid Build Coastguard Worker
2997*9880d681SAndroid Build Coastguard Worker// Alternate cases for PKHBT where identities eliminate some nodes.
2998*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
2999*9880d681SAndroid Build Coastguard Worker            (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
3000*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
3001*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
3002*9880d681SAndroid Build Coastguard Worker            (t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
3003*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
3004*9880d681SAndroid Build Coastguard Worker
3005*9880d681SAndroid Build Coastguard Worker// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
3006*9880d681SAndroid Build Coastguard Worker// will match the pattern below.
3007*9880d681SAndroid Build Coastguard Workerdef t2PKHTB : T2ThreeReg<
3008*9880d681SAndroid Build Coastguard Worker                  (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_asr_amt:$sh),
3009*9880d681SAndroid Build Coastguard Worker                  IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
3010*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
3011*9880d681SAndroid Build Coastguard Worker                                       (and (sra rGPR:$Rm, pkh_asr_amt:$sh),
3012*9880d681SAndroid Build Coastguard Worker                                            0xFFFF)))]>,
3013*9880d681SAndroid Build Coastguard Worker                  Requires<[HasT2ExtractPack, IsThumb2]>,
3014*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteALUsi, ReadALU]> {
3015*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3016*9880d681SAndroid Build Coastguard Worker  let Inst{26-25} = 0b01;
3017*9880d681SAndroid Build Coastguard Worker  let Inst{24-20} = 0b01100;
3018*9880d681SAndroid Build Coastguard Worker  let Inst{5} = 1; // TB form
3019*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 0;
3020*9880d681SAndroid Build Coastguard Worker
3021*9880d681SAndroid Build Coastguard Worker  bits<5> sh;
3022*9880d681SAndroid Build Coastguard Worker  let Inst{14-12} = sh{4-2};
3023*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = sh{1-0};
3024*9880d681SAndroid Build Coastguard Worker}
3025*9880d681SAndroid Build Coastguard Worker
3026*9880d681SAndroid Build Coastguard Worker// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
3027*9880d681SAndroid Build Coastguard Worker// a shift amount of 0 is *not legal* here, it is PKHBT instead.
3028*9880d681SAndroid Build Coastguard Worker// We also can not replace a srl (17..31) by an arithmetic shift we would use in
3029*9880d681SAndroid Build Coastguard Worker// pkhtb src1, src2, asr (17..31).
3030*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16:$sh)),
3031*9880d681SAndroid Build Coastguard Worker            (t2PKHTB rGPR:$src1, rGPR:$src2, imm16:$sh)>,
3032*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
3033*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (sra rGPR:$src2, imm16_31:$sh)),
3034*9880d681SAndroid Build Coastguard Worker            (t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
3035*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
3036*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
3037*9880d681SAndroid Build Coastguard Worker                (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
3038*9880d681SAndroid Build Coastguard Worker            (t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$sh)>,
3039*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
3040*9880d681SAndroid Build Coastguard Worker
3041*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3042*9880d681SAndroid Build Coastguard Worker// CRC32 Instructions
3043*9880d681SAndroid Build Coastguard Worker//
3044*9880d681SAndroid Build Coastguard Worker// Polynomials:
3045*9880d681SAndroid Build Coastguard Worker// + CRC32{B,H,W}       0x04C11DB7
3046*9880d681SAndroid Build Coastguard Worker// + CRC32C{B,H,W}      0x1EDC6F41
3047*9880d681SAndroid Build Coastguard Worker//
3048*9880d681SAndroid Build Coastguard Worker
3049*9880d681SAndroid Build Coastguard Workerclass T2I_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin>
3050*9880d681SAndroid Build Coastguard Worker  : T2ThreeRegNoP<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), NoItinerary,
3051*9880d681SAndroid Build Coastguard Worker               !strconcat("crc32", suffix, "\t$Rd, $Rn, $Rm"),
3052*9880d681SAndroid Build Coastguard Worker               [(set rGPR:$Rd, (builtin rGPR:$Rn, rGPR:$Rm))]>,
3053*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb2, HasV8, HasCRC]> {
3054*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11111;
3055*9880d681SAndroid Build Coastguard Worker  let Inst{26-21} = 0b010110;
3056*9880d681SAndroid Build Coastguard Worker  let Inst{20}    = C;
3057*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
3058*9880d681SAndroid Build Coastguard Worker  let Inst{7-6}   = 0b10;
3059*9880d681SAndroid Build Coastguard Worker  let Inst{5-4}   = sz;
3060*9880d681SAndroid Build Coastguard Worker}
3061*9880d681SAndroid Build Coastguard Worker
3062*9880d681SAndroid Build Coastguard Workerdef t2CRC32B  : T2I_crc32<0, 0b00, "b", int_arm_crc32b>;
3063*9880d681SAndroid Build Coastguard Workerdef t2CRC32CB : T2I_crc32<1, 0b00, "cb", int_arm_crc32cb>;
3064*9880d681SAndroid Build Coastguard Workerdef t2CRC32H  : T2I_crc32<0, 0b01, "h", int_arm_crc32h>;
3065*9880d681SAndroid Build Coastguard Workerdef t2CRC32CH : T2I_crc32<1, 0b01, "ch", int_arm_crc32ch>;
3066*9880d681SAndroid Build Coastguard Workerdef t2CRC32W  : T2I_crc32<0, 0b10, "w", int_arm_crc32w>;
3067*9880d681SAndroid Build Coastguard Workerdef t2CRC32CW : T2I_crc32<1, 0b10, "cw", int_arm_crc32cw>;
3068*9880d681SAndroid Build Coastguard Worker
3069*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3070*9880d681SAndroid Build Coastguard Worker//  Comparison Instructions...
3071*9880d681SAndroid Build Coastguard Worker//
3072*9880d681SAndroid Build Coastguard Workerdefm t2CMP  : T2I_cmp_irs<0b1101, "cmp",
3073*9880d681SAndroid Build Coastguard Worker                          IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, ARMcmp>;
3074*9880d681SAndroid Build Coastguard Worker
3075*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMcmpZ  GPRnopc:$lhs, t2_so_imm:$imm),
3076*9880d681SAndroid Build Coastguard Worker            (t2CMPri  GPRnopc:$lhs, t2_so_imm:$imm)>;
3077*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMcmpZ  GPRnopc:$lhs, rGPR:$rhs),
3078*9880d681SAndroid Build Coastguard Worker            (t2CMPrr  GPRnopc:$lhs, rGPR:$rhs)>;
3079*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMcmpZ  GPRnopc:$lhs, t2_so_reg:$rhs),
3080*9880d681SAndroid Build Coastguard Worker            (t2CMPrs  GPRnopc:$lhs, t2_so_reg:$rhs)>;
3081*9880d681SAndroid Build Coastguard Worker
3082*9880d681SAndroid Build Coastguard Workerlet isCompare = 1, Defs = [CPSR] in {
3083*9880d681SAndroid Build Coastguard Worker   // shifted imm
3084*9880d681SAndroid Build Coastguard Worker   def t2CMNri : T2OneRegCmpImm<
3085*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iCMPi,
3086*9880d681SAndroid Build Coastguard Worker                "cmn", ".w\t$Rn, $imm",
3087*9880d681SAndroid Build Coastguard Worker                [(ARMcmn GPRnopc:$Rn, (ineg t2_so_imm:$imm))]>,
3088*9880d681SAndroid Build Coastguard Worker                Sched<[WriteCMP, ReadALU]> {
3089*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11110;
3090*9880d681SAndroid Build Coastguard Worker     let Inst{25} = 0;
3091*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = 0b1000;
3092*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
3093*9880d681SAndroid Build Coastguard Worker     let Inst{15} = 0;
3094*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
3095*9880d681SAndroid Build Coastguard Worker   }
3096*9880d681SAndroid Build Coastguard Worker   // register
3097*9880d681SAndroid Build Coastguard Worker   def t2CMNzrr : T2TwoRegCmp<
3098*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, rGPR:$Rm), IIC_iCMPr,
3099*9880d681SAndroid Build Coastguard Worker                "cmn", ".w\t$Rn, $Rm",
3100*9880d681SAndroid Build Coastguard Worker                [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3101*9880d681SAndroid Build Coastguard Worker                  GPRnopc:$Rn, rGPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> {
3102*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
3103*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
3104*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = 0b1000;
3105*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
3106*9880d681SAndroid Build Coastguard Worker     let Inst{14-12} = 0b000; // imm3
3107*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
3108*9880d681SAndroid Build Coastguard Worker     let Inst{7-6} = 0b00; // imm2
3109*9880d681SAndroid Build Coastguard Worker     let Inst{5-4} = 0b00; // type
3110*9880d681SAndroid Build Coastguard Worker   }
3111*9880d681SAndroid Build Coastguard Worker   // shifted register
3112*9880d681SAndroid Build Coastguard Worker   def t2CMNzrs : T2OneRegCmpShiftedReg<
3113*9880d681SAndroid Build Coastguard Worker                (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), IIC_iCMPsi,
3114*9880d681SAndroid Build Coastguard Worker                "cmn", ".w\t$Rn, $ShiftedRm",
3115*9880d681SAndroid Build Coastguard Worker                [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
3116*9880d681SAndroid Build Coastguard Worker                  GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]>,
3117*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteCMPsi, ReadALU, ReadALU]> {
3118*9880d681SAndroid Build Coastguard Worker     let Inst{31-27} = 0b11101;
3119*9880d681SAndroid Build Coastguard Worker     let Inst{26-25} = 0b01;
3120*9880d681SAndroid Build Coastguard Worker     let Inst{24-21} = 0b1000;
3121*9880d681SAndroid Build Coastguard Worker     let Inst{20} = 1; // The S bit.
3122*9880d681SAndroid Build Coastguard Worker     let Inst{11-8} = 0b1111; // Rd
3123*9880d681SAndroid Build Coastguard Worker   }
3124*9880d681SAndroid Build Coastguard Worker}
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Worker// Assembler aliases w/o the ".w" suffix.
3127*9880d681SAndroid Build Coastguard Worker// No alias here for 'rr' version as not all instantiations of this multiclass
3128*9880d681SAndroid Build Coastguard Worker// want one (CMP in particular, does not).
3129*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cmn${p} $Rn, $imm",
3130*9880d681SAndroid Build Coastguard Worker   (t2CMNri GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>;
3131*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cmn${p} $Rn, $shift",
3132*9880d681SAndroid Build Coastguard Worker   (t2CMNzrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>;
3133*9880d681SAndroid Build Coastguard Worker
3134*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMcmp  GPR:$src, t2_so_imm_neg:$imm),
3135*9880d681SAndroid Build Coastguard Worker            (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
3136*9880d681SAndroid Build Coastguard Worker
3137*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMcmpZ GPRnopc:$src, t2_so_imm_neg:$imm),
3138*9880d681SAndroid Build Coastguard Worker            (t2CMNri GPRnopc:$src, t2_so_imm_neg:$imm)>;
3139*9880d681SAndroid Build Coastguard Worker
3140*9880d681SAndroid Build Coastguard Workerdefm t2TST  : T2I_cmp_irs<0b0000, "tst",
3141*9880d681SAndroid Build Coastguard Worker                          IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
3142*9880d681SAndroid Build Coastguard Worker                         BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
3143*9880d681SAndroid Build Coastguard Workerdefm t2TEQ  : T2I_cmp_irs<0b0100, "teq",
3144*9880d681SAndroid Build Coastguard Worker                          IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
3145*9880d681SAndroid Build Coastguard Worker                         BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>;
3146*9880d681SAndroid Build Coastguard Worker
3147*9880d681SAndroid Build Coastguard Worker// Conditional moves
3148*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in {
3149*9880d681SAndroid Build Coastguard Worker
3150*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1, isSelect = 1 in
3151*9880d681SAndroid Build Coastguard Workerdef t2MOVCCr : t2PseudoInst<(outs rGPR:$Rd),
3152*9880d681SAndroid Build Coastguard Worker                            (ins rGPR:$false, rGPR:$Rm, cmovpred:$p),
3153*9880d681SAndroid Build Coastguard Worker                            4, IIC_iCMOVr,
3154*9880d681SAndroid Build Coastguard Worker                            [(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm,
3155*9880d681SAndroid Build Coastguard Worker                                                     cmovpred:$p))]>,
3156*9880d681SAndroid Build Coastguard Worker               RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
3157*9880d681SAndroid Build Coastguard Worker
3158*9880d681SAndroid Build Coastguard Workerlet isMoveImm = 1 in
3159*9880d681SAndroid Build Coastguard Workerdef t2MOVCCi
3160*9880d681SAndroid Build Coastguard Worker    : t2PseudoInst<(outs rGPR:$Rd),
3161*9880d681SAndroid Build Coastguard Worker                   (ins rGPR:$false, t2_so_imm:$imm, cmovpred:$p),
3162*9880d681SAndroid Build Coastguard Worker                   4, IIC_iCMOVi,
3163*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, (ARMcmov rGPR:$false,t2_so_imm:$imm,
3164*9880d681SAndroid Build Coastguard Worker                                            cmovpred:$p))]>,
3165*9880d681SAndroid Build Coastguard Worker      RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
3166*9880d681SAndroid Build Coastguard Worker
3167*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
3168*9880d681SAndroid Build Coastguard Workerlet isMoveImm = 1 in
3169*9880d681SAndroid Build Coastguard Workerdef t2MOVCCi16
3170*9880d681SAndroid Build Coastguard Worker    : t2PseudoInst<(outs rGPR:$Rd),
3171*9880d681SAndroid Build Coastguard Worker                   (ins  rGPR:$false, imm0_65535_expr:$imm, cmovpred:$p),
3172*9880d681SAndroid Build Coastguard Worker                   4, IIC_iCMOVi,
3173*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, (ARMcmov rGPR:$false, imm0_65535:$imm,
3174*9880d681SAndroid Build Coastguard Worker                                            cmovpred:$p))]>,
3175*9880d681SAndroid Build Coastguard Worker      RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
3176*9880d681SAndroid Build Coastguard Worker
3177*9880d681SAndroid Build Coastguard Workerlet isMoveImm = 1 in
3178*9880d681SAndroid Build Coastguard Workerdef t2MVNCCi
3179*9880d681SAndroid Build Coastguard Worker    : t2PseudoInst<(outs rGPR:$Rd),
3180*9880d681SAndroid Build Coastguard Worker                   (ins rGPR:$false, t2_so_imm:$imm, cmovpred:$p),
3181*9880d681SAndroid Build Coastguard Worker                   4, IIC_iCMOVi,
3182*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd,
3183*9880d681SAndroid Build Coastguard Worker                         (ARMcmov rGPR:$false, t2_so_imm_not:$imm,
3184*9880d681SAndroid Build Coastguard Worker                                  cmovpred:$p))]>,
3185*9880d681SAndroid Build Coastguard Worker      RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
3186*9880d681SAndroid Build Coastguard Worker
3187*9880d681SAndroid Build Coastguard Workerclass MOVCCShPseudo<SDPatternOperator opnode, Operand ty>
3188*9880d681SAndroid Build Coastguard Worker    : t2PseudoInst<(outs rGPR:$Rd),
3189*9880d681SAndroid Build Coastguard Worker                   (ins rGPR:$false, rGPR:$Rm, i32imm:$imm, cmovpred:$p),
3190*9880d681SAndroid Build Coastguard Worker                   4, IIC_iCMOVsi,
3191*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$Rd, (ARMcmov rGPR:$false,
3192*9880d681SAndroid Build Coastguard Worker                                            (opnode rGPR:$Rm, (i32 ty:$imm)),
3193*9880d681SAndroid Build Coastguard Worker                                            cmovpred:$p))]>,
3194*9880d681SAndroid Build Coastguard Worker      RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
3195*9880d681SAndroid Build Coastguard Worker
3196*9880d681SAndroid Build Coastguard Workerdef t2MOVCClsl : MOVCCShPseudo<shl,  imm0_31>;
3197*9880d681SAndroid Build Coastguard Workerdef t2MOVCClsr : MOVCCShPseudo<srl,  imm_sr>;
3198*9880d681SAndroid Build Coastguard Workerdef t2MOVCCasr : MOVCCShPseudo<sra,  imm_sr>;
3199*9880d681SAndroid Build Coastguard Workerdef t2MOVCCror : MOVCCShPseudo<rotr, imm0_31>;
3200*9880d681SAndroid Build Coastguard Worker
3201*9880d681SAndroid Build Coastguard Workerlet isMoveImm = 1 in
3202*9880d681SAndroid Build Coastguard Workerdef t2MOVCCi32imm
3203*9880d681SAndroid Build Coastguard Worker    : t2PseudoInst<(outs rGPR:$dst),
3204*9880d681SAndroid Build Coastguard Worker                   (ins rGPR:$false, i32imm:$src, cmovpred:$p),
3205*9880d681SAndroid Build Coastguard Worker                   8, IIC_iCMOVix2,
3206*9880d681SAndroid Build Coastguard Worker                   [(set rGPR:$dst, (ARMcmov rGPR:$false, imm:$src,
3207*9880d681SAndroid Build Coastguard Worker                                             cmovpred:$p))]>,
3208*9880d681SAndroid Build Coastguard Worker      RegConstraint<"$false = $dst">;
3209*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly = 1
3210*9880d681SAndroid Build Coastguard Worker
3211*9880d681SAndroid Build Coastguard Worker} // hasSideEffects
3212*9880d681SAndroid Build Coastguard Worker
3213*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3214*9880d681SAndroid Build Coastguard Worker// Atomic operations intrinsics
3215*9880d681SAndroid Build Coastguard Worker//
3216*9880d681SAndroid Build Coastguard Worker
3217*9880d681SAndroid Build Coastguard Worker// memory barriers protect the atomic sequences
3218*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1 in {
3219*9880d681SAndroid Build Coastguard Workerdef t2DMB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
3220*9880d681SAndroid Build Coastguard Worker                "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
3221*9880d681SAndroid Build Coastguard Worker                Requires<[IsThumb, HasDB]> {
3222*9880d681SAndroid Build Coastguard Worker  bits<4> opt;
3223*9880d681SAndroid Build Coastguard Worker  let Inst{31-4} = 0xf3bf8f5;
3224*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = opt;
3225*9880d681SAndroid Build Coastguard Worker}
3226*9880d681SAndroid Build Coastguard Worker
3227*9880d681SAndroid Build Coastguard Workerdef t2DSB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
3228*9880d681SAndroid Build Coastguard Worker                "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
3229*9880d681SAndroid Build Coastguard Worker                Requires<[IsThumb, HasDB]> {
3230*9880d681SAndroid Build Coastguard Worker  bits<4> opt;
3231*9880d681SAndroid Build Coastguard Worker  let Inst{31-4} = 0xf3bf8f4;
3232*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = opt;
3233*9880d681SAndroid Build Coastguard Worker}
3234*9880d681SAndroid Build Coastguard Worker
3235*9880d681SAndroid Build Coastguard Workerdef t2ISB : T2I<(outs), (ins instsyncb_opt:$opt), NoItinerary,
3236*9880d681SAndroid Build Coastguard Worker                "isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>,
3237*9880d681SAndroid Build Coastguard Worker                Requires<[IsThumb, HasDB]> {
3238*9880d681SAndroid Build Coastguard Worker  bits<4> opt;
3239*9880d681SAndroid Build Coastguard Worker  let Inst{31-4} = 0xf3bf8f6;
3240*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = opt;
3241*9880d681SAndroid Build Coastguard Worker}
3242*9880d681SAndroid Build Coastguard Worker}
3243*9880d681SAndroid Build Coastguard Worker
3244*9880d681SAndroid Build Coastguard Workerclass T2I_ldrex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz,
3245*9880d681SAndroid Build Coastguard Worker                InstrItinClass itin, string opc, string asm, string cstr,
3246*9880d681SAndroid Build Coastguard Worker                list<dag> pattern, bits<4> rt2 = 0b1111>
3247*9880d681SAndroid Build Coastguard Worker  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
3248*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3249*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0001101;
3250*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = rt2;
3251*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = opcod;
3252*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b1111;
3253*9880d681SAndroid Build Coastguard Worker
3254*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
3255*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3256*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
3257*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3258*9880d681SAndroid Build Coastguard Worker}
3259*9880d681SAndroid Build Coastguard Workerclass T2I_strex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz,
3260*9880d681SAndroid Build Coastguard Worker                InstrItinClass itin, string opc, string asm, string cstr,
3261*9880d681SAndroid Build Coastguard Worker                list<dag> pattern, bits<4> rt2 = 0b1111>
3262*9880d681SAndroid Build Coastguard Worker  : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
3263*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3264*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0001100;
3265*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = rt2;
3266*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = opcod;
3267*9880d681SAndroid Build Coastguard Worker
3268*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
3269*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
3270*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3271*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}  = Rd;
3272*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
3273*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3274*9880d681SAndroid Build Coastguard Worker}
3275*9880d681SAndroid Build Coastguard Worker
3276*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in {
3277*9880d681SAndroid Build Coastguard Workerdef t2LDREXB : T2I_ldrex<0b0100, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
3278*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3279*9880d681SAndroid Build Coastguard Worker                         "ldrexb", "\t$Rt, $addr", "",
3280*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>,
3281*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]>;
3282*9880d681SAndroid Build Coastguard Workerdef t2LDREXH : T2I_ldrex<0b0101, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
3283*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3284*9880d681SAndroid Build Coastguard Worker                         "ldrexh", "\t$Rt, $addr", "",
3285*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>,
3286*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]>;
3287*9880d681SAndroid Build Coastguard Workerdef t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr),
3288*9880d681SAndroid Build Coastguard Worker                       AddrModeNone, 4, NoItinerary,
3289*9880d681SAndroid Build Coastguard Worker                       "ldrex", "\t$Rt, $addr", "",
3290*9880d681SAndroid Build Coastguard Worker                     [(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]>,
3291*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]> {
3292*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3293*9880d681SAndroid Build Coastguard Worker  bits<12> addr;
3294*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3295*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0000101;
3296*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr{11-8};
3297*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3298*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = 0b1111;
3299*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = addr{7-0};
3300*9880d681SAndroid Build Coastguard Worker}
3301*9880d681SAndroid Build Coastguard Workerlet hasExtraDefRegAllocReq = 1 in
3302*9880d681SAndroid Build Coastguard Workerdef t2LDREXD : T2I_ldrex<0b0111, (outs rGPR:$Rt, rGPR:$Rt2),
3303*9880d681SAndroid Build Coastguard Worker                         (ins addr_offset_none:$addr),
3304*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3305*9880d681SAndroid Build Coastguard Worker                         "ldrexd", "\t$Rt, $Rt2, $addr", "",
3306*9880d681SAndroid Build Coastguard Worker                         [], {?, ?, ?, ?}>,
3307*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb2, IsNotMClass]> {
3308*9880d681SAndroid Build Coastguard Worker  bits<4> Rt2;
3309*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt2;
3310*9880d681SAndroid Build Coastguard Worker}
3311*9880d681SAndroid Build Coastguard Workerdef t2LDAEXB : T2I_ldrex<0b1100, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
3312*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3313*9880d681SAndroid Build Coastguard Worker                         "ldaexb", "\t$Rt, $addr", "",
3314*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rt, (ldaex_1 addr_offset_none:$addr))]>,
3315*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3316*9880d681SAndroid Build Coastguard Workerdef t2LDAEXH : T2I_ldrex<0b1101, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
3317*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3318*9880d681SAndroid Build Coastguard Worker                         "ldaexh", "\t$Rt, $addr", "",
3319*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rt, (ldaex_2 addr_offset_none:$addr))]>,
3320*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3321*9880d681SAndroid Build Coastguard Workerdef t2LDAEX  : Thumb2I<(outs rGPR:$Rt), (ins addr_offset_none:$addr),
3322*9880d681SAndroid Build Coastguard Worker                       AddrModeNone, 4, NoItinerary,
3323*9880d681SAndroid Build Coastguard Worker                       "ldaex", "\t$Rt, $addr", "",
3324*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rt, (ldaex_4 addr_offset_none:$addr))]>,
3325*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]> {
3326*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3327*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
3328*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3329*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0001101;
3330*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
3331*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3332*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = 0b1111;
3333*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = 0b11101111;
3334*9880d681SAndroid Build Coastguard Worker}
3335*9880d681SAndroid Build Coastguard Workerlet hasExtraDefRegAllocReq = 1 in
3336*9880d681SAndroid Build Coastguard Workerdef t2LDAEXD : T2I_ldrex<0b1111, (outs rGPR:$Rt, rGPR:$Rt2),
3337*9880d681SAndroid Build Coastguard Worker                         (ins addr_offset_none:$addr),
3338*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3339*9880d681SAndroid Build Coastguard Worker                         "ldaexd", "\t$Rt, $Rt2, $addr", "",
3340*9880d681SAndroid Build Coastguard Worker                         [], {?, ?, ?, ?}>, Requires<[IsThumb,
3341*9880d681SAndroid Build Coastguard Worker                         HasAcquireRelease, HasV7Clrex, IsNotMClass]> {
3342*9880d681SAndroid Build Coastguard Worker  bits<4> Rt2;
3343*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt2;
3344*9880d681SAndroid Build Coastguard Worker
3345*9880d681SAndroid Build Coastguard Worker  let Inst{7} = 1;
3346*9880d681SAndroid Build Coastguard Worker}
3347*9880d681SAndroid Build Coastguard Worker}
3348*9880d681SAndroid Build Coastguard Worker
3349*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, Constraints = "@earlyclobber $Rd" in {
3350*9880d681SAndroid Build Coastguard Workerdef t2STREXB : T2I_strex<0b0100, (outs rGPR:$Rd),
3351*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, addr_offset_none:$addr),
3352*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3353*9880d681SAndroid Build Coastguard Worker                         "strexb", "\t$Rd, $Rt, $addr", "",
3354*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd,
3355*9880d681SAndroid Build Coastguard Worker                               (strex_1 rGPR:$Rt, addr_offset_none:$addr))]>,
3356*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]>;
3357*9880d681SAndroid Build Coastguard Workerdef t2STREXH : T2I_strex<0b0101, (outs rGPR:$Rd),
3358*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, addr_offset_none:$addr),
3359*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3360*9880d681SAndroid Build Coastguard Worker                         "strexh", "\t$Rd, $Rt, $addr", "",
3361*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd,
3362*9880d681SAndroid Build Coastguard Worker                               (strex_2 rGPR:$Rt, addr_offset_none:$addr))]>,
3363*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]>;
3364*9880d681SAndroid Build Coastguard Worker
3365*9880d681SAndroid Build Coastguard Workerdef t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt,
3366*9880d681SAndroid Build Coastguard Worker                             t2addrmode_imm0_1020s4:$addr),
3367*9880d681SAndroid Build Coastguard Worker                  AddrModeNone, 4, NoItinerary,
3368*9880d681SAndroid Build Coastguard Worker                  "strex", "\t$Rd, $Rt, $addr", "",
3369*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd,
3370*9880d681SAndroid Build Coastguard Worker                        (strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]>,
3371*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb, HasV8MBaseline]> {
3372*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
3373*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3374*9880d681SAndroid Build Coastguard Worker  bits<12> addr;
3375*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3376*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0000100;
3377*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr{11-8};
3378*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3379*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = Rd;
3380*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = addr{7-0};
3381*9880d681SAndroid Build Coastguard Worker}
3382*9880d681SAndroid Build Coastguard Workerlet hasExtraSrcRegAllocReq = 1 in
3383*9880d681SAndroid Build Coastguard Workerdef t2STREXD : T2I_strex<0b0111, (outs rGPR:$Rd),
3384*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr),
3385*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3386*9880d681SAndroid Build Coastguard Worker                         "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
3387*9880d681SAndroid Build Coastguard Worker                         {?, ?, ?, ?}>,
3388*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb2, IsNotMClass]> {
3389*9880d681SAndroid Build Coastguard Worker  bits<4> Rt2;
3390*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt2;
3391*9880d681SAndroid Build Coastguard Worker}
3392*9880d681SAndroid Build Coastguard Workerdef t2STLEXB : T2I_strex<0b1100, (outs rGPR:$Rd),
3393*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, addr_offset_none:$addr),
3394*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3395*9880d681SAndroid Build Coastguard Worker                         "stlexb", "\t$Rd, $Rt, $addr", "",
3396*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd,
3397*9880d681SAndroid Build Coastguard Worker                               (stlex_1 rGPR:$Rt, addr_offset_none:$addr))]>,
3398*9880d681SAndroid Build Coastguard Worker                         Requires<[IsThumb, HasAcquireRelease,
3399*9880d681SAndroid Build Coastguard Worker                                   HasV7Clrex]>;
3400*9880d681SAndroid Build Coastguard Worker
3401*9880d681SAndroid Build Coastguard Workerdef t2STLEXH : T2I_strex<0b1101, (outs rGPR:$Rd),
3402*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, addr_offset_none:$addr),
3403*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3404*9880d681SAndroid Build Coastguard Worker                         "stlexh", "\t$Rd, $Rt, $addr", "",
3405*9880d681SAndroid Build Coastguard Worker                         [(set rGPR:$Rd,
3406*9880d681SAndroid Build Coastguard Worker                               (stlex_2 rGPR:$Rt, addr_offset_none:$addr))]>,
3407*9880d681SAndroid Build Coastguard Worker                         Requires<[IsThumb, HasAcquireRelease,
3408*9880d681SAndroid Build Coastguard Worker                                   HasV7Clrex]>;
3409*9880d681SAndroid Build Coastguard Worker
3410*9880d681SAndroid Build Coastguard Workerdef t2STLEX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt,
3411*9880d681SAndroid Build Coastguard Worker                             addr_offset_none:$addr),
3412*9880d681SAndroid Build Coastguard Worker                  AddrModeNone, 4, NoItinerary,
3413*9880d681SAndroid Build Coastguard Worker                  "stlex", "\t$Rd, $Rt, $addr", "",
3414*9880d681SAndroid Build Coastguard Worker                  [(set rGPR:$Rd,
3415*9880d681SAndroid Build Coastguard Worker                        (stlex_4 rGPR:$Rt, addr_offset_none:$addr))]>,
3416*9880d681SAndroid Build Coastguard Worker                  Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]> {
3417*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
3418*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
3419*9880d681SAndroid Build Coastguard Worker  bits<4> addr;
3420*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11101;
3421*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b0001100;
3422*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = addr;
3423*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
3424*9880d681SAndroid Build Coastguard Worker  let Inst{11-4}  = 0b11111110;
3425*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = Rd;
3426*9880d681SAndroid Build Coastguard Worker}
3427*9880d681SAndroid Build Coastguard Workerlet hasExtraSrcRegAllocReq = 1 in
3428*9880d681SAndroid Build Coastguard Workerdef t2STLEXD : T2I_strex<0b1111, (outs rGPR:$Rd),
3429*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr),
3430*9880d681SAndroid Build Coastguard Worker                         AddrModeNone, 4, NoItinerary,
3431*9880d681SAndroid Build Coastguard Worker                         "stlexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
3432*9880d681SAndroid Build Coastguard Worker                         {?, ?, ?, ?}>, Requires<[IsThumb, HasAcquireRelease,
3433*9880d681SAndroid Build Coastguard Worker                         HasV7Clrex, IsNotMClass]> {
3434*9880d681SAndroid Build Coastguard Worker  bits<4> Rt2;
3435*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt2;
3436*9880d681SAndroid Build Coastguard Worker}
3437*9880d681SAndroid Build Coastguard Worker}
3438*9880d681SAndroid Build Coastguard Worker
3439*9880d681SAndroid Build Coastguard Workerdef t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", [(int_arm_clrex)]>,
3440*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasV7Clrex]>  {
3441*9880d681SAndroid Build Coastguard Worker  let Inst{31-16} = 0xf3bf;
3442*9880d681SAndroid Build Coastguard Worker  let Inst{15-14} = 0b10;
3443*9880d681SAndroid Build Coastguard Worker  let Inst{13} = 0;
3444*9880d681SAndroid Build Coastguard Worker  let Inst{12} = 0;
3445*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = 0b1111;
3446*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b0010;
3447*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b1111;
3448*9880d681SAndroid Build Coastguard Worker}
3449*9880d681SAndroid Build Coastguard Worker
3450*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and (ldrex_1 addr_offset_none:$addr), 0xff),
3451*9880d681SAndroid Build Coastguard Worker            (t2LDREXB addr_offset_none:$addr)>,
3452*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasV8MBaseline]>;
3453*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and (ldrex_2 addr_offset_none:$addr), 0xffff),
3454*9880d681SAndroid Build Coastguard Worker            (t2LDREXH addr_offset_none:$addr)>,
3455*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasV8MBaseline]>;
3456*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr),
3457*9880d681SAndroid Build Coastguard Worker            (t2STREXB GPR:$Rt, addr_offset_none:$addr)>,
3458*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasV8MBaseline]>;
3459*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
3460*9880d681SAndroid Build Coastguard Worker            (t2STREXH GPR:$Rt, addr_offset_none:$addr)>,
3461*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasV8MBaseline]>;
3462*9880d681SAndroid Build Coastguard Worker
3463*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and (ldaex_1 addr_offset_none:$addr), 0xff),
3464*9880d681SAndroid Build Coastguard Worker            (t2LDAEXB addr_offset_none:$addr)>,
3465*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3466*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and (ldaex_2 addr_offset_none:$addr), 0xffff),
3467*9880d681SAndroid Build Coastguard Worker            (t2LDAEXH addr_offset_none:$addr)>,
3468*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3469*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(stlex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr),
3470*9880d681SAndroid Build Coastguard Worker            (t2STLEXB GPR:$Rt, addr_offset_none:$addr)>,
3471*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3472*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
3473*9880d681SAndroid Build Coastguard Worker            (t2STLEXH GPR:$Rt, addr_offset_none:$addr)>,
3474*9880d681SAndroid Build Coastguard Worker            Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>;
3475*9880d681SAndroid Build Coastguard Worker
3476*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3477*9880d681SAndroid Build Coastguard Worker// SJLJ Exception handling intrinsics
3478*9880d681SAndroid Build Coastguard Worker//   eh_sjlj_setjmp() is an instruction sequence to store the return
3479*9880d681SAndroid Build Coastguard Worker//   address and save #0 in R0 for the non-longjmp case.
3480*9880d681SAndroid Build Coastguard Worker//   Since by its nature we may be coming from some other function to get
3481*9880d681SAndroid Build Coastguard Worker//   here, and we're using the stack frame for the containing function to
3482*9880d681SAndroid Build Coastguard Worker//   save/restore registers, we can't keep anything live in regs across
3483*9880d681SAndroid Build Coastguard Worker//   the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
3484*9880d681SAndroid Build Coastguard Worker//   when we get here from a longjmp(). We force everything out of registers
3485*9880d681SAndroid Build Coastguard Worker//   except for our own input by listing the relevant registers in Defs. By
3486*9880d681SAndroid Build Coastguard Worker//   doing so, we also cause the prologue/epilogue code to actively preserve
3487*9880d681SAndroid Build Coastguard Worker//   all of the callee-saved resgisters, which is exactly what we want.
3488*9880d681SAndroid Build Coastguard Worker//   $val is a scratch register for our use.
3489*9880d681SAndroid Build Coastguard Workerlet Defs =
3490*9880d681SAndroid Build Coastguard Worker  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR,
3491*9880d681SAndroid Build Coastguard Worker    Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15],
3492*9880d681SAndroid Build Coastguard Worker  hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
3493*9880d681SAndroid Build Coastguard Worker  usesCustomInserter = 1 in {
3494*9880d681SAndroid Build Coastguard Worker  def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
3495*9880d681SAndroid Build Coastguard Worker                               AddrModeNone, 0, NoItinerary, "", "",
3496*9880d681SAndroid Build Coastguard Worker                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
3497*9880d681SAndroid Build Coastguard Worker                             Requires<[IsThumb2, HasVFP2]>;
3498*9880d681SAndroid Build Coastguard Worker}
3499*9880d681SAndroid Build Coastguard Worker
3500*9880d681SAndroid Build Coastguard Workerlet Defs =
3501*9880d681SAndroid Build Coastguard Worker  [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,  R8,  R9,  R10, R11, R12, LR, CPSR ],
3502*9880d681SAndroid Build Coastguard Worker  hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
3503*9880d681SAndroid Build Coastguard Worker  usesCustomInserter = 1 in {
3504*9880d681SAndroid Build Coastguard Worker  def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
3505*9880d681SAndroid Build Coastguard Worker                               AddrModeNone, 0, NoItinerary, "", "",
3506*9880d681SAndroid Build Coastguard Worker                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
3507*9880d681SAndroid Build Coastguard Worker                                  Requires<[IsThumb2, NoVFP]>;
3508*9880d681SAndroid Build Coastguard Worker}
3509*9880d681SAndroid Build Coastguard Worker
3510*9880d681SAndroid Build Coastguard Worker
3511*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3512*9880d681SAndroid Build Coastguard Worker// Control-Flow Instructions
3513*9880d681SAndroid Build Coastguard Worker//
3514*9880d681SAndroid Build Coastguard Worker
3515*9880d681SAndroid Build Coastguard Worker// FIXME: remove when we have a way to marking a MI with these properties.
3516*9880d681SAndroid Build Coastguard Worker// FIXME: Should pc be an implicit operand like PICADD, etc?
3517*9880d681SAndroid Build Coastguard Workerlet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
3518*9880d681SAndroid Build Coastguard Worker    hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
3519*9880d681SAndroid Build Coastguard Workerdef t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
3520*9880d681SAndroid Build Coastguard Worker                                                   reglist:$regs, variable_ops),
3521*9880d681SAndroid Build Coastguard Worker                              4, IIC_iLoad_mBr, [],
3522*9880d681SAndroid Build Coastguard Worker            (t2LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
3523*9880d681SAndroid Build Coastguard Worker                         RegConstraint<"$Rn = $wb">;
3524*9880d681SAndroid Build Coastguard Worker
3525*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, isBarrier = 1 in {
3526*9880d681SAndroid Build Coastguard Workerlet isPredicable = 1 in
3527*9880d681SAndroid Build Coastguard Workerdef t2B   : T2I<(outs), (ins thumb_br_target:$target), IIC_Br,
3528*9880d681SAndroid Build Coastguard Worker                 "b", ".w\t$target",
3529*9880d681SAndroid Build Coastguard Worker                 [(br bb:$target)]>, Sched<[WriteBr]>,
3530*9880d681SAndroid Build Coastguard Worker                 Requires<[IsThumb, HasV8MBaseline]> {
3531*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
3532*9880d681SAndroid Build Coastguard Worker  let Inst{15-14} = 0b10;
3533*9880d681SAndroid Build Coastguard Worker  let Inst{12} = 1;
3534*9880d681SAndroid Build Coastguard Worker
3535*9880d681SAndroid Build Coastguard Worker  bits<24> target;
3536*9880d681SAndroid Build Coastguard Worker  let Inst{26} = target{23};
3537*9880d681SAndroid Build Coastguard Worker  let Inst{13} = target{22};
3538*9880d681SAndroid Build Coastguard Worker  let Inst{11} = target{21};
3539*9880d681SAndroid Build Coastguard Worker  let Inst{25-16} = target{20-11};
3540*9880d681SAndroid Build Coastguard Worker  let Inst{10-0} = target{10-0};
3541*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2BInstruction";
3542*9880d681SAndroid Build Coastguard Worker  let AsmMatchConverter = "cvtThumbBranches";
3543*9880d681SAndroid Build Coastguard Worker}
3544*9880d681SAndroid Build Coastguard Worker
3545*9880d681SAndroid Build Coastguard Workerlet Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {
3546*9880d681SAndroid Build Coastguard Workerdef t2BR_JT : t2PseudoInst<(outs),
3547*9880d681SAndroid Build Coastguard Worker          (ins GPR:$target, GPR:$index, i32imm:$jt),
3548*9880d681SAndroid Build Coastguard Worker           0, IIC_Br,
3549*9880d681SAndroid Build Coastguard Worker          [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt)]>,
3550*9880d681SAndroid Build Coastguard Worker          Sched<[WriteBr]>;
3551*9880d681SAndroid Build Coastguard Worker
3552*9880d681SAndroid Build Coastguard Worker// FIXME: Add a case that can be predicated.
3553*9880d681SAndroid Build Coastguard Workerdef t2TBB_JT : t2PseudoInst<(outs),
3554*9880d681SAndroid Build Coastguard Worker        (ins GPR:$base, GPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>,
3555*9880d681SAndroid Build Coastguard Worker        Sched<[WriteBr]>;
3556*9880d681SAndroid Build Coastguard Worker
3557*9880d681SAndroid Build Coastguard Workerdef t2TBH_JT : t2PseudoInst<(outs),
3558*9880d681SAndroid Build Coastguard Worker        (ins GPR:$base, GPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>,
3559*9880d681SAndroid Build Coastguard Worker        Sched<[WriteBr]>;
3560*9880d681SAndroid Build Coastguard Worker
3561*9880d681SAndroid Build Coastguard Workerdef t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br,
3562*9880d681SAndroid Build Coastguard Worker                    "tbb", "\t$addr", []>, Sched<[WriteBrTbl]> {
3563*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
3564*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
3565*9880d681SAndroid Build Coastguard Worker  let Inst{31-20} = 0b111010001101;
3566*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
3567*9880d681SAndroid Build Coastguard Worker  let Inst{15-5} = 0b11110000000;
3568*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 0; // B form
3569*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = Rm;
3570*9880d681SAndroid Build Coastguard Worker
3571*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeThumbTableBranch";
3572*9880d681SAndroid Build Coastguard Worker}
3573*9880d681SAndroid Build Coastguard Worker
3574*9880d681SAndroid Build Coastguard Workerdef t2TBH : T2I<(outs), (ins addrmode_tbh:$addr), IIC_Br,
3575*9880d681SAndroid Build Coastguard Worker                   "tbh", "\t$addr", []>, Sched<[WriteBrTbl]> {
3576*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
3577*9880d681SAndroid Build Coastguard Worker  bits<4> Rm;
3578*9880d681SAndroid Build Coastguard Worker  let Inst{31-20} = 0b111010001101;
3579*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
3580*9880d681SAndroid Build Coastguard Worker  let Inst{15-5} = 0b11110000000;
3581*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 1; // H form
3582*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = Rm;
3583*9880d681SAndroid Build Coastguard Worker
3584*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeThumbTableBranch";
3585*9880d681SAndroid Build Coastguard Worker}
3586*9880d681SAndroid Build Coastguard Worker} // isNotDuplicable, isIndirectBranch
3587*9880d681SAndroid Build Coastguard Worker
3588*9880d681SAndroid Build Coastguard Worker} // isBranch, isTerminator, isBarrier
3589*9880d681SAndroid Build Coastguard Worker
3590*9880d681SAndroid Build Coastguard Worker// FIXME: should be able to write a pattern for ARMBrcond, but can't use
3591*9880d681SAndroid Build Coastguard Worker// a two-value operand where a dag node expects ", "two operands. :(
3592*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1 in
3593*9880d681SAndroid Build Coastguard Workerdef t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
3594*9880d681SAndroid Build Coastguard Worker                "b", ".w\t$target",
3595*9880d681SAndroid Build Coastguard Worker                [/*(ARMbrcond bb:$target, imm:$cc)*/]>, Sched<[WriteBr]> {
3596*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
3597*9880d681SAndroid Build Coastguard Worker  let Inst{15-14} = 0b10;
3598*9880d681SAndroid Build Coastguard Worker  let Inst{12} = 0;
3599*9880d681SAndroid Build Coastguard Worker
3600*9880d681SAndroid Build Coastguard Worker  bits<4> p;
3601*9880d681SAndroid Build Coastguard Worker  let Inst{25-22} = p;
3602*9880d681SAndroid Build Coastguard Worker
3603*9880d681SAndroid Build Coastguard Worker  bits<21> target;
3604*9880d681SAndroid Build Coastguard Worker  let Inst{26} = target{20};
3605*9880d681SAndroid Build Coastguard Worker  let Inst{11} = target{19};
3606*9880d681SAndroid Build Coastguard Worker  let Inst{13} = target{18};
3607*9880d681SAndroid Build Coastguard Worker  let Inst{21-16} = target{17-12};
3608*9880d681SAndroid Build Coastguard Worker  let Inst{10-0} = target{11-1};
3609*9880d681SAndroid Build Coastguard Worker
3610*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeThumb2BCCInstruction";
3611*9880d681SAndroid Build Coastguard Worker  let AsmMatchConverter = "cvtThumbBranches";
3612*9880d681SAndroid Build Coastguard Worker}
3613*9880d681SAndroid Build Coastguard Worker
3614*9880d681SAndroid Build Coastguard Worker// Tail calls. The MachO version of thumb tail calls uses a t2 branch, so
3615*9880d681SAndroid Build Coastguard Worker// it goes here.
3616*9880d681SAndroid Build Coastguard Workerlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
3617*9880d681SAndroid Build Coastguard Worker  // IOS version.
3618*9880d681SAndroid Build Coastguard Worker  let Uses = [SP] in
3619*9880d681SAndroid Build Coastguard Worker  def tTAILJMPd: tPseudoExpand<(outs),
3620*9880d681SAndroid Build Coastguard Worker                   (ins thumb_br_target:$dst, pred:$p),
3621*9880d681SAndroid Build Coastguard Worker                   4, IIC_Br, [],
3622*9880d681SAndroid Build Coastguard Worker                   (t2B thumb_br_target:$dst, pred:$p)>,
3623*9880d681SAndroid Build Coastguard Worker                 Requires<[IsThumb2, IsMachO]>, Sched<[WriteBr]>;
3624*9880d681SAndroid Build Coastguard Worker}
3625*9880d681SAndroid Build Coastguard Worker
3626*9880d681SAndroid Build Coastguard Worker// IT block
3627*9880d681SAndroid Build Coastguard Workerlet Defs = [ITSTATE] in
3628*9880d681SAndroid Build Coastguard Workerdef t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
3629*9880d681SAndroid Build Coastguard Worker                    AddrModeNone, 2,  IIC_iALUx,
3630*9880d681SAndroid Build Coastguard Worker                    "it$mask\t$cc", "", []>,
3631*9880d681SAndroid Build Coastguard Worker           ComplexDeprecationPredicate<"IT"> {
3632*9880d681SAndroid Build Coastguard Worker  // 16-bit instruction.
3633*9880d681SAndroid Build Coastguard Worker  let Inst{31-16} = 0x0000;
3634*9880d681SAndroid Build Coastguard Worker  let Inst{15-8} = 0b10111111;
3635*9880d681SAndroid Build Coastguard Worker
3636*9880d681SAndroid Build Coastguard Worker  bits<4> cc;
3637*9880d681SAndroid Build Coastguard Worker  bits<4> mask;
3638*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = cc;
3639*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = mask;
3640*9880d681SAndroid Build Coastguard Worker
3641*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeIT";
3642*9880d681SAndroid Build Coastguard Worker}
3643*9880d681SAndroid Build Coastguard Worker
3644*9880d681SAndroid Build Coastguard Worker// Branch and Exchange Jazelle -- for disassembly only
3645*9880d681SAndroid Build Coastguard Worker// Rm = Inst{19-16}
3646*9880d681SAndroid Build Coastguard Workerdef t2BXJ : T2I<(outs), (ins GPRnopc:$func), NoItinerary, "bxj", "\t$func", []>,
3647*9880d681SAndroid Build Coastguard Worker    Sched<[WriteBr]>, Requires<[IsThumb2, IsNotMClass]> {
3648*9880d681SAndroid Build Coastguard Worker  bits<4> func;
3649*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
3650*9880d681SAndroid Build Coastguard Worker  let Inst{26} = 0;
3651*9880d681SAndroid Build Coastguard Worker  let Inst{25-20} = 0b111100;
3652*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = func;
3653*9880d681SAndroid Build Coastguard Worker  let Inst{15-0} = 0b1000111100000000;
3654*9880d681SAndroid Build Coastguard Worker}
3655*9880d681SAndroid Build Coastguard Worker
3656*9880d681SAndroid Build Coastguard Worker// Compare and branch on zero / non-zero
3657*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1 in {
3658*9880d681SAndroid Build Coastguard Worker  def tCBZ  : T1I<(outs), (ins tGPR:$Rn, thumb_cb_target:$target), IIC_Br,
3659*9880d681SAndroid Build Coastguard Worker                  "cbz\t$Rn, $target", []>,
3660*9880d681SAndroid Build Coastguard Worker              T1Misc<{0,0,?,1,?,?,?}>,
3661*9880d681SAndroid Build Coastguard Worker              Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteBr]> {
3662*9880d681SAndroid Build Coastguard Worker    // A8.6.27
3663*9880d681SAndroid Build Coastguard Worker    bits<6> target;
3664*9880d681SAndroid Build Coastguard Worker    bits<3> Rn;
3665*9880d681SAndroid Build Coastguard Worker    let Inst{9}   = target{5};
3666*9880d681SAndroid Build Coastguard Worker    let Inst{7-3} = target{4-0};
3667*9880d681SAndroid Build Coastguard Worker    let Inst{2-0} = Rn;
3668*9880d681SAndroid Build Coastguard Worker  }
3669*9880d681SAndroid Build Coastguard Worker
3670*9880d681SAndroid Build Coastguard Worker  def tCBNZ : T1I<(outs), (ins tGPR:$Rn, thumb_cb_target:$target), IIC_Br,
3671*9880d681SAndroid Build Coastguard Worker                  "cbnz\t$Rn, $target", []>,
3672*9880d681SAndroid Build Coastguard Worker              T1Misc<{1,0,?,1,?,?,?}>,
3673*9880d681SAndroid Build Coastguard Worker              Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteBr]> {
3674*9880d681SAndroid Build Coastguard Worker    // A8.6.27
3675*9880d681SAndroid Build Coastguard Worker    bits<6> target;
3676*9880d681SAndroid Build Coastguard Worker    bits<3> Rn;
3677*9880d681SAndroid Build Coastguard Worker    let Inst{9}   = target{5};
3678*9880d681SAndroid Build Coastguard Worker    let Inst{7-3} = target{4-0};
3679*9880d681SAndroid Build Coastguard Worker    let Inst{2-0} = Rn;
3680*9880d681SAndroid Build Coastguard Worker  }
3681*9880d681SAndroid Build Coastguard Worker}
3682*9880d681SAndroid Build Coastguard Worker
3683*9880d681SAndroid Build Coastguard Worker
3684*9880d681SAndroid Build Coastguard Worker// Change Processor State is a system instruction.
3685*9880d681SAndroid Build Coastguard Worker// FIXME: Since the asm parser has currently no clean way to handle optional
3686*9880d681SAndroid Build Coastguard Worker// operands, create 3 versions of the same instruction. Once there's a clean
3687*9880d681SAndroid Build Coastguard Worker// framework to represent optional operands, change this behavior.
3688*9880d681SAndroid Build Coastguard Workerclass t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary,
3689*9880d681SAndroid Build Coastguard Worker            !strconcat("cps", asm_op), []>,
3690*9880d681SAndroid Build Coastguard Worker          Requires<[IsThumb2, IsNotMClass]> {
3691*9880d681SAndroid Build Coastguard Worker  bits<2> imod;
3692*9880d681SAndroid Build Coastguard Worker  bits<3> iflags;
3693*9880d681SAndroid Build Coastguard Worker  bits<5> mode;
3694*9880d681SAndroid Build Coastguard Worker  bit M;
3695*9880d681SAndroid Build Coastguard Worker
3696*9880d681SAndroid Build Coastguard Worker  let Inst{31-11} = 0b111100111010111110000;
3697*9880d681SAndroid Build Coastguard Worker  let Inst{10-9}  = imod;
3698*9880d681SAndroid Build Coastguard Worker  let Inst{8}     = M;
3699*9880d681SAndroid Build Coastguard Worker  let Inst{7-5}   = iflags;
3700*9880d681SAndroid Build Coastguard Worker  let Inst{4-0}   = mode;
3701*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "DecodeT2CPSInstruction";
3702*9880d681SAndroid Build Coastguard Worker}
3703*9880d681SAndroid Build Coastguard Worker
3704*9880d681SAndroid Build Coastguard Workerlet M = 1 in
3705*9880d681SAndroid Build Coastguard Worker  def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode),
3706*9880d681SAndroid Build Coastguard Worker                      "$imod\t$iflags, $mode">;
3707*9880d681SAndroid Build Coastguard Workerlet mode = 0, M = 0 in
3708*9880d681SAndroid Build Coastguard Worker  def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags),
3709*9880d681SAndroid Build Coastguard Worker                      "$imod.w\t$iflags">;
3710*9880d681SAndroid Build Coastguard Workerlet imod = 0, iflags = 0, M = 1 in
3711*9880d681SAndroid Build Coastguard Worker  def t2CPS1p : t2CPS<(ins imm0_31:$mode), "\t$mode">;
3712*9880d681SAndroid Build Coastguard Worker
3713*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cps$imod.w $iflags, $mode",
3714*9880d681SAndroid Build Coastguard Worker                   (t2CPS3p imod_op:$imod, iflags_op:$iflags, i32imm:$mode), 0>;
3715*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cps.w $mode", (t2CPS1p imm0_31:$mode), 0>;
3716*9880d681SAndroid Build Coastguard Worker
3717*9880d681SAndroid Build Coastguard Worker// A6.3.4 Branches and miscellaneous control
3718*9880d681SAndroid Build Coastguard Worker// Table A6-14 Change Processor State, and hint instructions
3719*9880d681SAndroid Build Coastguard Workerdef t2HINT : T2I<(outs), (ins imm0_239:$imm), NoItinerary, "hint", ".w\t$imm",
3720*9880d681SAndroid Build Coastguard Worker                  [(int_arm_hint imm0_239:$imm)]> {
3721*9880d681SAndroid Build Coastguard Worker  bits<8> imm;
3722*9880d681SAndroid Build Coastguard Worker  let Inst{31-3} = 0b11110011101011111000000000000;
3723*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = imm;
3724*9880d681SAndroid Build Coastguard Worker}
3725*9880d681SAndroid Build Coastguard Worker
3726*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"hint$p $imm", (t2HINT imm0_239:$imm, pred:$p), 0>;
3727*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p), 1>;
3728*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p), 1>;
3729*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p), 1>;
3730*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"wfi$p.w", (t2HINT 3, pred:$p), 1>;
3731*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p), 1>;
3732*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sevl$p.w", (t2HINT 5, pred:$p), 1> {
3733*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, HasV8];
3734*9880d681SAndroid Build Coastguard Worker}
3735*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"esb$p.w", (t2HINT 16, pred:$p), 1> {
3736*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, HasRAS];
3737*9880d681SAndroid Build Coastguard Worker}
3738*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"esb$p", (t2HINT 16, pred:$p), 0> {
3739*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, HasRAS];
3740*9880d681SAndroid Build Coastguard Worker}
3741*9880d681SAndroid Build Coastguard Worker
3742*9880d681SAndroid Build Coastguard Workerdef t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt",
3743*9880d681SAndroid Build Coastguard Worker                [(int_arm_dbg imm0_15:$opt)]> {
3744*9880d681SAndroid Build Coastguard Worker  bits<4> opt;
3745*9880d681SAndroid Build Coastguard Worker  let Inst{31-20} = 0b111100111010;
3746*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111;
3747*9880d681SAndroid Build Coastguard Worker  let Inst{15-8} = 0b10000000;
3748*9880d681SAndroid Build Coastguard Worker  let Inst{7-4} = 0b1111;
3749*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = opt;
3750*9880d681SAndroid Build Coastguard Worker}
3751*9880d681SAndroid Build Coastguard Worker
3752*9880d681SAndroid Build Coastguard Worker// Secure Monitor Call is a system instruction.
3753*9880d681SAndroid Build Coastguard Worker// Option = Inst{19-16}
3754*9880d681SAndroid Build Coastguard Workerdef t2SMC : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt",
3755*9880d681SAndroid Build Coastguard Worker                []>, Requires<[IsThumb2, HasTrustZone]> {
3756*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
3757*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b1111111;
3758*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
3759*9880d681SAndroid Build Coastguard Worker
3760*9880d681SAndroid Build Coastguard Worker  bits<4> opt;
3761*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = opt;
3762*9880d681SAndroid Build Coastguard Worker}
3763*9880d681SAndroid Build Coastguard Worker
3764*9880d681SAndroid Build Coastguard Workerclass T2DCPS<bits<2> opt, string opc>
3765*9880d681SAndroid Build Coastguard Worker  : T2I<(outs), (ins), NoItinerary, opc, "", []>, Requires<[IsThumb2, HasV8]> {
3766*9880d681SAndroid Build Coastguard Worker  let Inst{31-27} = 0b11110;
3767*9880d681SAndroid Build Coastguard Worker  let Inst{26-20} = 0b1111000;
3768*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = 0b1111;
3769*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
3770*9880d681SAndroid Build Coastguard Worker  let Inst{11-2} = 0b0000000000;
3771*9880d681SAndroid Build Coastguard Worker  let Inst{1-0} = opt;
3772*9880d681SAndroid Build Coastguard Worker}
3773*9880d681SAndroid Build Coastguard Worker
3774*9880d681SAndroid Build Coastguard Workerdef t2DCPS1 : T2DCPS<0b01, "dcps1">;
3775*9880d681SAndroid Build Coastguard Workerdef t2DCPS2 : T2DCPS<0b10, "dcps2">;
3776*9880d681SAndroid Build Coastguard Workerdef t2DCPS3 : T2DCPS<0b11, "dcps3">;
3777*9880d681SAndroid Build Coastguard Worker
3778*9880d681SAndroid Build Coastguard Workerclass T2SRS<bits<2> Op, bit W, dag oops, dag iops, InstrItinClass itin,
3779*9880d681SAndroid Build Coastguard Worker            string opc, string asm, list<dag> pattern>
3780*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern>,
3781*9880d681SAndroid Build Coastguard Worker    Requires<[IsThumb2,IsNotMClass]> {
3782*9880d681SAndroid Build Coastguard Worker  bits<5> mode;
3783*9880d681SAndroid Build Coastguard Worker  let Inst{31-25} = 0b1110100;
3784*9880d681SAndroid Build Coastguard Worker  let Inst{24-23} = Op;
3785*9880d681SAndroid Build Coastguard Worker  let Inst{22} = 0;
3786*9880d681SAndroid Build Coastguard Worker  let Inst{21} = W;
3787*9880d681SAndroid Build Coastguard Worker  let Inst{20-16} = 0b01101;
3788*9880d681SAndroid Build Coastguard Worker  let Inst{15-5} = 0b11000000000;
3789*9880d681SAndroid Build Coastguard Worker  let Inst{4-0} = mode{4-0};
3790*9880d681SAndroid Build Coastguard Worker}
3791*9880d681SAndroid Build Coastguard Worker
3792*9880d681SAndroid Build Coastguard Worker// Store Return State is a system instruction.
3793*9880d681SAndroid Build Coastguard Workerdef t2SRSDB_UPD : T2SRS<0b00, 1, (outs), (ins imm0_31:$mode), NoItinerary,
3794*9880d681SAndroid Build Coastguard Worker                        "srsdb", "\tsp!, $mode", []>;
3795*9880d681SAndroid Build Coastguard Workerdef t2SRSDB  : T2SRS<0b00, 0, (outs), (ins imm0_31:$mode), NoItinerary,
3796*9880d681SAndroid Build Coastguard Worker                     "srsdb","\tsp, $mode", []>;
3797*9880d681SAndroid Build Coastguard Workerdef t2SRSIA_UPD : T2SRS<0b11, 1, (outs), (ins imm0_31:$mode), NoItinerary,
3798*9880d681SAndroid Build Coastguard Worker                        "srsia","\tsp!, $mode", []>;
3799*9880d681SAndroid Build Coastguard Workerdef t2SRSIA  : T2SRS<0b11, 0, (outs), (ins imm0_31:$mode), NoItinerary,
3800*9880d681SAndroid Build Coastguard Worker                     "srsia","\tsp, $mode", []>;
3801*9880d681SAndroid Build Coastguard Worker
3802*9880d681SAndroid Build Coastguard Worker
3803*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"srsdb${p} $mode", (t2SRSDB imm0_31:$mode, pred:$p)>;
3804*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"srsdb${p} $mode!", (t2SRSDB_UPD imm0_31:$mode, pred:$p)>;
3805*9880d681SAndroid Build Coastguard Worker
3806*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"srsia${p} $mode", (t2SRSIA imm0_31:$mode, pred:$p)>;
3807*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"srsia${p} $mode!", (t2SRSIA_UPD imm0_31:$mode, pred:$p)>;
3808*9880d681SAndroid Build Coastguard Worker
3809*9880d681SAndroid Build Coastguard Worker// Return From Exception is a system instruction.
3810*9880d681SAndroid Build Coastguard Workerclass T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin,
3811*9880d681SAndroid Build Coastguard Worker          string opc, string asm, list<dag> pattern>
3812*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, itin, opc, asm, pattern>,
3813*9880d681SAndroid Build Coastguard Worker    Requires<[IsThumb2,IsNotMClass]> {
3814*9880d681SAndroid Build Coastguard Worker  let Inst{31-20} = op31_20{11-0};
3815*9880d681SAndroid Build Coastguard Worker
3816*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
3817*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
3818*9880d681SAndroid Build Coastguard Worker  let Inst{15-0} = 0xc000;
3819*9880d681SAndroid Build Coastguard Worker}
3820*9880d681SAndroid Build Coastguard Worker
3821*9880d681SAndroid Build Coastguard Workerdef t2RFEDBW : T2RFE<0b111010000011,
3822*9880d681SAndroid Build Coastguard Worker                   (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn!",
3823*9880d681SAndroid Build Coastguard Worker                   [/* For disassembly only; pattern left blank */]>;
3824*9880d681SAndroid Build Coastguard Workerdef t2RFEDB  : T2RFE<0b111010000001,
3825*9880d681SAndroid Build Coastguard Worker                   (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn",
3826*9880d681SAndroid Build Coastguard Worker                   [/* For disassembly only; pattern left blank */]>;
3827*9880d681SAndroid Build Coastguard Workerdef t2RFEIAW : T2RFE<0b111010011011,
3828*9880d681SAndroid Build Coastguard Worker                   (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn!",
3829*9880d681SAndroid Build Coastguard Worker                   [/* For disassembly only; pattern left blank */]>;
3830*9880d681SAndroid Build Coastguard Workerdef t2RFEIA  : T2RFE<0b111010011001,
3831*9880d681SAndroid Build Coastguard Worker                   (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
3832*9880d681SAndroid Build Coastguard Worker                   [/* For disassembly only; pattern left blank */]>;
3833*9880d681SAndroid Build Coastguard Worker
3834*9880d681SAndroid Build Coastguard Worker// B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction.
3835*9880d681SAndroid Build Coastguard Worker// Exception return instruction is "subs pc, lr, #imm".
3836*9880d681SAndroid Build Coastguard Workerlet isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in
3837*9880d681SAndroid Build Coastguard Workerdef t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary,
3838*9880d681SAndroid Build Coastguard Worker                        "subs", "\tpc, lr, $imm",
3839*9880d681SAndroid Build Coastguard Worker                        [(ARMintretflag imm0_255:$imm)]>,
3840*9880d681SAndroid Build Coastguard Worker                   Requires<[IsThumb2,IsNotMClass]> {
3841*9880d681SAndroid Build Coastguard Worker  let Inst{31-8} = 0b111100111101111010001111;
3842*9880d681SAndroid Build Coastguard Worker
3843*9880d681SAndroid Build Coastguard Worker  bits<8> imm;
3844*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = imm;
3845*9880d681SAndroid Build Coastguard Worker}
3846*9880d681SAndroid Build Coastguard Worker
3847*9880d681SAndroid Build Coastguard Worker// Hypervisor Call is a system instruction.
3848*9880d681SAndroid Build Coastguard Workerlet isCall = 1 in {
3849*9880d681SAndroid Build Coastguard Workerdef t2HVC : T2XI <(outs), (ins imm0_65535:$imm16), IIC_Br, "hvc.w\t$imm16", []>,
3850*9880d681SAndroid Build Coastguard Worker      Requires<[IsThumb2, HasVirtualization]>, Sched<[WriteBr]> {
3851*9880d681SAndroid Build Coastguard Worker    bits<16> imm16;
3852*9880d681SAndroid Build Coastguard Worker    let Inst{31-20} = 0b111101111110;
3853*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = imm16{15-12};
3854*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = 0b1000;
3855*9880d681SAndroid Build Coastguard Worker    let Inst{11-0} = imm16{11-0};
3856*9880d681SAndroid Build Coastguard Worker}
3857*9880d681SAndroid Build Coastguard Worker}
3858*9880d681SAndroid Build Coastguard Worker
3859*9880d681SAndroid Build Coastguard Worker// Alias for HVC without the ".w" optional width specifier
3860*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"hvc\t$imm16", (t2HVC imm0_65535:$imm16)>;
3861*9880d681SAndroid Build Coastguard Worker
3862*9880d681SAndroid Build Coastguard Worker// ERET - Return from exception in Hypervisor mode.
3863*9880d681SAndroid Build Coastguard Worker// B9.3.3, B9.3.20: ERET is an alias for "SUBS PC, LR, #0" in an implementation that
3864*9880d681SAndroid Build Coastguard Worker// includes virtualization extensions.
3865*9880d681SAndroid Build Coastguard Workerdef t2ERET : InstAlias<"eret${p}", (t2SUBS_PC_LR 0, pred:$p), 1>,
3866*9880d681SAndroid Build Coastguard Worker             Requires<[IsThumb2, HasVirtualization]>;
3867*9880d681SAndroid Build Coastguard Worker
3868*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3869*9880d681SAndroid Build Coastguard Worker// Non-Instruction Patterns
3870*9880d681SAndroid Build Coastguard Worker//
3871*9880d681SAndroid Build Coastguard Worker
3872*9880d681SAndroid Build Coastguard Worker// 32-bit immediate using movw + movt.
3873*9880d681SAndroid Build Coastguard Worker// This is a single pseudo instruction to make it re-materializable.
3874*9880d681SAndroid Build Coastguard Worker// FIXME: Remove this when we can do generalized remat.
3875*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isMoveImm = 1 in
3876*9880d681SAndroid Build Coastguard Workerdef t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
3877*9880d681SAndroid Build Coastguard Worker                            [(set rGPR:$dst, (i32 imm:$src))]>,
3878*9880d681SAndroid Build Coastguard Worker                            Requires<[IsThumb, UseMovt]>;
3879*9880d681SAndroid Build Coastguard Worker
3880*9880d681SAndroid Build Coastguard Worker// Pseudo instruction that combines movw + movt + add pc (if pic).
3881*9880d681SAndroid Build Coastguard Worker// It also makes it possible to rematerialize the instructions.
3882*9880d681SAndroid Build Coastguard Worker// FIXME: Remove this when we can do generalized remat and when machine licm
3883*9880d681SAndroid Build Coastguard Worker// can properly the instructions.
3884*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1 in {
3885*9880d681SAndroid Build Coastguard Workerdef t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr),
3886*9880d681SAndroid Build Coastguard Worker                                IIC_iMOVix2addpc,
3887*9880d681SAndroid Build Coastguard Worker                          [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>,
3888*9880d681SAndroid Build Coastguard Worker                          Requires<[IsThumb, HasV8MBaseline, UseMovt]>;
3889*9880d681SAndroid Build Coastguard Worker
3890*9880d681SAndroid Build Coastguard Worker}
3891*9880d681SAndroid Build Coastguard Worker
3892*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapperPIC tglobaltlsaddr :$dst),
3893*9880d681SAndroid Build Coastguard Worker            (t2MOV_ga_pcrel tglobaltlsaddr:$dst)>,
3894*9880d681SAndroid Build Coastguard Worker      Requires<[IsThumb2, UseMovt]>;
3895*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapper tglobaltlsaddr:$dst),
3896*9880d681SAndroid Build Coastguard Worker            (t2MOVi32imm tglobaltlsaddr:$dst)>,
3897*9880d681SAndroid Build Coastguard Worker      Requires<[IsThumb2, UseMovt]>;
3898*9880d681SAndroid Build Coastguard Worker
3899*9880d681SAndroid Build Coastguard Worker// ConstantPool, GlobalAddress, and JumpTable
3900*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
3901*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapper texternalsym :$dst), (t2MOVi32imm texternalsym :$dst)>,
3902*9880d681SAndroid Build Coastguard Worker    Requires<[IsThumb, HasV8MBaseline, UseMovt]>;
3903*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
3904*9880d681SAndroid Build Coastguard Worker    Requires<[IsThumb, HasV8MBaseline, UseMovt]>;
3905*9880d681SAndroid Build Coastguard Worker
3906*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(ARMWrapperJT tjumptable:$dst), (t2LEApcrelJT tjumptable:$dst)>;
3907*9880d681SAndroid Build Coastguard Worker
3908*9880d681SAndroid Build Coastguard Worker// Pseudo instruction that combines ldr from constpool and add pc. This should
3909*9880d681SAndroid Build Coastguard Worker// be expanded into two instructions late to allow if-conversion and
3910*9880d681SAndroid Build Coastguard Worker// scheduling.
3911*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, isReMaterializable = 1 in
3912*9880d681SAndroid Build Coastguard Workerdef t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
3913*9880d681SAndroid Build Coastguard Worker                   IIC_iLoadiALU,
3914*9880d681SAndroid Build Coastguard Worker              [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
3915*9880d681SAndroid Build Coastguard Worker                                           imm:$cp))]>,
3916*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb2]>;
3917*9880d681SAndroid Build Coastguard Worker
3918*9880d681SAndroid Build Coastguard Worker// Pseudo isntruction that combines movs + predicated rsbmi
3919*9880d681SAndroid Build Coastguard Worker// to implement integer ABS
3920*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1, Defs = [CPSR] in {
3921*9880d681SAndroid Build Coastguard Workerdef t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src),
3922*9880d681SAndroid Build Coastguard Worker                       NoItinerary, []>, Requires<[IsThumb2]>;
3923*9880d681SAndroid Build Coastguard Worker}
3924*9880d681SAndroid Build Coastguard Worker
3925*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3926*9880d681SAndroid Build Coastguard Worker// Coprocessor load/store -- for disassembly only
3927*9880d681SAndroid Build Coastguard Worker//
3928*9880d681SAndroid Build Coastguard Workerclass T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm, list<dag> pattern>
3929*9880d681SAndroid Build Coastguard Worker  : T2I<oops, iops, NoItinerary, opc, asm, pattern> {
3930*9880d681SAndroid Build Coastguard Worker  let Inst{31-28} = op31_28;
3931*9880d681SAndroid Build Coastguard Worker  let Inst{27-25} = 0b110;
3932*9880d681SAndroid Build Coastguard Worker}
3933*9880d681SAndroid Build Coastguard Worker
3934*9880d681SAndroid Build Coastguard Workermulticlass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm, list<dag> pattern> {
3935*9880d681SAndroid Build Coastguard Worker  def _OFFSET : T2CI<op31_28,
3936*9880d681SAndroid Build Coastguard Worker                     (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
3937*9880d681SAndroid Build Coastguard Worker                     asm, "\t$cop, $CRd, $addr", pattern> {
3938*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
3939*9880d681SAndroid Build Coastguard Worker    bits<4> cop;
3940*9880d681SAndroid Build Coastguard Worker    bits<4> CRd;
3941*9880d681SAndroid Build Coastguard Worker    let Inst{24} = 1; // P = 1
3942*9880d681SAndroid Build Coastguard Worker    let Inst{23} = addr{8};
3943*9880d681SAndroid Build Coastguard Worker    let Inst{22} = Dbit;
3944*9880d681SAndroid Build Coastguard Worker    let Inst{21} = 0; // W = 0
3945*9880d681SAndroid Build Coastguard Worker    let Inst{20} = load;
3946*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{12-9};
3947*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = CRd;
3948*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = cop;
3949*9880d681SAndroid Build Coastguard Worker    let Inst{7-0} = addr{7-0};
3950*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeCopMemInstruction";
3951*9880d681SAndroid Build Coastguard Worker  }
3952*9880d681SAndroid Build Coastguard Worker  def _PRE : T2CI<op31_28,
3953*9880d681SAndroid Build Coastguard Worker                  (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr),
3954*9880d681SAndroid Build Coastguard Worker                  asm, "\t$cop, $CRd, $addr!", []> {
3955*9880d681SAndroid Build Coastguard Worker    bits<13> addr;
3956*9880d681SAndroid Build Coastguard Worker    bits<4> cop;
3957*9880d681SAndroid Build Coastguard Worker    bits<4> CRd;
3958*9880d681SAndroid Build Coastguard Worker    let Inst{24} = 1; // P = 1
3959*9880d681SAndroid Build Coastguard Worker    let Inst{23} = addr{8};
3960*9880d681SAndroid Build Coastguard Worker    let Inst{22} = Dbit;
3961*9880d681SAndroid Build Coastguard Worker    let Inst{21} = 1; // W = 1
3962*9880d681SAndroid Build Coastguard Worker    let Inst{20} = load;
3963*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr{12-9};
3964*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = CRd;
3965*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = cop;
3966*9880d681SAndroid Build Coastguard Worker    let Inst{7-0} = addr{7-0};
3967*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeCopMemInstruction";
3968*9880d681SAndroid Build Coastguard Worker  }
3969*9880d681SAndroid Build Coastguard Worker  def _POST: T2CI<op31_28,
3970*9880d681SAndroid Build Coastguard Worker                  (outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
3971*9880d681SAndroid Build Coastguard Worker                               postidx_imm8s4:$offset),
3972*9880d681SAndroid Build Coastguard Worker                 asm, "\t$cop, $CRd, $addr, $offset", []> {
3973*9880d681SAndroid Build Coastguard Worker    bits<9> offset;
3974*9880d681SAndroid Build Coastguard Worker    bits<4> addr;
3975*9880d681SAndroid Build Coastguard Worker    bits<4> cop;
3976*9880d681SAndroid Build Coastguard Worker    bits<4> CRd;
3977*9880d681SAndroid Build Coastguard Worker    let Inst{24} = 0; // P = 0
3978*9880d681SAndroid Build Coastguard Worker    let Inst{23} = offset{8};
3979*9880d681SAndroid Build Coastguard Worker    let Inst{22} = Dbit;
3980*9880d681SAndroid Build Coastguard Worker    let Inst{21} = 1; // W = 1
3981*9880d681SAndroid Build Coastguard Worker    let Inst{20} = load;
3982*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr;
3983*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = CRd;
3984*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = cop;
3985*9880d681SAndroid Build Coastguard Worker    let Inst{7-0} = offset{7-0};
3986*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeCopMemInstruction";
3987*9880d681SAndroid Build Coastguard Worker  }
3988*9880d681SAndroid Build Coastguard Worker  def _OPTION : T2CI<op31_28, (outs),
3989*9880d681SAndroid Build Coastguard Worker                     (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr,
3990*9880d681SAndroid Build Coastguard Worker                          coproc_option_imm:$option),
3991*9880d681SAndroid Build Coastguard Worker      asm, "\t$cop, $CRd, $addr, $option", []> {
3992*9880d681SAndroid Build Coastguard Worker    bits<8> option;
3993*9880d681SAndroid Build Coastguard Worker    bits<4> addr;
3994*9880d681SAndroid Build Coastguard Worker    bits<4> cop;
3995*9880d681SAndroid Build Coastguard Worker    bits<4> CRd;
3996*9880d681SAndroid Build Coastguard Worker    let Inst{24} = 0; // P = 0
3997*9880d681SAndroid Build Coastguard Worker    let Inst{23} = 1; // U = 1
3998*9880d681SAndroid Build Coastguard Worker    let Inst{22} = Dbit;
3999*9880d681SAndroid Build Coastguard Worker    let Inst{21} = 0; // W = 0
4000*9880d681SAndroid Build Coastguard Worker    let Inst{20} = load;
4001*9880d681SAndroid Build Coastguard Worker    let Inst{19-16} = addr;
4002*9880d681SAndroid Build Coastguard Worker    let Inst{15-12} = CRd;
4003*9880d681SAndroid Build Coastguard Worker    let Inst{11-8} = cop;
4004*9880d681SAndroid Build Coastguard Worker    let Inst{7-0} = option;
4005*9880d681SAndroid Build Coastguard Worker    let DecoderMethod = "DecodeCopMemInstruction";
4006*9880d681SAndroid Build Coastguard Worker  }
4007*9880d681SAndroid Build Coastguard Worker}
4008*9880d681SAndroid Build Coastguard Worker
4009*9880d681SAndroid Build Coastguard Workerdefm t2LDC   : t2LdStCop<0b1110, 1, 0, "ldc", [(int_arm_ldc imm:$cop, imm:$CRd, addrmode5:$addr)]>;
4010*9880d681SAndroid Build Coastguard Workerdefm t2LDCL  : t2LdStCop<0b1110, 1, 1, "ldcl", [(int_arm_ldcl imm:$cop, imm:$CRd, addrmode5:$addr)]>;
4011*9880d681SAndroid Build Coastguard Workerdefm t2LDC2  : t2LdStCop<0b1111, 1, 0, "ldc2", [(int_arm_ldc2 imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[PreV8,IsThumb2]>;
4012*9880d681SAndroid Build Coastguard Workerdefm t2LDC2L : t2LdStCop<0b1111, 1, 1, "ldc2l", [(int_arm_ldc2l imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[PreV8,IsThumb2]>;
4013*9880d681SAndroid Build Coastguard Worker
4014*9880d681SAndroid Build Coastguard Workerdefm t2STC   : t2LdStCop<0b1110, 0, 0, "stc", [(int_arm_stc imm:$cop, imm:$CRd, addrmode5:$addr)]>;
4015*9880d681SAndroid Build Coastguard Workerdefm t2STCL  : t2LdStCop<0b1110, 0, 1, "stcl", [(int_arm_stcl imm:$cop, imm:$CRd, addrmode5:$addr)]>;
4016*9880d681SAndroid Build Coastguard Workerdefm t2STC2  : t2LdStCop<0b1111, 0, 0, "stc2", [(int_arm_stc2 imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[PreV8,IsThumb2]>;
4017*9880d681SAndroid Build Coastguard Workerdefm t2STC2L : t2LdStCop<0b1111, 0, 1, "stc2l", [(int_arm_stc2l imm:$cop, imm:$CRd, addrmode5:$addr)]>, Requires<[PreV8,IsThumb2]>;
4018*9880d681SAndroid Build Coastguard Worker
4019*9880d681SAndroid Build Coastguard Worker
4020*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4021*9880d681SAndroid Build Coastguard Worker// Move between special register and ARM core register -- for disassembly only
4022*9880d681SAndroid Build Coastguard Worker//
4023*9880d681SAndroid Build Coastguard Worker// Move to ARM core register from Special Register
4024*9880d681SAndroid Build Coastguard Worker
4025*9880d681SAndroid Build Coastguard Worker// A/R class MRS.
4026*9880d681SAndroid Build Coastguard Worker//
4027*9880d681SAndroid Build Coastguard Worker// A/R class can only move from CPSR or SPSR.
4028*9880d681SAndroid Build Coastguard Workerdef t2MRS_AR : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr",
4029*9880d681SAndroid Build Coastguard Worker                  []>, Requires<[IsThumb2,IsNotMClass]> {
4030*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
4031*9880d681SAndroid Build Coastguard Worker  let Inst{31-12} = 0b11110011111011111000;
4032*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rd;
4033*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = 0b00000000;
4034*9880d681SAndroid Build Coastguard Worker}
4035*9880d681SAndroid Build Coastguard Worker
4036*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS_AR GPR:$Rd, pred:$p)>;
4037*9880d681SAndroid Build Coastguard Worker
4038*9880d681SAndroid Build Coastguard Workerdef t2MRSsys_AR: T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
4039*9880d681SAndroid Build Coastguard Worker                   []>, Requires<[IsThumb2,IsNotMClass]> {
4040*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
4041*9880d681SAndroid Build Coastguard Worker  let Inst{31-12} = 0b11110011111111111000;
4042*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rd;
4043*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = 0b00000000;
4044*9880d681SAndroid Build Coastguard Worker}
4045*9880d681SAndroid Build Coastguard Worker
4046*9880d681SAndroid Build Coastguard Workerdef t2MRSbanked : T2I<(outs rGPR:$Rd), (ins banked_reg:$banked),
4047*9880d681SAndroid Build Coastguard Worker                      NoItinerary, "mrs", "\t$Rd, $banked", []>,
4048*9880d681SAndroid Build Coastguard Worker                  Requires<[IsThumb, HasVirtualization]> {
4049*9880d681SAndroid Build Coastguard Worker  bits<6> banked;
4050*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
4051*9880d681SAndroid Build Coastguard Worker
4052*9880d681SAndroid Build Coastguard Worker  let Inst{31-21} = 0b11110011111;
4053*9880d681SAndroid Build Coastguard Worker  let Inst{20} = banked{5}; // R bit
4054*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = banked{3-0};
4055*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
4056*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rd;
4057*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = 0b001;
4058*9880d681SAndroid Build Coastguard Worker  let Inst{4} = banked{4};
4059*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b0000;
4060*9880d681SAndroid Build Coastguard Worker}
4061*9880d681SAndroid Build Coastguard Worker
4062*9880d681SAndroid Build Coastguard Worker
4063*9880d681SAndroid Build Coastguard Worker// M class MRS.
4064*9880d681SAndroid Build Coastguard Worker//
4065*9880d681SAndroid Build Coastguard Worker// This MRS has a mask field in bits 7-0 and can take more values than
4066*9880d681SAndroid Build Coastguard Worker// the A/R class (a full msr_mask).
4067*9880d681SAndroid Build Coastguard Workerdef t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$SYSm), NoItinerary,
4068*9880d681SAndroid Build Coastguard Worker                  "mrs", "\t$Rd, $SYSm", []>,
4069*9880d681SAndroid Build Coastguard Worker              Requires<[IsThumb,IsMClass]> {
4070*9880d681SAndroid Build Coastguard Worker  bits<4> Rd;
4071*9880d681SAndroid Build Coastguard Worker  bits<8> SYSm;
4072*9880d681SAndroid Build Coastguard Worker  let Inst{31-12} = 0b11110011111011111000;
4073*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rd;
4074*9880d681SAndroid Build Coastguard Worker  let Inst{7-0} = SYSm;
4075*9880d681SAndroid Build Coastguard Worker
4076*9880d681SAndroid Build Coastguard Worker  let Unpredictable{20-16} = 0b11111;
4077*9880d681SAndroid Build Coastguard Worker  let Unpredictable{13} = 0b1;
4078*9880d681SAndroid Build Coastguard Worker}
4079*9880d681SAndroid Build Coastguard Worker
4080*9880d681SAndroid Build Coastguard Worker
4081*9880d681SAndroid Build Coastguard Worker// Move from ARM core register to Special Register
4082*9880d681SAndroid Build Coastguard Worker//
4083*9880d681SAndroid Build Coastguard Worker// A/R class MSR.
4084*9880d681SAndroid Build Coastguard Worker//
4085*9880d681SAndroid Build Coastguard Worker// No need to have both system and application versions, the encodings are the
4086*9880d681SAndroid Build Coastguard Worker// same and the assembly parser has no way to distinguish between them. The mask
4087*9880d681SAndroid Build Coastguard Worker// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
4088*9880d681SAndroid Build Coastguard Worker// the mask with the fields to be accessed in the special register.
4089*9880d681SAndroid Build Coastguard Workerlet Defs = [CPSR] in
4090*9880d681SAndroid Build Coastguard Workerdef t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
4091*9880d681SAndroid Build Coastguard Worker                   NoItinerary, "msr", "\t$mask, $Rn", []>,
4092*9880d681SAndroid Build Coastguard Worker               Requires<[IsThumb2,IsNotMClass]> {
4093*9880d681SAndroid Build Coastguard Worker  bits<5> mask;
4094*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
4095*9880d681SAndroid Build Coastguard Worker  let Inst{31-21} = 0b11110011100;
4096*9880d681SAndroid Build Coastguard Worker  let Inst{20}    = mask{4}; // R Bit
4097*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
4098*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
4099*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = mask{3-0};
4100*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = 0;
4101*9880d681SAndroid Build Coastguard Worker}
4102*9880d681SAndroid Build Coastguard Worker
4103*9880d681SAndroid Build Coastguard Worker// However, the MSR (banked register) system instruction (ARMv7VE) *does* have a
4104*9880d681SAndroid Build Coastguard Worker// separate encoding (distinguished by bit 5.
4105*9880d681SAndroid Build Coastguard Workerdef t2MSRbanked : T2I<(outs), (ins banked_reg:$banked, rGPR:$Rn),
4106*9880d681SAndroid Build Coastguard Worker                      NoItinerary, "msr", "\t$banked, $Rn", []>,
4107*9880d681SAndroid Build Coastguard Worker                  Requires<[IsThumb, HasVirtualization]> {
4108*9880d681SAndroid Build Coastguard Worker  bits<6> banked;
4109*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
4110*9880d681SAndroid Build Coastguard Worker
4111*9880d681SAndroid Build Coastguard Worker  let Inst{31-21} = 0b11110011100;
4112*9880d681SAndroid Build Coastguard Worker  let Inst{20} = banked{5}; // R bit
4113*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
4114*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
4115*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = banked{3-0};
4116*9880d681SAndroid Build Coastguard Worker  let Inst{7-5} = 0b001;
4117*9880d681SAndroid Build Coastguard Worker  let Inst{4} = banked{4};
4118*9880d681SAndroid Build Coastguard Worker  let Inst{3-0} = 0b0000;
4119*9880d681SAndroid Build Coastguard Worker}
4120*9880d681SAndroid Build Coastguard Worker
4121*9880d681SAndroid Build Coastguard Worker
4122*9880d681SAndroid Build Coastguard Worker// M class MSR.
4123*9880d681SAndroid Build Coastguard Worker//
4124*9880d681SAndroid Build Coastguard Worker// Move from ARM core register to Special Register
4125*9880d681SAndroid Build Coastguard Workerlet Defs = [CPSR] in
4126*9880d681SAndroid Build Coastguard Workerdef t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
4127*9880d681SAndroid Build Coastguard Worker                  NoItinerary, "msr", "\t$SYSm, $Rn", []>,
4128*9880d681SAndroid Build Coastguard Worker              Requires<[IsThumb,IsMClass]> {
4129*9880d681SAndroid Build Coastguard Worker  bits<12> SYSm;
4130*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
4131*9880d681SAndroid Build Coastguard Worker  let Inst{31-21} = 0b11110011100;
4132*9880d681SAndroid Build Coastguard Worker  let Inst{20}    = 0b0;
4133*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
4134*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1000;
4135*9880d681SAndroid Build Coastguard Worker  let Inst{11-10} = SYSm{11-10};
4136*9880d681SAndroid Build Coastguard Worker  let Inst{9-8}   = 0b00;
4137*9880d681SAndroid Build Coastguard Worker  let Inst{7-0}   = SYSm{7-0};
4138*9880d681SAndroid Build Coastguard Worker
4139*9880d681SAndroid Build Coastguard Worker  let Unpredictable{20} = 0b1;
4140*9880d681SAndroid Build Coastguard Worker  let Unpredictable{13} = 0b1;
4141*9880d681SAndroid Build Coastguard Worker  let Unpredictable{9-8} = 0b11;
4142*9880d681SAndroid Build Coastguard Worker}
4143*9880d681SAndroid Build Coastguard Worker
4144*9880d681SAndroid Build Coastguard Worker
4145*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4146*9880d681SAndroid Build Coastguard Worker// Move between coprocessor and ARM core register
4147*9880d681SAndroid Build Coastguard Worker//
4148*9880d681SAndroid Build Coastguard Worker
4149*9880d681SAndroid Build Coastguard Workerclass t2MovRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops,
4150*9880d681SAndroid Build Coastguard Worker                  list<dag> pattern>
4151*9880d681SAndroid Build Coastguard Worker  : T2Cop<Op, oops, iops, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
4152*9880d681SAndroid Build Coastguard Worker          pattern> {
4153*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1110;
4154*9880d681SAndroid Build Coastguard Worker  let Inst{20} = direction;
4155*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 1;
4156*9880d681SAndroid Build Coastguard Worker
4157*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
4158*9880d681SAndroid Build Coastguard Worker  bits<4> cop;
4159*9880d681SAndroid Build Coastguard Worker  bits<3> opc1;
4160*9880d681SAndroid Build Coastguard Worker  bits<3> opc2;
4161*9880d681SAndroid Build Coastguard Worker  bits<4> CRm;
4162*9880d681SAndroid Build Coastguard Worker  bits<4> CRn;
4163*9880d681SAndroid Build Coastguard Worker
4164*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
4165*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = cop;
4166*9880d681SAndroid Build Coastguard Worker  let Inst{23-21} = opc1;
4167*9880d681SAndroid Build Coastguard Worker  let Inst{7-5}   = opc2;
4168*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = CRm;
4169*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = CRn;
4170*9880d681SAndroid Build Coastguard Worker}
4171*9880d681SAndroid Build Coastguard Worker
4172*9880d681SAndroid Build Coastguard Workerclass t2MovRRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops,
4173*9880d681SAndroid Build Coastguard Worker                   list<dag> pattern = []>
4174*9880d681SAndroid Build Coastguard Worker  : T2Cop<Op, oops, iops, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> {
4175*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1100;
4176*9880d681SAndroid Build Coastguard Worker  let Inst{23-21} = 0b010;
4177*9880d681SAndroid Build Coastguard Worker  let Inst{20} = direction;
4178*9880d681SAndroid Build Coastguard Worker
4179*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
4180*9880d681SAndroid Build Coastguard Worker  bits<4> Rt2;
4181*9880d681SAndroid Build Coastguard Worker  bits<4> cop;
4182*9880d681SAndroid Build Coastguard Worker  bits<4> opc1;
4183*9880d681SAndroid Build Coastguard Worker  bits<4> CRm;
4184*9880d681SAndroid Build Coastguard Worker
4185*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = Rt;
4186*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rt2;
4187*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = cop;
4188*9880d681SAndroid Build Coastguard Worker  let Inst{7-4}   = opc1;
4189*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = CRm;
4190*9880d681SAndroid Build Coastguard Worker}
4191*9880d681SAndroid Build Coastguard Worker
4192*9880d681SAndroid Build Coastguard Worker/* from ARM core register to coprocessor */
4193*9880d681SAndroid Build Coastguard Workerdef t2MCR : t2MovRCopro<0b1110, "mcr", 0,
4194*9880d681SAndroid Build Coastguard Worker           (outs),
4195*9880d681SAndroid Build Coastguard Worker           (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4196*9880d681SAndroid Build Coastguard Worker                c_imm:$CRm, imm0_7:$opc2),
4197*9880d681SAndroid Build Coastguard Worker           [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4198*9880d681SAndroid Build Coastguard Worker                         imm:$CRm, imm:$opc2)]>,
4199*9880d681SAndroid Build Coastguard Worker           ComplexDeprecationPredicate<"MCR">;
4200*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
4201*9880d681SAndroid Build Coastguard Worker                  (t2MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4202*9880d681SAndroid Build Coastguard Worker                         c_imm:$CRm, 0, pred:$p)>;
4203*9880d681SAndroid Build Coastguard Workerdef t2MCR2 : t2MovRCopro<0b1111, "mcr2", 0,
4204*9880d681SAndroid Build Coastguard Worker             (outs), (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4205*9880d681SAndroid Build Coastguard Worker                          c_imm:$CRm, imm0_7:$opc2),
4206*9880d681SAndroid Build Coastguard Worker             [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
4207*9880d681SAndroid Build Coastguard Worker                            imm:$CRm, imm:$opc2)]> {
4208*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4209*9880d681SAndroid Build Coastguard Worker}
4210*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mcr2${p} $cop, $opc1, $Rt, $CRn, $CRm",
4211*9880d681SAndroid Build Coastguard Worker                  (t2MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
4212*9880d681SAndroid Build Coastguard Worker                          c_imm:$CRm, 0, pred:$p)>;
4213*9880d681SAndroid Build Coastguard Worker
4214*9880d681SAndroid Build Coastguard Worker/* from coprocessor to ARM core register */
4215*9880d681SAndroid Build Coastguard Workerdef t2MRC : t2MovRCopro<0b1110, "mrc", 1,
4216*9880d681SAndroid Build Coastguard Worker             (outs GPRwithAPSR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4217*9880d681SAndroid Build Coastguard Worker                                  c_imm:$CRm, imm0_7:$opc2), []>;
4218*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm",
4219*9880d681SAndroid Build Coastguard Worker                  (t2MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4220*9880d681SAndroid Build Coastguard Worker                         c_imm:$CRm, 0, pred:$p)>;
4221*9880d681SAndroid Build Coastguard Worker
4222*9880d681SAndroid Build Coastguard Workerdef t2MRC2 : t2MovRCopro<0b1111, "mrc2", 1,
4223*9880d681SAndroid Build Coastguard Worker             (outs GPRwithAPSR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4224*9880d681SAndroid Build Coastguard Worker                                  c_imm:$CRm, imm0_7:$opc2), []> {
4225*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4226*9880d681SAndroid Build Coastguard Worker}
4227*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mrc2${p} $cop, $opc1, $Rt, $CRn, $CRm",
4228*9880d681SAndroid Build Coastguard Worker                  (t2MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
4229*9880d681SAndroid Build Coastguard Worker                          c_imm:$CRm, 0, pred:$p)>;
4230*9880d681SAndroid Build Coastguard Worker
4231*9880d681SAndroid Build Coastguard Workerdef : T2v6Pat<(int_arm_mrc  imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
4232*9880d681SAndroid Build Coastguard Worker              (t2MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4233*9880d681SAndroid Build Coastguard Worker
4234*9880d681SAndroid Build Coastguard Workerdef : T2v6Pat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
4235*9880d681SAndroid Build Coastguard Worker              (t2MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
4236*9880d681SAndroid Build Coastguard Worker
4237*9880d681SAndroid Build Coastguard Worker
4238*9880d681SAndroid Build Coastguard Worker/* from ARM core register to coprocessor */
4239*9880d681SAndroid Build Coastguard Workerdef t2MCRR : t2MovRRCopro<0b1110, "mcrr", 0, (outs),
4240*9880d681SAndroid Build Coastguard Worker                         (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2,
4241*9880d681SAndroid Build Coastguard Worker                         c_imm:$CRm),
4242*9880d681SAndroid Build Coastguard Worker                        [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2,
4243*9880d681SAndroid Build Coastguard Worker                                       imm:$CRm)]>;
4244*9880d681SAndroid Build Coastguard Workerdef t2MCRR2 : t2MovRRCopro<0b1111, "mcrr2", 0, (outs),
4245*9880d681SAndroid Build Coastguard Worker                          (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2,
4246*9880d681SAndroid Build Coastguard Worker                           c_imm:$CRm),
4247*9880d681SAndroid Build Coastguard Worker                          [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt,
4248*9880d681SAndroid Build Coastguard Worker                                          GPR:$Rt2, imm:$CRm)]> {
4249*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4250*9880d681SAndroid Build Coastguard Worker}
4251*9880d681SAndroid Build Coastguard Worker
4252*9880d681SAndroid Build Coastguard Worker/* from coprocessor to ARM core register */
4253*9880d681SAndroid Build Coastguard Workerdef t2MRRC : t2MovRRCopro<0b1110, "mrrc", 1, (outs GPR:$Rt, GPR:$Rt2),
4254*9880d681SAndroid Build Coastguard Worker                          (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm)>;
4255*9880d681SAndroid Build Coastguard Worker
4256*9880d681SAndroid Build Coastguard Workerdef t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1, (outs GPR:$Rt, GPR:$Rt2),
4257*9880d681SAndroid Build Coastguard Worker                           (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm)> {
4258*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4259*9880d681SAndroid Build Coastguard Worker}
4260*9880d681SAndroid Build Coastguard Worker
4261*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4262*9880d681SAndroid Build Coastguard Worker// Other Coprocessor Instructions.
4263*9880d681SAndroid Build Coastguard Worker//
4264*9880d681SAndroid Build Coastguard Worker
4265*9880d681SAndroid Build Coastguard Workerdef t2CDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4266*9880d681SAndroid Build Coastguard Worker                 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4267*9880d681SAndroid Build Coastguard Worker                 "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4268*9880d681SAndroid Build Coastguard Worker                 [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4269*9880d681SAndroid Build Coastguard Worker                               imm:$CRm, imm:$opc2)]> {
4270*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1110;
4271*9880d681SAndroid Build Coastguard Worker
4272*9880d681SAndroid Build Coastguard Worker  bits<4> opc1;
4273*9880d681SAndroid Build Coastguard Worker  bits<4> CRn;
4274*9880d681SAndroid Build Coastguard Worker  bits<4> CRd;
4275*9880d681SAndroid Build Coastguard Worker  bits<4> cop;
4276*9880d681SAndroid Build Coastguard Worker  bits<3> opc2;
4277*9880d681SAndroid Build Coastguard Worker  bits<4> CRm;
4278*9880d681SAndroid Build Coastguard Worker
4279*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = CRm;
4280*9880d681SAndroid Build Coastguard Worker  let Inst{4}     = 0;
4281*9880d681SAndroid Build Coastguard Worker  let Inst{7-5}   = opc2;
4282*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = cop;
4283*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = CRd;
4284*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = CRn;
4285*9880d681SAndroid Build Coastguard Worker  let Inst{23-20} = opc1;
4286*9880d681SAndroid Build Coastguard Worker
4287*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4288*9880d681SAndroid Build Coastguard Worker}
4289*9880d681SAndroid Build Coastguard Worker
4290*9880d681SAndroid Build Coastguard Workerdef t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1,
4291*9880d681SAndroid Build Coastguard Worker                   c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
4292*9880d681SAndroid Build Coastguard Worker                   "cdp2", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
4293*9880d681SAndroid Build Coastguard Worker                   [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
4294*9880d681SAndroid Build Coastguard Worker                                  imm:$CRm, imm:$opc2)]> {
4295*9880d681SAndroid Build Coastguard Worker  let Inst{27-24} = 0b1110;
4296*9880d681SAndroid Build Coastguard Worker
4297*9880d681SAndroid Build Coastguard Worker  bits<4> opc1;
4298*9880d681SAndroid Build Coastguard Worker  bits<4> CRn;
4299*9880d681SAndroid Build Coastguard Worker  bits<4> CRd;
4300*9880d681SAndroid Build Coastguard Worker  bits<4> cop;
4301*9880d681SAndroid Build Coastguard Worker  bits<3> opc2;
4302*9880d681SAndroid Build Coastguard Worker  bits<4> CRm;
4303*9880d681SAndroid Build Coastguard Worker
4304*9880d681SAndroid Build Coastguard Worker  let Inst{3-0}   = CRm;
4305*9880d681SAndroid Build Coastguard Worker  let Inst{4}     = 0;
4306*9880d681SAndroid Build Coastguard Worker  let Inst{7-5}   = opc2;
4307*9880d681SAndroid Build Coastguard Worker  let Inst{11-8}  = cop;
4308*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = CRd;
4309*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = CRn;
4310*9880d681SAndroid Build Coastguard Worker  let Inst{23-20} = opc1;
4311*9880d681SAndroid Build Coastguard Worker
4312*9880d681SAndroid Build Coastguard Worker  let Predicates = [IsThumb2, PreV8];
4313*9880d681SAndroid Build Coastguard Worker}
4314*9880d681SAndroid Build Coastguard Worker
4315*9880d681SAndroid Build Coastguard Worker
4316*9880d681SAndroid Build Coastguard Worker
4317*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4318*9880d681SAndroid Build Coastguard Worker// ARMv8.1 Privilege Access Never extension
4319*9880d681SAndroid Build Coastguard Worker//
4320*9880d681SAndroid Build Coastguard Worker// SETPAN #imm1
4321*9880d681SAndroid Build Coastguard Worker
4322*9880d681SAndroid Build Coastguard Workerdef t2SETPAN : T1I<(outs), (ins imm0_1:$imm), NoItinerary, "setpan\t$imm", []>,
4323*9880d681SAndroid Build Coastguard Worker               T1Misc<0b0110000>, Requires<[IsThumb2, HasV8, HasV8_1a]> {
4324*9880d681SAndroid Build Coastguard Worker  bits<1> imm;
4325*9880d681SAndroid Build Coastguard Worker
4326*9880d681SAndroid Build Coastguard Worker  let Inst{4} = 0b1;
4327*9880d681SAndroid Build Coastguard Worker  let Inst{3} = imm;
4328*9880d681SAndroid Build Coastguard Worker  let Inst{2-0} = 0b000;
4329*9880d681SAndroid Build Coastguard Worker
4330*9880d681SAndroid Build Coastguard Worker  let Unpredictable{4} = 0b1;
4331*9880d681SAndroid Build Coastguard Worker  let Unpredictable{2-0} = 0b111;
4332*9880d681SAndroid Build Coastguard Worker}
4333*9880d681SAndroid Build Coastguard Worker
4334*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4335*9880d681SAndroid Build Coastguard Worker// ARMv8-M Security Extensions instructions
4336*9880d681SAndroid Build Coastguard Worker//
4337*9880d681SAndroid Build Coastguard Worker
4338*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1 in
4339*9880d681SAndroid Build Coastguard Workerdef t2SG : T2I<(outs), (ins), NoItinerary, "sg", "", []>,
4340*9880d681SAndroid Build Coastguard Worker           Requires<[Has8MSecExt]> {
4341*9880d681SAndroid Build Coastguard Worker  let Inst = 0xe97fe97f;
4342*9880d681SAndroid Build Coastguard Worker}
4343*9880d681SAndroid Build Coastguard Worker
4344*9880d681SAndroid Build Coastguard Workerclass T2TT<bits<2> at, string asm, list<dag> pattern>
4345*9880d681SAndroid Build Coastguard Worker  : T2I<(outs rGPR:$Rt), (ins GPRnopc:$Rn), NoItinerary, asm, "\t$Rt, $Rn",
4346*9880d681SAndroid Build Coastguard Worker        pattern> {
4347*9880d681SAndroid Build Coastguard Worker  bits<4> Rn;
4348*9880d681SAndroid Build Coastguard Worker  bits<4> Rt;
4349*9880d681SAndroid Build Coastguard Worker
4350*9880d681SAndroid Build Coastguard Worker  let Inst{31-20} = 0b111010000100;
4351*9880d681SAndroid Build Coastguard Worker  let Inst{19-16} = Rn;
4352*9880d681SAndroid Build Coastguard Worker  let Inst{15-12} = 0b1111;
4353*9880d681SAndroid Build Coastguard Worker  let Inst{11-8} = Rt;
4354*9880d681SAndroid Build Coastguard Worker  let Inst{7-6} = at;
4355*9880d681SAndroid Build Coastguard Worker  let Inst{5-0} = 0b000000;
4356*9880d681SAndroid Build Coastguard Worker
4357*9880d681SAndroid Build Coastguard Worker  let Unpredictable{5-0} = 0b111111;
4358*9880d681SAndroid Build Coastguard Worker}
4359*9880d681SAndroid Build Coastguard Worker
4360*9880d681SAndroid Build Coastguard Workerdef t2TT   : T2TT<0b00, "tt",   []>, Requires<[IsThumb,Has8MSecExt]>;
4361*9880d681SAndroid Build Coastguard Workerdef t2TTT  : T2TT<0b01, "ttt",  []>, Requires<[IsThumb,Has8MSecExt]>;
4362*9880d681SAndroid Build Coastguard Workerdef t2TTA  : T2TT<0b10, "tta",  []>, Requires<[IsThumb,Has8MSecExt]>;
4363*9880d681SAndroid Build Coastguard Workerdef t2TTAT : T2TT<0b11, "ttat", []>, Requires<[IsThumb,Has8MSecExt]>;
4364*9880d681SAndroid Build Coastguard Worker
4365*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4366*9880d681SAndroid Build Coastguard Worker// Non-Instruction Patterns
4367*9880d681SAndroid Build Coastguard Worker//
4368*9880d681SAndroid Build Coastguard Worker
4369*9880d681SAndroid Build Coastguard Worker// SXT/UXT with no rotate
4370*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 16 in {
4371*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and rGPR:$Rm, 0x000000FF), (t2UXTB rGPR:$Rm, 0)>,
4372*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2]>;
4373*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and rGPR:$Rm, 0x0000FFFF), (t2UXTH rGPR:$Rm, 0)>,
4374*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2]>;
4375*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(and rGPR:$Rm, 0x00FF00FF), (t2UXTB16 rGPR:$Rm, 0)>,
4376*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]>;
4377*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0x00FF)),
4378*9880d681SAndroid Build Coastguard Worker            (t2UXTAB rGPR:$Rn, rGPR:$Rm, 0)>,
4379*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]>;
4380*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0xFFFF)),
4381*9880d681SAndroid Build Coastguard Worker            (t2UXTAH rGPR:$Rn, rGPR:$Rm, 0)>,
4382*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]>;
4383*9880d681SAndroid Build Coastguard Worker}
4384*9880d681SAndroid Build Coastguard Worker
4385*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(sext_inreg rGPR:$Src, i8),  (t2SXTB rGPR:$Src, 0)>,
4386*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2]>;
4387*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(sext_inreg rGPR:$Src, i16), (t2SXTH rGPR:$Src, 0)>,
4388*9880d681SAndroid Build Coastguard Worker           Requires<[IsThumb2]>;
4389*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i8)),
4390*9880d681SAndroid Build Coastguard Worker            (t2SXTAB rGPR:$Rn, rGPR:$Rm, 0)>,
4391*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]>;
4392*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)),
4393*9880d681SAndroid Build Coastguard Worker            (t2SXTAH rGPR:$Rn, rGPR:$Rm, 0)>,
4394*9880d681SAndroid Build Coastguard Worker           Requires<[HasT2ExtractPack, IsThumb2]>;
4395*9880d681SAndroid Build Coastguard Worker
4396*9880d681SAndroid Build Coastguard Worker// Atomic load/store patterns
4397*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_8   t2addrmode_imm12:$addr),
4398*9880d681SAndroid Build Coastguard Worker            (t2LDRBi12  t2addrmode_imm12:$addr)>;
4399*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_8   t2addrmode_negimm8:$addr),
4400*9880d681SAndroid Build Coastguard Worker            (t2LDRBi8   t2addrmode_negimm8:$addr)>;
4401*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_8   t2addrmode_so_reg:$addr),
4402*9880d681SAndroid Build Coastguard Worker            (t2LDRBs    t2addrmode_so_reg:$addr)>;
4403*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_16  t2addrmode_imm12:$addr),
4404*9880d681SAndroid Build Coastguard Worker            (t2LDRHi12  t2addrmode_imm12:$addr)>;
4405*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_16  t2addrmode_negimm8:$addr),
4406*9880d681SAndroid Build Coastguard Worker            (t2LDRHi8   t2addrmode_negimm8:$addr)>;
4407*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_16  t2addrmode_so_reg:$addr),
4408*9880d681SAndroid Build Coastguard Worker            (t2LDRHs    t2addrmode_so_reg:$addr)>;
4409*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_32  t2addrmode_imm12:$addr),
4410*9880d681SAndroid Build Coastguard Worker            (t2LDRi12   t2addrmode_imm12:$addr)>;
4411*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_32  t2addrmode_negimm8:$addr),
4412*9880d681SAndroid Build Coastguard Worker            (t2LDRi8    t2addrmode_negimm8:$addr)>;
4413*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_load_32  t2addrmode_so_reg:$addr),
4414*9880d681SAndroid Build Coastguard Worker            (t2LDRs     t2addrmode_so_reg:$addr)>;
4415*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_8  t2addrmode_imm12:$addr, GPR:$val),
4416*9880d681SAndroid Build Coastguard Worker            (t2STRBi12  GPR:$val, t2addrmode_imm12:$addr)>;
4417*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_8  t2addrmode_negimm8:$addr, GPR:$val),
4418*9880d681SAndroid Build Coastguard Worker            (t2STRBi8   GPR:$val, t2addrmode_negimm8:$addr)>;
4419*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_8  t2addrmode_so_reg:$addr, GPR:$val),
4420*9880d681SAndroid Build Coastguard Worker            (t2STRBs    GPR:$val, t2addrmode_so_reg:$addr)>;
4421*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_16 t2addrmode_imm12:$addr, GPR:$val),
4422*9880d681SAndroid Build Coastguard Worker            (t2STRHi12  GPR:$val, t2addrmode_imm12:$addr)>;
4423*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_16 t2addrmode_negimm8:$addr, GPR:$val),
4424*9880d681SAndroid Build Coastguard Worker            (t2STRHi8   GPR:$val, t2addrmode_negimm8:$addr)>;
4425*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_16 t2addrmode_so_reg:$addr, GPR:$val),
4426*9880d681SAndroid Build Coastguard Worker            (t2STRHs    GPR:$val, t2addrmode_so_reg:$addr)>;
4427*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_32 t2addrmode_imm12:$addr, GPR:$val),
4428*9880d681SAndroid Build Coastguard Worker            (t2STRi12   GPR:$val, t2addrmode_imm12:$addr)>;
4429*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_32 t2addrmode_negimm8:$addr, GPR:$val),
4430*9880d681SAndroid Build Coastguard Worker            (t2STRi8    GPR:$val, t2addrmode_negimm8:$addr)>;
4431*9880d681SAndroid Build Coastguard Workerdef : T2Pat<(atomic_store_32 t2addrmode_so_reg:$addr, GPR:$val),
4432*9880d681SAndroid Build Coastguard Worker            (t2STRs     GPR:$val, t2addrmode_so_reg:$addr)>;
4433*9880d681SAndroid Build Coastguard Worker
4434*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 8 in {
4435*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_load_acquire_8 addr_offset_none:$addr),  (t2LDAB addr_offset_none:$addr)>;
4436*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_load_acquire_16 addr_offset_none:$addr), (t2LDAH addr_offset_none:$addr)>;
4437*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_load_acquire_32 addr_offset_none:$addr), (t2LDA  addr_offset_none:$addr)>;
4438*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val),  (t2STLB GPR:$val, addr_offset_none:$addr)>;
4439*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (t2STLH GPR:$val, addr_offset_none:$addr)>;
4440*9880d681SAndroid Build Coastguard Worker  def : T2Pat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (t2STL  GPR:$val, addr_offset_none:$addr)>;
4441*9880d681SAndroid Build Coastguard Worker}
4442*9880d681SAndroid Build Coastguard Worker
4443*9880d681SAndroid Build Coastguard Worker
4444*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
4445*9880d681SAndroid Build Coastguard Worker// Assembler aliases
4446*9880d681SAndroid Build Coastguard Worker//
4447*9880d681SAndroid Build Coastguard Worker
4448*9880d681SAndroid Build Coastguard Worker// Aliases for ADC without the ".w" optional width specifier.
4449*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"adc${s}${p} $Rd, $Rn, $Rm",
4450*9880d681SAndroid Build Coastguard Worker                  (t2ADCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4451*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"adc${s}${p} $Rd, $Rn, $ShiftedRm",
4452*9880d681SAndroid Build Coastguard Worker                  (t2ADCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm,
4453*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4454*9880d681SAndroid Build Coastguard Worker
4455*9880d681SAndroid Build Coastguard Worker// Aliases for SBC without the ".w" optional width specifier.
4456*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $Rm",
4457*9880d681SAndroid Build Coastguard Worker                  (t2SBCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4458*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $ShiftedRm",
4459*9880d681SAndroid Build Coastguard Worker                  (t2SBCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm,
4460*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4461*9880d681SAndroid Build Coastguard Worker
4462*9880d681SAndroid Build Coastguard Worker// Aliases for ADD without the ".w" optional width specifier.
4463*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4464*9880d681SAndroid Build Coastguard Worker        (t2ADDri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p,
4465*9880d681SAndroid Build Coastguard Worker         cc_out:$s)>;
4466*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${p} $Rd, $Rn, $imm",
4467*9880d681SAndroid Build Coastguard Worker           (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
4468*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $Rm",
4469*9880d681SAndroid Build Coastguard Worker              (t2ADDrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4470*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm",
4471*9880d681SAndroid Build Coastguard Worker                  (t2ADDrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm,
4472*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4473*9880d681SAndroid Build Coastguard Worker// ... and with the destination and source register combined.
4474*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rdn, $imm",
4475*9880d681SAndroid Build Coastguard Worker      (t2ADDri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4476*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${p} $Rdn, $imm",
4477*9880d681SAndroid Build Coastguard Worker           (t2ADDri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
4478*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rdn, $Rm",
4479*9880d681SAndroid Build Coastguard Worker            (t2ADDrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4480*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm",
4481*9880d681SAndroid Build Coastguard Worker                  (t2ADDrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm,
4482*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4483*9880d681SAndroid Build Coastguard Worker
4484*9880d681SAndroid Build Coastguard Worker// add w/ negative immediates is just a sub.
4485*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4486*9880d681SAndroid Build Coastguard Worker        (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
4487*9880d681SAndroid Build Coastguard Worker                 cc_out:$s)>;
4488*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${p} $Rd, $Rn, $imm",
4489*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4490*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rdn, $imm",
4491*9880d681SAndroid Build Coastguard Worker      (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4492*9880d681SAndroid Build Coastguard Worker               cc_out:$s)>;
4493*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${p} $Rdn, $imm",
4494*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4495*9880d681SAndroid Build Coastguard Worker
4496*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p}.w $Rd, $Rn, $imm",
4497*9880d681SAndroid Build Coastguard Worker        (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
4498*9880d681SAndroid Build Coastguard Worker                 cc_out:$s)>;
4499*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"addw${p} $Rd, $Rn, $imm",
4500*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4501*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p}.w $Rdn, $imm",
4502*9880d681SAndroid Build Coastguard Worker      (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4503*9880d681SAndroid Build Coastguard Worker               cc_out:$s)>;
4504*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"addw${p} $Rdn, $imm",
4505*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4506*9880d681SAndroid Build Coastguard Worker
4507*9880d681SAndroid Build Coastguard Worker
4508*9880d681SAndroid Build Coastguard Worker// Aliases for SUB without the ".w" optional width specifier.
4509*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm",
4510*9880d681SAndroid Build Coastguard Worker        (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4511*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${p} $Rd, $Rn, $imm",
4512*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
4513*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm",
4514*9880d681SAndroid Build Coastguard Worker              (t2SUBrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4515*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm",
4516*9880d681SAndroid Build Coastguard Worker                  (t2SUBrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm,
4517*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4518*9880d681SAndroid Build Coastguard Worker// ... and with the destination and source register combined.
4519*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rdn, $imm",
4520*9880d681SAndroid Build Coastguard Worker      (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4521*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${p} $Rdn, $imm",
4522*9880d681SAndroid Build Coastguard Worker           (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
4523*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p}.w $Rdn, $Rm",
4524*9880d681SAndroid Build Coastguard Worker            (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4525*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rdn, $Rm",
4526*9880d681SAndroid Build Coastguard Worker            (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4527*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sub${s}${p} $Rdn, $ShiftedRm",
4528*9880d681SAndroid Build Coastguard Worker                  (t2SUBrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm,
4529*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4530*9880d681SAndroid Build Coastguard Worker
4531*9880d681SAndroid Build Coastguard Worker// Alias for compares without the ".w" optional width specifier.
4532*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cmn${p} $Rn, $Rm",
4533*9880d681SAndroid Build Coastguard Worker                  (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
4534*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"teq${p} $Rn, $Rm",
4535*9880d681SAndroid Build Coastguard Worker                  (t2TEQrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
4536*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"tst${p} $Rn, $Rm",
4537*9880d681SAndroid Build Coastguard Worker                  (t2TSTrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
4538*9880d681SAndroid Build Coastguard Worker
4539*9880d681SAndroid Build Coastguard Worker// Memory barriers
4540*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"dmb${p}", (t2DMB 0xf, pred:$p), 0>, Requires<[HasDB]>;
4541*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
4542*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
4543*9880d681SAndroid Build Coastguard Worker
4544*9880d681SAndroid Build Coastguard Worker// Alias for LDR, LDRB, LDRH, LDRSB, and LDRSH without the ".w" optional
4545*9880d681SAndroid Build Coastguard Worker// width specifier.
4546*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldr${p} $Rt, $addr",
4547*9880d681SAndroid Build Coastguard Worker                  (t2LDRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4548*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrb${p} $Rt, $addr",
4549*9880d681SAndroid Build Coastguard Worker                  (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4550*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrh${p} $Rt, $addr",
4551*9880d681SAndroid Build Coastguard Worker                  (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4552*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsb${p} $Rt, $addr",
4553*9880d681SAndroid Build Coastguard Worker                  (t2LDRSBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4554*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsh${p} $Rt, $addr",
4555*9880d681SAndroid Build Coastguard Worker                  (t2LDRSHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4556*9880d681SAndroid Build Coastguard Worker
4557*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldr${p} $Rt, $addr",
4558*9880d681SAndroid Build Coastguard Worker                  (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4559*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrb${p} $Rt, $addr",
4560*9880d681SAndroid Build Coastguard Worker                  (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4561*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrh${p} $Rt, $addr",
4562*9880d681SAndroid Build Coastguard Worker                  (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4563*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsb${p} $Rt, $addr",
4564*9880d681SAndroid Build Coastguard Worker                  (t2LDRSBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4565*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsh${p} $Rt, $addr",
4566*9880d681SAndroid Build Coastguard Worker                  (t2LDRSHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4567*9880d681SAndroid Build Coastguard Worker
4568*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldr${p} $Rt, $addr",
4569*9880d681SAndroid Build Coastguard Worker                  (t2LDRpci GPRnopc:$Rt, t2ldrlabel:$addr, pred:$p)>;
4570*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrb${p} $Rt, $addr",
4571*9880d681SAndroid Build Coastguard Worker                  (t2LDRBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
4572*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrh${p} $Rt, $addr",
4573*9880d681SAndroid Build Coastguard Worker                  (t2LDRHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
4574*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsb${p} $Rt, $addr",
4575*9880d681SAndroid Build Coastguard Worker                  (t2LDRSBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
4576*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsh${p} $Rt, $addr",
4577*9880d681SAndroid Build Coastguard Worker                  (t2LDRSHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
4578*9880d681SAndroid Build Coastguard Worker
4579*9880d681SAndroid Build Coastguard Worker// Alias for MVN with(out) the ".w" optional width specifier.
4580*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mvn${s}${p}.w $Rd, $imm",
4581*9880d681SAndroid Build Coastguard Worker           (t2MVNi rGPR:$Rd, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4582*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mvn${s}${p} $Rd, $Rm",
4583*9880d681SAndroid Build Coastguard Worker           (t2MVNr rGPR:$Rd, rGPR:$Rm, pred:$p, cc_out:$s)>;
4584*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mvn${s}${p} $Rd, $ShiftedRm",
4585*9880d681SAndroid Build Coastguard Worker           (t2MVNs rGPR:$Rd, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>;
4586*9880d681SAndroid Build Coastguard Worker
4587*9880d681SAndroid Build Coastguard Worker// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT with the
4588*9880d681SAndroid Build Coastguard Worker// input operands swapped when the shift amount is zero (i.e., unspecified).
4589*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm",
4590*9880d681SAndroid Build Coastguard Worker                (t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4591*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
4592*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm",
4593*9880d681SAndroid Build Coastguard Worker                (t2PKHBT rGPR:$Rd, rGPR:$Rm, rGPR:$Rn, 0, pred:$p), 0>,
4594*9880d681SAndroid Build Coastguard Worker            Requires<[HasT2ExtractPack, IsThumb2]>;
4595*9880d681SAndroid Build Coastguard Worker
4596*9880d681SAndroid Build Coastguard Worker// PUSH/POP aliases for STM/LDM
4597*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"push${p}.w $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>;
4598*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"push${p} $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>;
4599*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"pop${p}.w $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>;
4600*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"pop${p} $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>;
4601*9880d681SAndroid Build Coastguard Worker
4602*9880d681SAndroid Build Coastguard Worker// STMIA/STMIA_UPD aliases w/o the optional .w suffix
4603*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"stm${p} $Rn, $regs",
4604*9880d681SAndroid Build Coastguard Worker                  (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>;
4605*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"stm${p} $Rn!, $regs",
4606*9880d681SAndroid Build Coastguard Worker                  (t2STMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>;
4607*9880d681SAndroid Build Coastguard Worker
4608*9880d681SAndroid Build Coastguard Worker// LDMIA/LDMIA_UPD aliases w/o the optional .w suffix
4609*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldm${p} $Rn, $regs",
4610*9880d681SAndroid Build Coastguard Worker                  (t2LDMIA GPR:$Rn, pred:$p, reglist:$regs)>;
4611*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldm${p} $Rn!, $regs",
4612*9880d681SAndroid Build Coastguard Worker                  (t2LDMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>;
4613*9880d681SAndroid Build Coastguard Worker
4614*9880d681SAndroid Build Coastguard Worker// STMDB/STMDB_UPD aliases w/ the optional .w suffix
4615*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"stmdb${p}.w $Rn, $regs",
4616*9880d681SAndroid Build Coastguard Worker                  (t2STMDB GPR:$Rn, pred:$p, reglist:$regs)>;
4617*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"stmdb${p}.w $Rn!, $regs",
4618*9880d681SAndroid Build Coastguard Worker                  (t2STMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>;
4619*9880d681SAndroid Build Coastguard Worker
4620*9880d681SAndroid Build Coastguard Worker// LDMDB/LDMDB_UPD aliases w/ the optional .w suffix
4621*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldmdb${p}.w $Rn, $regs",
4622*9880d681SAndroid Build Coastguard Worker                  (t2LDMDB GPR:$Rn, pred:$p, reglist:$regs)>;
4623*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldmdb${p}.w $Rn!, $regs",
4624*9880d681SAndroid Build Coastguard Worker                  (t2LDMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>;
4625*9880d681SAndroid Build Coastguard Worker
4626*9880d681SAndroid Build Coastguard Worker// Alias for REV/REV16/REVSH without the ".w" optional width specifier.
4627*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rev${p} $Rd, $Rm", (t2REV rGPR:$Rd, rGPR:$Rm, pred:$p)>;
4628*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rev16${p} $Rd, $Rm", (t2REV16 rGPR:$Rd, rGPR:$Rm, pred:$p)>;
4629*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"revsh${p} $Rd, $Rm", (t2REVSH rGPR:$Rd, rGPR:$Rm, pred:$p)>;
4630*9880d681SAndroid Build Coastguard Worker
4631*9880d681SAndroid Build Coastguard Worker
4632*9880d681SAndroid Build Coastguard Worker// Alias for RSB without the ".w" optional width specifier, and with optional
4633*9880d681SAndroid Build Coastguard Worker// implied destination register.
4634*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rsb${s}${p} $Rd, $Rn, $imm",
4635*9880d681SAndroid Build Coastguard Worker           (t2RSBri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4636*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rsb${s}${p} $Rdn, $imm",
4637*9880d681SAndroid Build Coastguard Worker           (t2RSBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4638*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rsb${s}${p} $Rdn, $Rm",
4639*9880d681SAndroid Build Coastguard Worker           (t2RSBrr rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
4640*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"rsb${s}${p} $Rdn, $ShiftedRm",
4641*9880d681SAndroid Build Coastguard Worker           (t2RSBrs rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p,
4642*9880d681SAndroid Build Coastguard Worker                    cc_out:$s)>;
4643*9880d681SAndroid Build Coastguard Worker
4644*9880d681SAndroid Build Coastguard Worker// SSAT/USAT optional shift operand.
4645*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ssat${p} $Rd, $sat_imm, $Rn",
4646*9880d681SAndroid Build Coastguard Worker                  (t2SSAT rGPR:$Rd, imm1_32:$sat_imm, rGPR:$Rn, 0, pred:$p)>;
4647*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"usat${p} $Rd, $sat_imm, $Rn",
4648*9880d681SAndroid Build Coastguard Worker                  (t2USAT rGPR:$Rd, imm0_31:$sat_imm, rGPR:$Rn, 0, pred:$p)>;
4649*9880d681SAndroid Build Coastguard Worker
4650*9880d681SAndroid Build Coastguard Worker// STM w/o the .w suffix.
4651*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"stm${p} $Rn, $regs",
4652*9880d681SAndroid Build Coastguard Worker                  (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>;
4653*9880d681SAndroid Build Coastguard Worker
4654*9880d681SAndroid Build Coastguard Worker// Alias for STR, STRB, and STRH without the ".w" optional
4655*9880d681SAndroid Build Coastguard Worker// width specifier.
4656*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"str${p} $Rt, $addr",
4657*9880d681SAndroid Build Coastguard Worker                  (t2STRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4658*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"strb${p} $Rt, $addr",
4659*9880d681SAndroid Build Coastguard Worker                  (t2STRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4660*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"strh${p} $Rt, $addr",
4661*9880d681SAndroid Build Coastguard Worker                  (t2STRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
4662*9880d681SAndroid Build Coastguard Worker
4663*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"str${p} $Rt, $addr",
4664*9880d681SAndroid Build Coastguard Worker                  (t2STRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4665*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"strb${p} $Rt, $addr",
4666*9880d681SAndroid Build Coastguard Worker                  (t2STRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4667*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"strh${p} $Rt, $addr",
4668*9880d681SAndroid Build Coastguard Worker                  (t2STRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
4669*9880d681SAndroid Build Coastguard Worker
4670*9880d681SAndroid Build Coastguard Worker// Extend instruction optional rotate operand.
4671*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sxtab${p} $Rd, $Rn, $Rm",
4672*9880d681SAndroid Build Coastguard Worker              (t2SXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4673*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4674*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sxtah${p} $Rd, $Rn, $Rm",
4675*9880d681SAndroid Build Coastguard Worker              (t2SXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4676*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4677*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sxtab16${p} $Rd, $Rn, $Rm",
4678*9880d681SAndroid Build Coastguard Worker              (t2SXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4679*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4680*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sxtb16${p} $Rd, $Rm",
4681*9880d681SAndroid Build Coastguard Worker              (t2SXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p), 0>,
4682*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4683*9880d681SAndroid Build Coastguard Worker
4684*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxtb${p} $Rd, $Rm",
4685*9880d681SAndroid Build Coastguard Worker                (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4686*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxth${p} $Rd, $Rm",
4687*9880d681SAndroid Build Coastguard Worker                (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4688*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxtb${p}.w $Rd, $Rm",
4689*9880d681SAndroid Build Coastguard Worker                (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4690*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxth${p}.w $Rd, $Rm",
4691*9880d681SAndroid Build Coastguard Worker                (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4692*9880d681SAndroid Build Coastguard Worker
4693*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"uxtab${p} $Rd, $Rn, $Rm",
4694*9880d681SAndroid Build Coastguard Worker              (t2UXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4695*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4696*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"uxtah${p} $Rd, $Rn, $Rm",
4697*9880d681SAndroid Build Coastguard Worker              (t2UXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4698*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4699*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
4700*9880d681SAndroid Build Coastguard Worker              (t2UXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p), 0>,
4701*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4702*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"uxtb16${p} $Rd, $Rm",
4703*9880d681SAndroid Build Coastguard Worker              (t2UXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p), 0>,
4704*9880d681SAndroid Build Coastguard Worker              Requires<[HasT2ExtractPack, IsThumb2]>;
4705*9880d681SAndroid Build Coastguard Worker
4706*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxtb${p} $Rd, $Rm",
4707*9880d681SAndroid Build Coastguard Worker                (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4708*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxth${p} $Rd, $Rm",
4709*9880d681SAndroid Build Coastguard Worker                (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4710*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxtb${p}.w $Rd, $Rm",
4711*9880d681SAndroid Build Coastguard Worker                (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4712*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxth${p}.w $Rd, $Rm",
4713*9880d681SAndroid Build Coastguard Worker                (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>;
4714*9880d681SAndroid Build Coastguard Worker
4715*9880d681SAndroid Build Coastguard Worker// Extend instruction w/o the ".w" optional width specifier.
4716*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxtb${p} $Rd, $Rm$rot",
4717*9880d681SAndroid Build Coastguard Worker                  (t2UXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
4718*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"uxtb16${p} $Rd, $Rm$rot",
4719*9880d681SAndroid Build Coastguard Worker                (t2UXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p), 0>,
4720*9880d681SAndroid Build Coastguard Worker                Requires<[HasT2ExtractPack, IsThumb2]>;
4721*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"uxth${p} $Rd, $Rm$rot",
4722*9880d681SAndroid Build Coastguard Worker                  (t2UXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
4723*9880d681SAndroid Build Coastguard Worker
4724*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxtb${p} $Rd, $Rm$rot",
4725*9880d681SAndroid Build Coastguard Worker                  (t2SXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
4726*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sxtb16${p} $Rd, $Rm$rot",
4727*9880d681SAndroid Build Coastguard Worker                (t2SXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p), 0>,
4728*9880d681SAndroid Build Coastguard Worker                Requires<[HasT2ExtractPack, IsThumb2]>;
4729*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"sxth${p} $Rd, $Rm$rot",
4730*9880d681SAndroid Build Coastguard Worker                  (t2SXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>;
4731*9880d681SAndroid Build Coastguard Worker
4732*9880d681SAndroid Build Coastguard Worker
4733*9880d681SAndroid Build Coastguard Worker// "mov Rd, t2_so_imm_not" can be handled via "mvn" in assembly, just like
4734*9880d681SAndroid Build Coastguard Worker// for isel.
4735*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mov${p} $Rd, $imm",
4736*9880d681SAndroid Build Coastguard Worker                  (t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
4737*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mvn${p} $Rd, $imm",
4738*9880d681SAndroid Build Coastguard Worker                  (t2MOVi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
4739*9880d681SAndroid Build Coastguard Worker// Same for AND <--> BIC
4740*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"bic${s}${p} $Rd, $Rn, $imm",
4741*9880d681SAndroid Build Coastguard Worker                  (t2ANDri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
4742*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4743*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"bic${s}${p} $Rdn, $imm",
4744*9880d681SAndroid Build Coastguard Worker                  (t2ANDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
4745*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4746*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"and${s}${p} $Rd, $Rn, $imm",
4747*9880d681SAndroid Build Coastguard Worker                  (t2BICri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
4748*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4749*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"and${s}${p} $Rdn, $imm",
4750*9880d681SAndroid Build Coastguard Worker                  (t2BICri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
4751*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4752*9880d681SAndroid Build Coastguard Worker// Likewise, "add Rd, t2_so_imm_neg" -> sub
4753*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4754*9880d681SAndroid Build Coastguard Worker                  (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
4755*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4756*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${s}${p} $Rd, $imm",
4757*9880d681SAndroid Build Coastguard Worker                  (t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm,
4758*9880d681SAndroid Build Coastguard Worker                           pred:$p, cc_out:$s)>;
4759*9880d681SAndroid Build Coastguard Worker// Same for CMP <--> CMN via t2_so_imm_neg
4760*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cmp${p} $Rd, $imm",
4761*9880d681SAndroid Build Coastguard Worker                  (t2CMNri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>;
4762*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"cmn${p} $Rd, $imm",
4763*9880d681SAndroid Build Coastguard Worker                  (t2CMPri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>;
4764*9880d681SAndroid Build Coastguard Worker
4765*9880d681SAndroid Build Coastguard Worker
4766*9880d681SAndroid Build Coastguard Worker// Wide 'mul' encoding can be specified with only two operands.
4767*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"mul${p} $Rn, $Rm",
4768*9880d681SAndroid Build Coastguard Worker                  (t2MUL rGPR:$Rn, rGPR:$Rm, rGPR:$Rn, pred:$p)>;
4769*9880d681SAndroid Build Coastguard Worker
4770*9880d681SAndroid Build Coastguard Worker// "neg" is and alias for "rsb rd, rn, #0"
4771*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"neg${s}${p} $Rd, $Rm",
4772*9880d681SAndroid Build Coastguard Worker                  (t2RSBri rGPR:$Rd, rGPR:$Rm, 0, pred:$p, cc_out:$s)>;
4773*9880d681SAndroid Build Coastguard Worker
4774*9880d681SAndroid Build Coastguard Worker// MOV so_reg assembler pseudos. InstAlias isn't expressive enough for
4775*9880d681SAndroid Build Coastguard Worker// these, unfortunately.
4776*9880d681SAndroid Build Coastguard Workerdef t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift",
4777*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>;
4778*9880d681SAndroid Build Coastguard Workerdef t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift",
4779*9880d681SAndroid Build Coastguard Worker                          (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>;
4780*9880d681SAndroid Build Coastguard Worker
4781*9880d681SAndroid Build Coastguard Workerdef t2MOVsr: t2AsmPseudo<"mov${p} $Rd, $shift",
4782*9880d681SAndroid Build Coastguard Worker                         (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>;
4783*9880d681SAndroid Build Coastguard Workerdef t2MOVSsr: t2AsmPseudo<"movs${p} $Rd, $shift",
4784*9880d681SAndroid Build Coastguard Worker                          (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>;
4785*9880d681SAndroid Build Coastguard Worker
4786*9880d681SAndroid Build Coastguard Worker// ADR w/o the .w suffix
4787*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"adr${p} $Rd, $addr",
4788*9880d681SAndroid Build Coastguard Worker                  (t2ADR rGPR:$Rd, t2adrlabel:$addr, pred:$p)>;
4789*9880d681SAndroid Build Coastguard Worker
4790*9880d681SAndroid Build Coastguard Worker// LDR(literal) w/ alternate [pc, #imm] syntax.
4791*9880d681SAndroid Build Coastguard Workerdef t2LDRpcrel   : t2AsmPseudo<"ldr${p} $Rt, $addr",
4792*9880d681SAndroid Build Coastguard Worker                         (ins GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4793*9880d681SAndroid Build Coastguard Workerdef t2LDRBpcrel  : t2AsmPseudo<"ldrb${p} $Rt, $addr",
4794*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4795*9880d681SAndroid Build Coastguard Workerdef t2LDRHpcrel  : t2AsmPseudo<"ldrh${p} $Rt, $addr",
4796*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4797*9880d681SAndroid Build Coastguard Workerdef t2LDRSBpcrel  : t2AsmPseudo<"ldrsb${p} $Rt, $addr",
4798*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4799*9880d681SAndroid Build Coastguard Workerdef t2LDRSHpcrel  : t2AsmPseudo<"ldrsh${p} $Rt, $addr",
4800*9880d681SAndroid Build Coastguard Worker                         (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4801*9880d681SAndroid Build Coastguard Worker    // Version w/ the .w suffix.
4802*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldr${p}.w $Rt, $addr",
4803*9880d681SAndroid Build Coastguard Worker                  (t2LDRpcrel GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p), 0>;
4804*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrb${p}.w $Rt, $addr",
4805*9880d681SAndroid Build Coastguard Worker                  (t2LDRBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4806*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrh${p}.w $Rt, $addr",
4807*9880d681SAndroid Build Coastguard Worker                  (t2LDRHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4808*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsb${p}.w $Rt, $addr",
4809*9880d681SAndroid Build Coastguard Worker                  (t2LDRSBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4810*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"ldrsh${p}.w $Rt, $addr",
4811*9880d681SAndroid Build Coastguard Worker                  (t2LDRSHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
4812*9880d681SAndroid Build Coastguard Worker
4813*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"add${p} $Rd, pc, $imm",
4814*9880d681SAndroid Build Coastguard Worker                  (t2ADR rGPR:$Rd, imm0_4095:$imm, pred:$p)>;
4815*9880d681SAndroid Build Coastguard Worker
4816*9880d681SAndroid Build Coastguard Worker// Pseudo instruction ldr Rt, =immediate
4817*9880d681SAndroid Build Coastguard Workerdef t2LDRConstPool
4818*9880d681SAndroid Build Coastguard Worker  : t2AsmPseudo<"ldr${p} $Rt, $immediate",
4819*9880d681SAndroid Build Coastguard Worker                (ins GPRnopc:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
4820*9880d681SAndroid Build Coastguard Worker
4821*9880d681SAndroid Build Coastguard Worker// PLD/PLDW/PLI with alternate literal form.
4822*9880d681SAndroid Build Coastguard Workerdef : t2InstAlias<"pld${p} $addr",
4823*9880d681SAndroid Build Coastguard Worker                  (t2PLDpci t2ldr_pcrel_imm12:$addr, pred:$p)>;
4824*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"pli${p} $addr",
4825*9880d681SAndroid Build Coastguard Worker                 (t2PLIpci  t2ldr_pcrel_imm12:$addr, pred:$p), 0>,
4826*9880d681SAndroid Build Coastguard Worker      Requires<[IsThumb2,HasV7]>;
4827