ARMInstrThumb.td revision 199511
1249259Sdim//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This file describes the Thumb instruction set.
11249259Sdim//
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim// Thumb specific DAG Nodes.
16249259Sdim//
17276479Sdim
18276479Sdimdef ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall,
19249259Sdim                      [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
20249259Sdim
21249259Sdimdef imm_neg_XFORM : SDNodeXForm<imm, [{
22249259Sdim  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
23249259Sdim}]>;
24249259Sdimdef imm_comp_XFORM : SDNodeXForm<imm, [{
25249259Sdim  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
26249259Sdim}]>;
27249259Sdim
28249259Sdim
29249259Sdim/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7].
30249259Sdimdef imm0_7 : PatLeaf<(i32 imm), [{
31249259Sdim  return (uint32_t)N->getZExtValue() < 8;
32249259Sdim}]>;
33249259Sdimdef imm0_7_neg : PatLeaf<(i32 imm), [{
34249259Sdim  return (uint32_t)-N->getZExtValue() < 8;
35249259Sdim}], imm_neg_XFORM>;
36249259Sdim
37249259Sdimdef imm0_255 : PatLeaf<(i32 imm), [{
38249259Sdim  return (uint32_t)N->getZExtValue() < 256;
39249259Sdim}]>;
40249259Sdimdef imm0_255_comp : PatLeaf<(i32 imm), [{
41249259Sdim  return ~((uint32_t)N->getZExtValue()) < 256;
42249259Sdim}]>;
43249259Sdim
44249259Sdimdef imm8_255 : PatLeaf<(i32 imm), [{
45249259Sdim  return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256;
46249259Sdim}]>;
47249259Sdimdef imm8_255_neg : PatLeaf<(i32 imm), [{
48249259Sdim  unsigned Val = -N->getZExtValue();
49249259Sdim  return Val >= 8 && Val < 256;
50249259Sdim}], imm_neg_XFORM>;
51249259Sdim
52249259Sdim// Break imm's up into two pieces: an immediate + a left shift.
53249259Sdim// This uses thumb_immshifted to match and thumb_immshifted_val and
54249259Sdim// thumb_immshifted_shamt to get the val/shift pieces.
55249259Sdimdef thumb_immshifted : PatLeaf<(imm), [{
56249259Sdim  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
57249259Sdim}]>;
58249259Sdim
59249259Sdimdef thumb_immshifted_val : SDNodeXForm<imm, [{
60249259Sdim  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
61249259Sdim  return CurDAG->getTargetConstant(V, MVT::i32);
62249259Sdim}]>;
63249259Sdim
64249259Sdimdef thumb_immshifted_shamt : SDNodeXForm<imm, [{
65296417Sdim  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
66296417Sdim  return CurDAG->getTargetConstant(V, MVT::i32);
67296417Sdim}]>;
68296417Sdim
69249259Sdim// Scaled 4 immediate.
70249259Sdimdef t_imm_s4 : Operand<i32> {
71249259Sdim  let PrintMethod = "printThumbS4ImmOperand";
72249259Sdim}
73249259Sdim
74276479Sdim// Define Thumb specific addressing modes.
75249259Sdim
76249259Sdim// t_addrmode_rr := reg + reg
77249259Sdim//
78249259Sdimdef t_addrmode_rr : Operand<i32>,
79249259Sdim                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
80249259Sdim  let PrintMethod = "printThumbAddrModeRROperand";
81249259Sdim  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
82276479Sdim}
83249259Sdim
84249259Sdim// t_addrmode_s4 := reg + reg
85249259Sdim//                  reg + imm5 * 4
86249259Sdim//
87249259Sdimdef t_addrmode_s4 : Operand<i32>,
88249259Sdim                    ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
89249259Sdim  let PrintMethod = "printThumbAddrModeS4Operand";
90296417Sdim  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
91296417Sdim}
92249259Sdim
93288943Sdim// t_addrmode_s2 := reg + reg
94288943Sdim//                  reg + imm5 * 2
95288943Sdim//
96249259Sdimdef t_addrmode_s2 : Operand<i32>,
97249259Sdim                    ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
98249259Sdim  let PrintMethod = "printThumbAddrModeS2Operand";
99249259Sdim  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
100249259Sdim}
101249259Sdim
102249259Sdim// t_addrmode_s1 := reg + reg
103249259Sdim//                  reg + imm5
104249259Sdim//
105249259Sdimdef t_addrmode_s1 : Operand<i32>,
106249259Sdim                    ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
107249259Sdim  let PrintMethod = "printThumbAddrModeS1Operand";
108249259Sdim  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
109249259Sdim}
110249259Sdim
111249259Sdim// t_addrmode_sp := sp + imm8 * 4
112249259Sdim//
113249259Sdimdef t_addrmode_sp : Operand<i32>,
114249259Sdim                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
115276479Sdim  let PrintMethod = "printThumbAddrModeSPOperand";
116288943Sdim  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
117249259Sdim}
118249259Sdim
119249259Sdim//===----------------------------------------------------------------------===//
120249259Sdim//  Miscellaneous Instructions.
121249259Sdim//
122249259Sdim
123249259Sdimlet Defs = [SP], Uses = [SP] in {
124249259Sdimdef tADJCALLSTACKUP :
125249259SdimPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
126249259Sdim           "@ tADJCALLSTACKUP $amt1",
127249259Sdim           [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>;
128249259Sdim
129249259Sdimdef tADJCALLSTACKDOWN :
130249259SdimPseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
131249259Sdim           "@ tADJCALLSTACKDOWN $amt",
132249259Sdim           [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
133249259Sdim}
134249259Sdim
135249259Sdim// For both thumb1 and thumb2.
136249259Sdimlet isNotDuplicable = 1 in
137288943Sdimdef tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
138249259Sdim                 "\n$cp:\n\tadd\t$dst, pc",
139249259Sdim                 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
140249259Sdim
141249259Sdim// PC relative add.
142249259Sdimdef tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi,
143249259Sdim                  "add\t$dst, pc, $rhs", []>;
144249259Sdim
145249259Sdim// ADD rd, sp, #imm8
146249259Sdimdef tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi,
147249259Sdim                  "add\t$dst, $sp, $rhs", []>;
148276479Sdim
149249259Sdim// ADD sp, sp, #imm7
150249259Sdimdef tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi,
151249259Sdim                  "add\t$dst, $rhs", []>;
152249259Sdim
153249259Sdim// SUB sp, sp, #imm7
154249259Sdimdef tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi,
155249259Sdim                  "sub\t$dst, $rhs", []>;
156249259Sdim
157249259Sdim// ADD rm, sp
158249259Sdimdef tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
159249259Sdim                  "add\t$dst, $rhs", []>;
160249259Sdim
161288943Sdim// ADD sp, rm
162288943Sdimdef tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
163288943Sdim                  "add\t$dst, $rhs", []>;
164288943Sdim
165249259Sdim// Pseudo instruction that will expand into a tSUBspi + a copy.
166249259Sdimlet usesCustomInserter = 1 in { // Expanded after instruction selection.
167288943Sdimdef tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs),
168288943Sdim               NoItinerary, "@ sub\t$dst, $rhs", []>;
169288943Sdim
170288943Sdimdef tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
171249259Sdim               NoItinerary, "@ add\t$dst, $rhs", []>;
172249259Sdim
173249259Sdimlet Defs = [CPSR] in
174288943Sdimdef tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
175288943Sdim             NoItinerary, "@ and\t$dst, $rhs", []>;
176288943Sdim} // usesCustomInserter
177288943Sdim
178288943Sdim//===----------------------------------------------------------------------===//
179288943Sdim//  Control Flow Instructions.
180249259Sdim//
181249259Sdim
182249259Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1 in {
183249259Sdim  def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>;
184249259Sdim  // Alternative return instruction used by vararg functions.
185249259Sdim  def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>;
186288943Sdim}
187249259Sdim
188249259Sdim// Indirect branches
189288943Sdimlet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
190249259Sdim  def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst",
191249259Sdim                  [(brind GPR:$dst)]>;
192288943Sdim}
193249259Sdim
194249259Sdim// FIXME: remove when we have a way to marking a MI with these properties.
195288943Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
196249259Sdim    hasExtraDefRegAllocReq = 1 in
197249259Sdimdef tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
198288943Sdim                   "pop${p}\t$wb", []>;
199249259Sdim
200288943Sdimlet isCall = 1,
201288943Sdim  Defs = [R0,  R1,  R2,  R3,  R12, LR,
202249259Sdim          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
203249259Sdim          D16, D17, D18, D19, D20, D21, D22, D23,
204249259Sdim          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
205249259Sdim  // Also used for Thumb2
206249259Sdim  def tBL  : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
207249259Sdim                   "bl\t${func:call}",
208249259Sdim                   [(ARMtcall tglobaladdr:$func)]>,
209249259Sdim             Requires<[IsThumb, IsNotDarwin]>;
210249259Sdim
211288943Sdim  // ARMv5T and above, also used for Thumb2
212288943Sdim  def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
213249259Sdim                    "blx\t${func:call}",
214249259Sdim                    [(ARMcall tglobaladdr:$func)]>,
215276479Sdim              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
216249259Sdim
217249259Sdim  // Also used for Thumb2
218249259Sdim  def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
219288943Sdim                  "blx\t$func",
220288943Sdim                  [(ARMtcall GPR:$func)]>,
221249259Sdim              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
222249259Sdim
223249259Sdim  // ARMv4T
224249259Sdim  def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
225249259Sdim                  "mov\tlr, pc\n\tbx\t$func",
226249259Sdim                  [(ARMcall_nolink tGPR:$func)]>,
227249259Sdim            Requires<[IsThumb1Only, IsNotDarwin]>;
228249259Sdim}
229249259Sdim
230288943Sdim// On Darwin R9 is call-clobbered.
231296417Sdimlet isCall = 1,
232288943Sdim  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
233296417Sdim          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
234296417Sdim          D16, D17, D18, D19, D20, D21, D22, D23,
235249259Sdim          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
236249259Sdim  // Also used for Thumb2
237249259Sdim  def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
238249259Sdim                   "bl\t${func:call}",
239249259Sdim                   [(ARMtcall tglobaladdr:$func)]>,
240249259Sdim              Requires<[IsThumb, IsDarwin]>;
241249259Sdim
242249259Sdim  // ARMv5T and above, also used for Thumb2
243249259Sdim  def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
244249259Sdim                      "blx\t${func:call}",
245249259Sdim                      [(ARMcall tglobaladdr:$func)]>,
246249259Sdim                 Requires<[IsThumb, HasV5T, IsDarwin]>;
247249259Sdim
248249259Sdim  // Also used for Thumb2
249296417Sdim  def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
250296417Sdim                  "blx\t$func",
251296417Sdim                  [(ARMtcall GPR:$func)]>,
252296417Sdim                 Requires<[IsThumb, HasV5T, IsDarwin]>;
253296417Sdim
254249259Sdim  // ARMv4T
255249259Sdim  def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
256249259Sdim                  "mov\tlr, pc\n\tbx\t$func",
257249259Sdim                  [(ARMcall_nolink tGPR:$func)]>,
258288943Sdim              Requires<[IsThumb1Only, IsDarwin]>;
259288943Sdim}
260288943Sdim
261249259Sdimlet isBranch = 1, isTerminator = 1 in {
262249259Sdim  let isBarrier = 1 in {
263249259Sdim    let isPredicable = 1 in
264249259Sdim    def tB   : T1I<(outs), (ins brtarget:$target), IIC_Br,
265249259Sdim                   "b\t$target", [(br bb:$target)]>;
266249259Sdim
267249259Sdim  // Far jump
268249259Sdim  let Defs = [LR] in
269249259Sdim  def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 
270249259Sdim                    "bl\t$target\t@ far jump",[]>;
271249259Sdim
272249259Sdim  def tBR_JTr : T1JTI<(outs),
273249259Sdim                      (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
274249259Sdim                      IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt",
275249259Sdim                      [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
276249259Sdim  }
277249259Sdim}
278249259Sdim
279249259Sdim// FIXME: should be able to write a pattern for ARMBrcond, but can't use
280249259Sdim// a two-value operand where a dag node expects two operands. :(
281249259Sdimlet isBranch = 1, isTerminator = 1 in
282249259Sdim  def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br,
283249259Sdim                 "b$cc\t$target",
284249259Sdim                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
285249259Sdim
286249259Sdim// Compare and branch on zero / non-zero
287249259Sdimlet isBranch = 1, isTerminator = 1 in {
288249259Sdim  def tCBZ  : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br,
289288943Sdim                  "cbz\t$cmp, $target", []>;
290288943Sdim
291288943Sdim  def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br,
292288943Sdim                  "cbnz\t$cmp, $target", []>;
293276479Sdim}
294249259Sdim
295296417Sdim//===----------------------------------------------------------------------===//
296249259Sdim//  Load Store Instructions.
297296417Sdim//
298296417Sdim
299249259Sdimlet canFoldAsLoad = 1 in
300249259Sdimdef tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 
301249259Sdim               "ldr", "\t$dst, $addr",
302296417Sdim               [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
303296417Sdim
304296417Sdimdef tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
305296417Sdim                "ldrb", "\t$dst, $addr",
306296417Sdim                [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
307296417Sdim
308296417Sdimdef tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
309296417Sdim                "ldrh", "\t$dst, $addr",
310296417Sdim                [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
311296417Sdim
312296417Sdimlet AddedComplexity = 10 in
313296417Sdimdef tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
314296417Sdim                 "ldrsb", "\t$dst, $addr",
315249259Sdim                 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
316249259Sdim
317249259Sdimlet AddedComplexity = 10 in
318249259Sdimdef tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
319249259Sdim                 "ldrsh", "\t$dst, $addr",
320249259Sdim                 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
321288943Sdim
322288943Sdimlet canFoldAsLoad = 1 in
323288943Sdimdef tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
324288943Sdim                  "ldr", "\t$dst, $addr",
325288943Sdim                  [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
326288943Sdim
327249259Sdim// Special instruction for restore. It cannot clobber condition register
328249259Sdim// when it's expanded by eliminateCallFramePseudoInstr().
329249259Sdimlet canFoldAsLoad = 1, mayLoad = 1 in
330249259Sdimdef tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
331249259Sdim                    "ldr", "\t$dst, $addr", []>;
332249259Sdim
333249259Sdim// Load tconstpool
334249259Sdim// FIXME: Use ldr.n to work around a Darwin assembler bug.
335249259Sdimlet canFoldAsLoad = 1 in
336288943Sdimdef tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
337288943Sdim                  "ldr", ".n\t$dst, $addr",
338288943Sdim                  [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
339288943Sdim
340249259Sdim// Special LDR for loads from non-pc-relative constpools.
341249259Sdimlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
342288943Sdimdef tLDRcp  : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
343288943Sdim                  "ldr", "\t$dst, $addr", []>;
344288943Sdim
345288943Sdimdef tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
346288943Sdim               "str", "\t$src, $addr",
347288943Sdim               [(store tGPR:$src, t_addrmode_s4:$addr)]>;
348249259Sdim
349296417Sdimdef tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
350296417Sdim                 "strb", "\t$src, $addr",
351249259Sdim                 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
352249259Sdim
353249259Sdimdef tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
354249259Sdim                 "strh", "\t$src, $addr",
355249259Sdim                 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
356249259Sdim
357249259Sdimdef tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
358296417Sdim                   "str", "\t$src, $addr",
359296417Sdim                   [(store tGPR:$src, t_addrmode_sp:$addr)]>;
360296417Sdim
361296417Sdimlet mayStore = 1 in {
362296417Sdim// Special instruction for spill. It cannot clobber condition register
363296417Sdim// when it's expanded by eliminateCallFramePseudoInstr().
364296417Sdimdef tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
365296417Sdim                  "str", "\t$src, $addr", []>;
366296417Sdim}
367296417Sdim
368296417Sdim//===----------------------------------------------------------------------===//
369296417Sdim//  Load / store multiple Instructions.
370296417Sdim//
371296417Sdim
372296417Sdim// These requires base address to be written back or one of the loaded regs.
373296417Sdimlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in
374296417Sdimdef tLDM : T1I<(outs),
375296417Sdim               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
376296417Sdim               IIC_iLoadm,
377249259Sdim               "ldm${addr:submode}${p}\t$addr, $wb", []>;
378249259Sdim
379280031Sdimlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in
380280031Sdimdef tSTM : T1I<(outs),
381280031Sdim               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
382249259Sdim               IIC_iStorem,
383249259Sdim               "stm${addr:submode}${p}\t$addr, $wb", []>;
384249259Sdim
385249259Sdimlet mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
386249259Sdimdef tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
387249259Sdim               "pop${p}\t$wb", []>;
388249259Sdim
389249259Sdimlet mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
390249259Sdimdef tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
391249259Sdim                "push${p}\t$wb", []>;
392249259Sdim
393249259Sdim//===----------------------------------------------------------------------===//
394249259Sdim//  Arithmetic Instructions.
395249259Sdim//
396249259Sdim
397249259Sdim// Add with carry register
398249259Sdimlet isCommutable = 1, Uses = [CPSR] in
399249259Sdimdef tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
400249259Sdim                 "adc", "\t$dst, $rhs",
401249259Sdim                 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
402249259Sdim
403249259Sdim// Add immediate
404249259Sdimdef tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
405249259Sdim                   "add", "\t$dst, $lhs, $rhs",
406249259Sdim                   [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
407249259Sdim
408249259Sdimdef tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
409249259Sdim                   "add", "\t$dst, $rhs",
410249259Sdim                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
411249259Sdim
412249259Sdim// Add register
413249259Sdimlet isCommutable = 1 in
414249259Sdimdef tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
415249259Sdim                   "add", "\t$dst, $lhs, $rhs",
416249259Sdim                   [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
417249259Sdim
418249259Sdimlet neverHasSideEffects = 1 in
419249259Sdimdef tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
420249259Sdim                     "add", "\t$dst, $rhs", []>;
421249259Sdim
422249259Sdim// And register
423249259Sdimlet isCommutable = 1 in
424249259Sdimdef tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
425249259Sdim                 "and", "\t$dst, $rhs",
426249259Sdim                 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
427249259Sdim
428249259Sdim// ASR immediate
429249259Sdimdef tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
430249259Sdim                  "asr", "\t$dst, $lhs, $rhs",
431249259Sdim                  [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
432249259Sdim
433249259Sdim// ASR register
434280031Sdimdef tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
435249259Sdim                   "asr", "\t$dst, $rhs",
436276479Sdim                   [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
437276479Sdim
438249259Sdim// BIC register
439249259Sdimdef tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
440249259Sdim                 "bic", "\t$dst, $rhs",
441249259Sdim                 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
442249259Sdim
443249259Sdim// CMN register
444249259Sdimlet Defs = [CPSR] in {
445249259Sdimdef tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
446249259Sdim                "cmn", "\t$lhs, $rhs",
447249259Sdim                [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
448249259Sdimdef tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
449249259Sdim                 "cmn", "\t$lhs, $rhs",
450249259Sdim                 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
451249259Sdim}
452249259Sdim
453249259Sdim// CMP immediate
454249259Sdimlet Defs = [CPSR] in {
455249259Sdimdef tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
456249259Sdim                  "cmp", "\t$lhs, $rhs",
457249259Sdim                  [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
458249259Sdimdef tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
459249259Sdim                  "cmp", "\t$lhs, $rhs",
460249259Sdim                  [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
461249259Sdim
462249259Sdim}
463249259Sdim
464249259Sdim// CMP register
465249259Sdimlet Defs = [CPSR] in {
466249259Sdimdef tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
467249259Sdim                 "cmp", "\t$lhs, $rhs",
468249259Sdim                 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
469249259Sdimdef tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
470249259Sdim                  "cmp", "\t$lhs, $rhs",
471249259Sdim                  [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
472249259Sdim
473249259Sdimdef tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
474276479Sdim                   "cmp", "\t$lhs, $rhs", []>;
475249259Sdimdef tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
476249259Sdim                    "cmp", "\t$lhs, $rhs", []>;
477249259Sdim}
478249259Sdim
479249259Sdim
480249259Sdim// XOR register
481249259Sdimlet isCommutable = 1 in
482249259Sdimdef tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
483249259Sdim                 "eor", "\t$dst, $rhs",
484249259Sdim                 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
485249259Sdim
486249259Sdim// LSL immediate
487249259Sdimdef tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
488249259Sdim                  "lsl", "\t$dst, $lhs, $rhs",
489249259Sdim                  [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
490276479Sdim
491249259Sdim// LSL register
492249259Sdimdef tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
493249259Sdim                   "lsl", "\t$dst, $rhs",
494249259Sdim                   [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
495249259Sdim
496249259Sdim// LSR immediate
497249259Sdimdef tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
498249259Sdim                  "lsr", "\t$dst, $lhs, $rhs",
499249259Sdim                  [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
500249259Sdim
501249259Sdim// LSR register
502249259Sdimdef tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
503249259Sdim                   "lsr", "\t$dst, $rhs",
504249259Sdim                   [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
505249259Sdim
506249259Sdim// move register
507280031Sdimdef tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
508276479Sdim                  "mov", "\t$dst, $src",
509249259Sdim                  [(set tGPR:$dst, imm0_255:$src)]>;
510249259Sdim
511249259Sdim// TODO: A7-73: MOV(2) - mov setting flag.
512249259Sdim
513249259Sdim
514249259Sdimlet neverHasSideEffects = 1 in {
515249259Sdim// FIXME: Make this predicable.
516249259Sdimdef tMOVr       : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
517249259Sdim                      "mov\t$dst, $src", []>;
518249259Sdimlet Defs = [CPSR] in
519249259Sdimdef tMOVSr      : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
520249259Sdim                       "movs\t$dst, $src", []>;
521249259Sdim
522249259Sdim// FIXME: Make these predicable.
523249259Sdimdef tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr,
524249259Sdim                       "mov\t$dst, $src", []>;
525249259Sdimdef tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr,
526249259Sdim                       "mov\t$dst, $src", []>;
527249259Sdimdef tMOVgpr2gpr  : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
528276479Sdim                       "mov\t$dst, $src", []>;
529249259Sdim} // neverHasSideEffects
530249259Sdim
531249259Sdim// multiply register
532249259Sdimlet isCommutable = 1 in
533249259Sdimdef tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32,
534249259Sdim                 "mul", "\t$dst, $rhs",
535276479Sdim                 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
536249259Sdim
537249259Sdim// move inverse register
538249259Sdimdef tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
539249259Sdim                "mvn", "\t$dst, $src",
540249259Sdim                [(set tGPR:$dst, (not tGPR:$src))]>;
541249259Sdim
542249259Sdim// bitwise or register
543249259Sdimlet isCommutable = 1 in
544288943Sdimdef tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),  IIC_iALUr,
545288943Sdim                 "orr", "\t$dst, $rhs",
546296417Sdim                 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
547288943Sdim
548288943Sdim// swaps
549288943Sdimdef tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
550296417Sdim                "rev", "\t$dst, $src",
551296417Sdim                [(set tGPR:$dst, (bswap tGPR:$src))]>,
552249259Sdim                Requires<[IsThumb1Only, HasV6]>;
553249259Sdim
554249259Sdimdef tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
555249259Sdim                  "rev16", "\t$dst, $src",
556249259Sdim             [(set tGPR:$dst,
557249259Sdim                   (or (and (srl tGPR:$src, (i32 8)), 0xFF),
558249259Sdim                       (or (and (shl tGPR:$src, (i32 8)), 0xFF00),
559249259Sdim                           (or (and (srl tGPR:$src, (i32 8)), 0xFF0000),
560249259Sdim                               (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
561249259Sdim                Requires<[IsThumb1Only, HasV6]>;
562249259Sdim
563249259Sdimdef tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
564249259Sdim                  "revsh", "\t$dst, $src",
565249259Sdim                  [(set tGPR:$dst,
566249259Sdim                        (sext_inreg
567249259Sdim                          (or (srl (and tGPR:$src, 0xFF00), (i32 8)),
568296417Sdim                              (shl tGPR:$src, (i32 8))), i16))]>,
569296417Sdim                  Requires<[IsThumb1Only, HasV6]>;
570296417Sdim
571296417Sdim// rotate right register
572296417Sdimdef tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
573249259Sdim                 "ror", "\t$dst, $rhs",
574249259Sdim                 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
575249259Sdim
576249259Sdim// negate register
577288943Sdimdef tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi,
578288943Sdim                "rsb", "\t$dst, $src, #0",
579288943Sdim                [(set tGPR:$dst, (ineg tGPR:$src))]>;
580288943Sdim
581288943Sdim// Subtract with carry register
582249259Sdimlet Uses = [CPSR] in
583249259Sdimdef tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
584296417Sdim                 "sbc", "\t$dst, $rhs",
585296417Sdim                 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
586249259Sdim
587249259Sdim// Subtract immediate
588249259Sdimdef tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
589296417Sdim                  "sub", "\t$dst, $lhs, $rhs",
590296417Sdim                  [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
591296417Sdim
592296417Sdimdef tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
593296417Sdim                   "sub", "\t$dst, $rhs",
594296417Sdim                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
595296417Sdim
596296417Sdim// subtract register
597296417Sdimdef tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
598296417Sdim                  "sub", "\t$dst, $lhs, $rhs",
599296417Sdim                  [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
600296417Sdim
601296417Sdim// TODO: A7-96: STMIA - store multiple.
602249259Sdim
603249259Sdim// sign-extend byte
604249259Sdimdef tSXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
605249259Sdim                  "sxtb", "\t$dst, $src",
606249259Sdim                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
607249259Sdim                  Requires<[IsThumb1Only, HasV6]>;
608249259Sdim
609249259Sdim// sign-extend short
610249259Sdimdef tSXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
611249259Sdim                  "sxth", "\t$dst, $src",
612296417Sdim                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
613296417Sdim                  Requires<[IsThumb1Only, HasV6]>;
614249259Sdim
615249259Sdim// test
616249259Sdimlet isCommutable = 1, Defs = [CPSR] in
617249259Sdimdef tTST  : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
618249259Sdim                 "tst", "\t$lhs, $rhs",
619249259Sdim                 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
620249259Sdim
621249259Sdim// zero-extend byte
622296417Sdimdef tUXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
623296417Sdim                  "uxtb", "\t$dst, $src",
624296417Sdim                  [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
625296417Sdim                  Requires<[IsThumb1Only, HasV6]>;
626296417Sdim
627296417Sdim// zero-extend short
628296417Sdimdef tUXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
629296417Sdim                  "uxth", "\t$dst, $src",
630296417Sdim                  [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
631296417Sdim                  Requires<[IsThumb1Only, HasV6]>;
632296417Sdim
633296417Sdim
634296417Sdim// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
635296417Sdim// Expanded after instruction selection into a branch sequence.
636296417Sdimlet usesCustomInserter = 1 in  // Expanded after instruction selection.
637296417Sdim  def tMOVCCr_pseudo :
638296417Sdim  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
639296417Sdim              NoItinerary, "@ tMOVCCr $cc",
640249259Sdim             [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
641249259Sdim
642249259Sdim
643249259Sdim// 16-bit movcc in IT blocks for Thumb2.
644249259Sdimdef tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
645249259Sdim                    "mov", "\t$dst, $rhs", []>;
646249259Sdim
647249259Sdimdef tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
648249259Sdim                    "mov", "\t$dst, $rhs", []>;
649249259Sdim
650249259Sdim// tLEApcrel - Load a pc-relative address into a register without offending the
651249259Sdim// assembler.
652249259Sdimdef tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
653249259Sdim                    "adr$p\t$dst, #$label", []>;
654288943Sdim
655288943Sdimdef tLEApcrelJT : T1I<(outs tGPR:$dst),
656288943Sdim                      (ins i32imm:$label, nohash_imm:$id, pred:$p),
657288943Sdim                      IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>;
658288943Sdim
659288943Sdim//===----------------------------------------------------------------------===//
660288943Sdim// TLS Instructions
661288943Sdim//
662288943Sdim
663288943Sdim// __aeabi_read_tp preserves the registers r1-r3.
664288943Sdimlet isCall = 1,
665288943Sdim  Defs = [R0, LR] in {
666249259Sdim  def tTPsoft  : TIx2<(outs), (ins), IIC_Br,
667249259Sdim               "bl\t__aeabi_read_tp",
668249259Sdim               [(set R0, ARMthread_pointer)]>;
669249259Sdim}
670249259Sdim
671249259Sdim//===----------------------------------------------------------------------===//
672249259Sdim// Non-Instruction Patterns
673249259Sdim//
674249259Sdim
675249259Sdim// Add with carry
676249259Sdimdef : T1Pat<(addc   tGPR:$lhs, imm0_7:$rhs),
677249259Sdim            (tADDi3 tGPR:$lhs, imm0_7:$rhs)>;
678249259Sdimdef : T1Pat<(addc   tGPR:$lhs, imm8_255:$rhs),
679249259Sdim            (tADDi8 tGPR:$lhs, imm8_255:$rhs)>;
680249259Sdimdef : T1Pat<(addc   tGPR:$lhs, tGPR:$rhs),
681249259Sdim            (tADDrr tGPR:$lhs, tGPR:$rhs)>;
682249259Sdim
683249259Sdim// Subtract with carry
684249259Sdimdef : T1Pat<(addc   tGPR:$lhs, imm0_7_neg:$rhs),
685249259Sdim            (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>;
686249259Sdimdef : T1Pat<(addc   tGPR:$lhs, imm8_255_neg:$rhs),
687249259Sdim            (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>;
688249259Sdimdef : T1Pat<(subc   tGPR:$lhs, tGPR:$rhs),
689249259Sdim            (tSUBrr tGPR:$lhs, tGPR:$rhs)>;
690249259Sdim
691249259Sdim// ConstantPool, GlobalAddress
692249259Sdimdef : T1Pat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
693249259Sdimdef : T1Pat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
694249259Sdim
695249259Sdim// JumpTable
696249259Sdimdef : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
697249259Sdim            (tLEApcrelJT tjumptable:$dst, imm:$id)>;
698249259Sdim
699249259Sdim// Direct calls
700249259Sdimdef : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>,
701249259Sdim      Requires<[IsThumb, IsNotDarwin]>;
702249259Sdimdef : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>,
703249259Sdim      Requires<[IsThumb, IsDarwin]>;
704249259Sdim
705249259Sdimdef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>,
706249259Sdim      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
707249259Sdimdef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>,
708249259Sdim      Requires<[IsThumb, HasV5T, IsDarwin]>;
709249259Sdim
710249259Sdim// Indirect calls to ARM routines
711249259Sdimdef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>,
712249259Sdim      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
713249259Sdimdef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>,
714249259Sdim      Requires<[IsThumb, HasV5T, IsDarwin]>;
715249259Sdim
716249259Sdim// zextload i1 -> zextload i8
717249259Sdimdef : T1Pat<(zextloadi1 t_addrmode_s1:$addr),
718249259Sdim            (tLDRB t_addrmode_s1:$addr)>;
719249259Sdim
720249259Sdim// extload -> zextload
721249259Sdimdef : T1Pat<(extloadi1  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
722249259Sdimdef : T1Pat<(extloadi8  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
723249259Sdimdef : T1Pat<(extloadi16 t_addrmode_s2:$addr),  (tLDRH t_addrmode_s2:$addr)>;
724249259Sdim
725249259Sdim// If it's impossible to use [r,r] address mode for sextload, select to
726249259Sdim// ldr{b|h} + sxt{b|h} instead.
727249259Sdimdef : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
728249259Sdim            (tSXTB (tLDRB t_addrmode_s1:$addr))>,
729249259Sdim      Requires<[IsThumb1Only, HasV6]>;
730249259Sdimdef : T1Pat<(sextloadi16 t_addrmode_s2:$addr),
731249259Sdim            (tSXTH (tLDRH t_addrmode_s2:$addr))>,
732249259Sdim      Requires<[IsThumb1Only, HasV6]>;
733249259Sdim
734249259Sdimdef : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
735249259Sdim            (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>;
736249259Sdimdef : T1Pat<(sextloadi16 t_addrmode_s1:$addr),
737249259Sdim            (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>;
738249259Sdim
739249259Sdim// Large immediate handling.
740249259Sdim
741249259Sdim// Two piece imms.
742249259Sdimdef : T1Pat<(i32 thumb_immshifted:$src),
743249259Sdim            (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
744249259Sdim                    (thumb_immshifted_shamt imm:$src))>;
745249259Sdim
746249259Sdimdef : T1Pat<(i32 imm0_255_comp:$src),
747249259Sdim            (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
748249259Sdim
749249259Sdim// Pseudo instruction that combines ldr from constpool and add pc. This should
750249259Sdim// be expanded into two instructions late to allow if-conversion and
751249259Sdim// scheduling.
752249259Sdimlet isReMaterializable = 1 in
753249259Sdimdef tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
754249259Sdim                   NoItinerary, "@ ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
755296417Sdim               [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
756296417Sdim                                           imm:$cp))]>,
757296417Sdim               Requires<[IsThumb1Only]>;
758296417Sdim