ARMInstrThumb.td revision 198090
1193323Sed//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file describes the Thumb instruction set.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed// Thumb specific DAG Nodes.
16193323Sed//
17193323Sed
18193323Seddef ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall,
19193323Sed                      [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
20193323Sed
21193323Seddef imm_neg_XFORM : SDNodeXForm<imm, [{
22193323Sed  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
23193323Sed}]>;
24193323Seddef imm_comp_XFORM : SDNodeXForm<imm, [{
25193323Sed  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
26193323Sed}]>;
27193323Sed
28193323Sed
29193323Sed/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7].
30193323Seddef imm0_7 : PatLeaf<(i32 imm), [{
31193323Sed  return (uint32_t)N->getZExtValue() < 8;
32193323Sed}]>;
33193323Seddef imm0_7_neg : PatLeaf<(i32 imm), [{
34193323Sed  return (uint32_t)-N->getZExtValue() < 8;
35193323Sed}], imm_neg_XFORM>;
36193323Sed
37193323Seddef imm0_255 : PatLeaf<(i32 imm), [{
38193323Sed  return (uint32_t)N->getZExtValue() < 256;
39193323Sed}]>;
40193323Seddef imm0_255_comp : PatLeaf<(i32 imm), [{
41193323Sed  return ~((uint32_t)N->getZExtValue()) < 256;
42193323Sed}]>;
43193323Sed
44193323Seddef imm8_255 : PatLeaf<(i32 imm), [{
45193323Sed  return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256;
46193323Sed}]>;
47193323Seddef imm8_255_neg : PatLeaf<(i32 imm), [{
48193323Sed  unsigned Val = -N->getZExtValue();
49193323Sed  return Val >= 8 && Val < 256;
50193323Sed}], imm_neg_XFORM>;
51193323Sed
52193323Sed// Break imm's up into two pieces: an immediate + a left shift.
53193323Sed// This uses thumb_immshifted to match and thumb_immshifted_val and
54193323Sed// thumb_immshifted_shamt to get the val/shift pieces.
55193323Seddef thumb_immshifted : PatLeaf<(imm), [{
56193323Sed  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
57193323Sed}]>;
58193323Sed
59193323Seddef thumb_immshifted_val : SDNodeXForm<imm, [{
60193323Sed  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
61193323Sed  return CurDAG->getTargetConstant(V, MVT::i32);
62193323Sed}]>;
63193323Sed
64193323Seddef thumb_immshifted_shamt : SDNodeXForm<imm, [{
65193323Sed  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
66193323Sed  return CurDAG->getTargetConstant(V, MVT::i32);
67193323Sed}]>;
68193323Sed
69193323Sed// Define Thumb specific addressing modes.
70193323Sed
71193323Sed// t_addrmode_rr := reg + reg
72193323Sed//
73193323Seddef t_addrmode_rr : Operand<i32>,
74193323Sed                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
75193323Sed  let PrintMethod = "printThumbAddrModeRROperand";
76193323Sed  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
77193323Sed}
78193323Sed
79193323Sed// t_addrmode_s4 := reg + reg
80193323Sed//                  reg + imm5 * 4
81193323Sed//
82193323Seddef t_addrmode_s4 : Operand<i32>,
83193323Sed                    ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
84193323Sed  let PrintMethod = "printThumbAddrModeS4Operand";
85193323Sed  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
86193323Sed}
87193323Sed
88193323Sed// t_addrmode_s2 := reg + reg
89193323Sed//                  reg + imm5 * 2
90193323Sed//
91193323Seddef t_addrmode_s2 : Operand<i32>,
92193323Sed                    ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
93193323Sed  let PrintMethod = "printThumbAddrModeS2Operand";
94193323Sed  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
95193323Sed}
96193323Sed
97193323Sed// t_addrmode_s1 := reg + reg
98193323Sed//                  reg + imm5
99193323Sed//
100193323Seddef t_addrmode_s1 : Operand<i32>,
101193323Sed                    ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
102193323Sed  let PrintMethod = "printThumbAddrModeS1Operand";
103193323Sed  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
104193323Sed}
105193323Sed
106193323Sed// t_addrmode_sp := sp + imm8 * 4
107193323Sed//
108193323Seddef t_addrmode_sp : Operand<i32>,
109193323Sed                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
110193323Sed  let PrintMethod = "printThumbAddrModeSPOperand";
111193323Sed  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
112193323Sed}
113193323Sed
114193323Sed//===----------------------------------------------------------------------===//
115193323Sed//  Miscellaneous Instructions.
116193323Sed//
117193323Sed
118193323Sedlet Defs = [SP], Uses = [SP] in {
119193323Seddef tADJCALLSTACKUP :
120198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
121193323Sed           "@ tADJCALLSTACKUP $amt1",
122198090Srdivacky           [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>;
123193323Sed
124193323Seddef tADJCALLSTACKDOWN :
125198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
126193323Sed           "@ tADJCALLSTACKDOWN $amt",
127198090Srdivacky           [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
128193323Sed}
129193323Sed
130198090Srdivacky// For both thumb1 and thumb2.
131193323Sedlet isNotDuplicable = 1 in
132198090Srdivackydef tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
133198090Srdivacky                 "\n$cp:\n\tadd $dst, pc",
134198090Srdivacky                 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
135193323Sed
136195098Sed// PC relative add.
137198090Srdivackydef tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi,
138195098Sed                  "add $dst, pc, $rhs * 4", []>;
139195098Sed
140195098Sed// ADD rd, sp, #imm8
141198090Srdivackydef tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALUi,
142198090Srdivacky                  "add $dst, $sp, $rhs * 4", []>;
143195098Sed
144195098Sed// ADD sp, sp, #imm7
145198090Srdivackydef tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi,
146195098Sed                  "add $dst, $rhs * 4", []>;
147195098Sed
148198090Srdivacky// SUB sp, sp, #imm7
149198090Srdivackydef tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi,
150198090Srdivacky                  "sub $dst, $rhs * 4", []>;
151198090Srdivacky
152198090Srdivacky// ADD rm, sp
153198090Srdivackydef tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
154198090Srdivacky                  "add $dst, $rhs", []>;
155198090Srdivacky
156195098Sed// ADD sp, rm
157198090Srdivackydef tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
158198090Srdivacky                  "add $dst, $rhs", []>;
159195098Sed
160198090Srdivacky// Pseudo instruction that will expand into a tSUBspi + a copy.
161198090Srdivackylet usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
162198090Srdivackydef tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
163198090Srdivacky               NoItinerary, "@ sub $dst, $rhs * 4", []>;
164198090Srdivacky
165198090Srdivackydef tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
166198090Srdivacky               NoItinerary, "@ add $dst, $rhs", []>;
167198090Srdivacky
168198090Srdivackylet Defs = [CPSR] in
169198090Srdivackydef tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
170198090Srdivacky             NoItinerary, "@ and $dst, $rhs", []>;
171198090Srdivacky} // usesCustomDAGSchedInserter
172198090Srdivacky
173193323Sed//===----------------------------------------------------------------------===//
174193323Sed//  Control Flow Instructions.
175193323Sed//
176193323Sed
177198090Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1 in {
178198090Srdivacky  def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>;
179193323Sed  // Alternative return instruction used by vararg functions.
180198090Srdivacky  def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx $target", []>;
181193323Sed}
182193323Sed
183193323Sed// FIXME: remove when we have a way to marking a MI with these properties.
184198090Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
185198090Srdivacky    hasExtraDefRegAllocReq = 1 in
186198090Srdivackydef tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
187198090Srdivacky                   "pop${p} $wb", []>;
188193323Sed
189193323Sedlet isCall = 1,
190198090Srdivacky  Defs = [R0,  R1,  R2,  R3,  R12, LR,
191198090Srdivacky          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
192198090Srdivacky          D16, D17, D18, D19, D20, D21, D22, D23,
193198090Srdivacky          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
194198090Srdivacky  // Also used for Thumb2
195198090Srdivacky  def tBL  : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
196193323Sed                   "bl ${func:call}",
197198090Srdivacky                   [(ARMtcall tglobaladdr:$func)]>,
198198090Srdivacky             Requires<[IsThumb, IsNotDarwin]>;
199198090Srdivacky
200198090Srdivacky  // ARMv5T and above, also used for Thumb2
201198090Srdivacky  def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
202193323Sed                    "blx ${func:call}",
203198090Srdivacky                    [(ARMcall tglobaladdr:$func)]>,
204198090Srdivacky              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
205198090Srdivacky
206198090Srdivacky  // Also used for Thumb2
207198090Srdivacky  def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
208193323Sed                  "blx $func",
209198090Srdivacky                  [(ARMtcall GPR:$func)]>,
210198090Srdivacky              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
211198090Srdivacky
212193323Sed  // ARMv4T
213198090Srdivacky  def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
214198090Srdivacky                  "mov lr, pc\n\tbx $func",
215198090Srdivacky                  [(ARMcall_nolink tGPR:$func)]>,
216198090Srdivacky            Requires<[IsThumb1Only, IsNotDarwin]>;
217193323Sed}
218193323Sed
219198090Srdivacky// On Darwin R9 is call-clobbered.
220198090Srdivackylet isCall = 1,
221198090Srdivacky  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR,
222198090Srdivacky          D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,
223198090Srdivacky          D16, D17, D18, D19, D20, D21, D22, D23,
224198090Srdivacky          D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
225198090Srdivacky  // Also used for Thumb2
226198090Srdivacky  def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
227198090Srdivacky                   "bl ${func:call}",
228198090Srdivacky                   [(ARMtcall tglobaladdr:$func)]>,
229198090Srdivacky              Requires<[IsThumb, IsDarwin]>;
230198090Srdivacky
231198090Srdivacky  // ARMv5T and above, also used for Thumb2
232198090Srdivacky  def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
233198090Srdivacky                      "blx ${func:call}",
234198090Srdivacky                      [(ARMcall tglobaladdr:$func)]>,
235198090Srdivacky                 Requires<[IsThumb, HasV5T, IsDarwin]>;
236198090Srdivacky
237198090Srdivacky  // Also used for Thumb2
238198090Srdivacky  def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
239198090Srdivacky                  "blx $func",
240198090Srdivacky                  [(ARMtcall GPR:$func)]>,
241198090Srdivacky                 Requires<[IsThumb, HasV5T, IsDarwin]>;
242198090Srdivacky
243198090Srdivacky  // ARMv4T
244198090Srdivacky  def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
245198090Srdivacky                  "mov lr, pc\n\tbx $func",
246198090Srdivacky                  [(ARMcall_nolink tGPR:$func)]>,
247198090Srdivacky              Requires<[IsThumb1Only, IsDarwin]>;
248198090Srdivacky}
249198090Srdivacky
250193323Sedlet isBranch = 1, isTerminator = 1 in {
251193323Sed  let isBarrier = 1 in {
252193323Sed    let isPredicable = 1 in
253198090Srdivacky    def tB   : T1I<(outs), (ins brtarget:$target), IIC_Br,
254198090Srdivacky                   "b $target", [(br bb:$target)]>;
255193323Sed
256193323Sed  // Far jump
257198090Srdivacky  let Defs = [LR] in
258198090Srdivacky  def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 
259195340Sed                    "bl $target\t@ far jump",[]>;
260193323Sed
261195340Sed  def tBR_JTr : T1JTI<(outs),
262195340Sed                      (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
263198090Srdivacky                      IIC_Br, "mov pc, $target\n\t.align\t2\n$jt",
264195340Sed                      [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
265193323Sed  }
266193323Sed}
267193323Sed
268193323Sed// FIXME: should be able to write a pattern for ARMBrcond, but can't use
269193323Sed// a two-value operand where a dag node expects two operands. :(
270193323Sedlet isBranch = 1, isTerminator = 1 in
271198090Srdivacky  def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br,
272198090Srdivacky                 "b$cc $target",
273193323Sed                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
274193323Sed
275193323Sed//===----------------------------------------------------------------------===//
276193323Sed//  Load Store Instructions.
277193323Sed//
278193323Sed
279193323Sedlet canFoldAsLoad = 1 in
280198090Srdivackydef tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 
281198090Srdivacky               "ldr", " $dst, $addr",
282193323Sed               [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
283193323Sed
284198090Srdivackydef tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
285198090Srdivacky                "ldrb", " $dst, $addr",
286193323Sed                [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
287193323Sed
288198090Srdivackydef tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
289198090Srdivacky                "ldrh", " $dst, $addr",
290193323Sed                [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
291193323Sed
292198090Srdivackylet AddedComplexity = 10 in
293198090Srdivackydef tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
294198090Srdivacky                 "ldrsb", " $dst, $addr",
295193323Sed                 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
296193323Sed
297198090Srdivackylet AddedComplexity = 10 in
298198090Srdivackydef tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
299198090Srdivacky                 "ldrsh", " $dst, $addr",
300193323Sed                 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
301193323Sed
302193323Sedlet canFoldAsLoad = 1 in
303198090Srdivackydef tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
304198090Srdivacky                  "ldr", " $dst, $addr",
305193323Sed                  [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
306193323Sed
307193323Sed// Special instruction for restore. It cannot clobber condition register
308193323Sed// when it's expanded by eliminateCallFramePseudoInstr().
309193323Sedlet canFoldAsLoad = 1, mayLoad = 1 in
310198090Srdivackydef tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
311198090Srdivacky                    "ldr", " $dst, $addr", []>;
312193323Sed
313193323Sed// Load tconstpool
314193323Sedlet canFoldAsLoad = 1 in
315198090Srdivackydef tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
316198090Srdivacky                  "ldr", " $dst, $addr",
317193323Sed                  [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
318193323Sed
319193323Sed// Special LDR for loads from non-pc-relative constpools.
320193323Sedlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
321198090Srdivackydef tLDRcp  : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
322198090Srdivacky                  "ldr", " $dst, $addr", []>;
323193323Sed
324198090Srdivackydef tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
325198090Srdivacky               "str", " $src, $addr",
326193323Sed               [(store tGPR:$src, t_addrmode_s4:$addr)]>;
327193323Sed
328198090Srdivackydef tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
329198090Srdivacky                 "strb", " $src, $addr",
330193323Sed                 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
331193323Sed
332198090Srdivackydef tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
333198090Srdivacky                 "strh", " $src, $addr",
334193323Sed                 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
335193323Sed
336198090Srdivackydef tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
337198090Srdivacky                   "str", " $src, $addr",
338193323Sed                   [(store tGPR:$src, t_addrmode_sp:$addr)]>;
339193323Sed
340193323Sedlet mayStore = 1 in {
341193323Sed// Special instruction for spill. It cannot clobber condition register
342193323Sed// when it's expanded by eliminateCallFramePseudoInstr().
343198090Srdivackydef tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
344198090Srdivacky                  "str", " $src, $addr", []>;
345193323Sed}
346193323Sed
347193323Sed//===----------------------------------------------------------------------===//
348193323Sed//  Load / store multiple Instructions.
349193323Sed//
350193323Sed
351198090Srdivacky// These requires base address to be written back or one of the loaded regs.
352198090Srdivackylet mayLoad = 1, hasExtraDefRegAllocReq = 1 in
353198090Srdivackydef tLDM : T1I<(outs),
354198090Srdivacky               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
355198090Srdivacky               IIC_iLoadm,
356198090Srdivacky               "ldm${addr:submode}${p} $addr, $wb", []>;
357193323Sed
358198090Srdivackylet mayStore = 1, hasExtraSrcRegAllocReq = 1 in
359198090Srdivackydef tSTM : T1I<(outs),
360198090Srdivacky               (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
361198090Srdivacky               IIC_iStorem,
362198090Srdivacky               "stm${addr:submode}${p} $addr, $wb", []>;
363193323Sed
364198090Srdivackylet mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
365198090Srdivackydef tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
366198090Srdivacky               "pop${p} $wb", []>;
367193323Sed
368198090Srdivackylet mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
369198090Srdivackydef tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
370198090Srdivacky                "push${p} $wb", []>;
371198090Srdivacky
372193323Sed//===----------------------------------------------------------------------===//
373193323Sed//  Arithmetic Instructions.
374193323Sed//
375193323Sed
376195098Sed// Add with carry register
377198090Srdivackylet isCommutable = 1, Uses = [CPSR] in
378198090Srdivackydef tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
379198090Srdivacky                 "adc", " $dst, $rhs",
380198090Srdivacky                 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
381193323Sed
382195098Sed// Add immediate
383198090Srdivackydef tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
384198090Srdivacky                   "add", " $dst, $lhs, $rhs",
385198090Srdivacky                   [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
386193323Sed
387198090Srdivackydef tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
388198090Srdivacky                   "add", " $dst, $rhs",
389198090Srdivacky                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
390193323Sed
391195098Sed// Add register
392198090Srdivackylet isCommutable = 1 in
393198090Srdivackydef tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
394198090Srdivacky                   "add", " $dst, $lhs, $rhs",
395198090Srdivacky                   [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
396193323Sed
397194178Sedlet neverHasSideEffects = 1 in
398198090Srdivackydef tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
399198090Srdivacky                     "add", " $dst, $rhs", []>;
400193323Sed
401195098Sed// And register
402198090Srdivackylet isCommutable = 1 in
403198090Srdivackydef tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
404198090Srdivacky                 "and", " $dst, $rhs",
405198090Srdivacky                 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
406193323Sed
407195098Sed// ASR immediate
408198090Srdivackydef tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
409198090Srdivacky                  "asr", " $dst, $lhs, $rhs",
410198090Srdivacky                  [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
411193323Sed
412195098Sed// ASR register
413198090Srdivackydef tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
414198090Srdivacky                   "asr", " $dst, $rhs",
415198090Srdivacky                   [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
416193323Sed
417195098Sed// BIC register
418198090Srdivackydef tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
419198090Srdivacky                 "bic", " $dst, $rhs",
420198090Srdivacky                 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
421193323Sed
422195098Sed// CMN register
423195098Sedlet Defs = [CPSR] in {
424198090Srdivackydef tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
425198090Srdivacky                "cmn", " $lhs, $rhs",
426198090Srdivacky                [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
427198090Srdivackydef tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
428198090Srdivacky                 "cmn", " $lhs, $rhs",
429198090Srdivacky                 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
430195098Sed}
431193323Sed
432195098Sed// CMP immediate
433195098Sedlet Defs = [CPSR] in {
434198090Srdivackydef tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
435198090Srdivacky                  "cmp", " $lhs, $rhs",
436198090Srdivacky                  [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
437198090Srdivackydef tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
438198090Srdivacky                  "cmp", " $lhs, $rhs",
439198090Srdivacky                  [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
440193323Sed
441195098Sed}
442195098Sed
443195098Sed// CMP register
444195098Sedlet Defs = [CPSR] in {
445198090Srdivackydef tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
446198090Srdivacky                 "cmp", " $lhs, $rhs",
447198090Srdivacky                 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
448198090Srdivackydef tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
449198090Srdivacky                  "cmp", " $lhs, $rhs",
450198090Srdivacky                  [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
451198090Srdivacky
452198090Srdivackydef tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
453198090Srdivacky                   "cmp", " $lhs, $rhs", []>;
454198090Srdivackydef tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
455198090Srdivacky                    "cmp", " $lhs, $rhs", []>;
456195098Sed}
457193323Sed
458193323Sed
459195098Sed// XOR register
460198090Srdivackylet isCommutable = 1 in
461198090Srdivackydef tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
462198090Srdivacky                 "eor", " $dst, $rhs",
463198090Srdivacky                 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
464193323Sed
465195098Sed// LSL immediate
466198090Srdivackydef tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
467198090Srdivacky                  "lsl", " $dst, $lhs, $rhs",
468198090Srdivacky                  [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
469193323Sed
470195098Sed// LSL register
471198090Srdivackydef tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
472198090Srdivacky                   "lsl", " $dst, $rhs",
473198090Srdivacky                   [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
474193323Sed
475195098Sed// LSR immediate
476198090Srdivackydef tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
477198090Srdivacky                  "lsr", " $dst, $lhs, $rhs",
478198090Srdivacky                  [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
479193323Sed
480195098Sed// LSR register
481198090Srdivackydef tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
482198090Srdivacky                   "lsr", " $dst, $rhs",
483198090Srdivacky                   [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
484193323Sed
485195098Sed// move register
486198090Srdivackydef tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
487198090Srdivacky                  "mov", " $dst, $src",
488198090Srdivacky                  [(set tGPR:$dst, imm0_255:$src)]>;
489193323Sed
490193323Sed// TODO: A7-73: MOV(2) - mov setting flag.
491193323Sed
492193323Sed
493194178Sedlet neverHasSideEffects = 1 in {
494198090Srdivacky// FIXME: Make this predicable.
495198090Srdivackydef tMOVr       : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
496198090Srdivacky                      "mov $dst, $src", []>;
497198090Srdivackylet Defs = [CPSR] in
498198090Srdivackydef tMOVSr      : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
499198090Srdivacky                       "movs $dst, $src", []>;
500198090Srdivacky
501198090Srdivacky// FIXME: Make these predicable.
502198090Srdivackydef tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr,
503198090Srdivacky                       "mov $dst, $src", []>;
504198090Srdivackydef tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr,
505198090Srdivacky                       "mov $dst, $src", []>;
506198090Srdivackydef tMOVgpr2gpr  : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
507198090Srdivacky                       "mov $dst, $src", []>;
508194178Sed} // neverHasSideEffects
509193323Sed
510195098Sed// multiply register
511198090Srdivackylet isCommutable = 1 in
512198090Srdivackydef tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32,
513198090Srdivacky                 "mul", " $dst, $rhs",
514198090Srdivacky                 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
515193323Sed
516195098Sed// move inverse register
517198090Srdivackydef tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
518198090Srdivacky                "mvn", " $dst, $src",
519198090Srdivacky                [(set tGPR:$dst, (not tGPR:$src))]>;
520193323Sed
521195098Sed// bitwise or register
522198090Srdivackylet isCommutable = 1 in
523198090Srdivackydef tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),  IIC_iALUr,
524198090Srdivacky                 "orr", " $dst, $rhs",
525198090Srdivacky                 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
526193323Sed
527195098Sed// swaps
528198090Srdivackydef tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
529198090Srdivacky                "rev", " $dst, $src",
530198090Srdivacky                [(set tGPR:$dst, (bswap tGPR:$src))]>,
531198090Srdivacky                Requires<[IsThumb1Only, HasV6]>;
532193323Sed
533198090Srdivackydef tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
534198090Srdivacky                  "rev16", " $dst, $src",
535198090Srdivacky             [(set tGPR:$dst,
536198090Srdivacky                   (or (and (srl tGPR:$src, (i32 8)), 0xFF),
537198090Srdivacky                       (or (and (shl tGPR:$src, (i32 8)), 0xFF00),
538198090Srdivacky                           (or (and (srl tGPR:$src, (i32 8)), 0xFF0000),
539198090Srdivacky                               (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
540198090Srdivacky                Requires<[IsThumb1Only, HasV6]>;
541193323Sed
542198090Srdivackydef tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
543198090Srdivacky                  "revsh", " $dst, $src",
544198090Srdivacky                  [(set tGPR:$dst,
545198090Srdivacky                        (sext_inreg
546198090Srdivacky                          (or (srl (and tGPR:$src, 0xFF00), (i32 8)),
547198090Srdivacky                              (shl tGPR:$src, (i32 8))), i16))]>,
548198090Srdivacky                  Requires<[IsThumb1Only, HasV6]>;
549193323Sed
550195098Sed// rotate right register
551198090Srdivackydef tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
552198090Srdivacky                 "ror", " $dst, $rhs",
553198090Srdivacky                 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
554193323Sed
555198090Srdivacky// negate register
556198090Srdivackydef tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi,
557198090Srdivacky                "rsb", " $dst, $src, #0",
558198090Srdivacky                [(set tGPR:$dst, (ineg tGPR:$src))]>;
559198090Srdivacky
560195098Sed// Subtract with carry register
561198090Srdivackylet Uses = [CPSR] in
562198090Srdivackydef tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
563198090Srdivacky                 "sbc", " $dst, $rhs",
564198090Srdivacky                 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
565193323Sed
566195098Sed// Subtract immediate
567198090Srdivackydef tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
568198090Srdivacky                  "sub", " $dst, $lhs, $rhs",
569198090Srdivacky                  [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
570193323Sed
571198090Srdivackydef tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
572198090Srdivacky                   "sub", " $dst, $rhs",
573198090Srdivacky                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
574193323Sed
575195098Sed// subtract register
576198090Srdivackydef tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
577198090Srdivacky                  "sub", " $dst, $lhs, $rhs",
578198090Srdivacky                  [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
579193323Sed
580195098Sed// TODO: A7-96: STMIA - store multiple.
581195098Sed
582195098Sed// sign-extend byte
583198090Srdivackydef tSXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
584198090Srdivacky                  "sxtb", " $dst, $src",
585198090Srdivacky                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
586198090Srdivacky                  Requires<[IsThumb1Only, HasV6]>;
587195098Sed
588195098Sed// sign-extend short
589198090Srdivackydef tSXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
590198090Srdivacky                  "sxth", " $dst, $src",
591198090Srdivacky                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
592198090Srdivacky                  Requires<[IsThumb1Only, HasV6]>;
593193323Sed
594195098Sed// test
595195098Sedlet isCommutable = 1, Defs = [CPSR] in
596198090Srdivackydef tTST  : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
597198090Srdivacky                 "tst", " $lhs, $rhs",
598198090Srdivacky                 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
599193323Sed
600195098Sed// zero-extend byte
601198090Srdivackydef tUXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
602198090Srdivacky                  "uxtb", " $dst, $src",
603198090Srdivacky                  [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
604198090Srdivacky                  Requires<[IsThumb1Only, HasV6]>;
605195098Sed
606195098Sed// zero-extend short
607198090Srdivackydef tUXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
608198090Srdivacky                  "uxth", " $dst, $src",
609198090Srdivacky                  [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
610198090Srdivacky                  Requires<[IsThumb1Only, HasV6]>;
611193323Sed
612193323Sed
613193323Sed// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
614193323Sed// Expanded by the scheduler into a branch sequence.
615193323Sedlet usesCustomDAGSchedInserter = 1 in  // Expanded by the scheduler.
616198090Srdivacky  def tMOVCCr_pseudo :
617193323Sed  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
618198090Srdivacky              NoItinerary, "@ tMOVCCr $cc",
619198090Srdivacky             [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
620193323Sed
621198090Srdivacky
622198090Srdivacky// 16-bit movcc in IT blocks for Thumb2.
623198090Srdivackydef tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
624198090Srdivacky                    "mov", " $dst, $rhs", []>;
625198090Srdivacky
626198090Srdivackydef tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
627198090Srdivacky                    "mov", " $dst, $rhs", []>;
628198090Srdivacky
629193323Sed// tLEApcrel - Load a pc-relative address into a register without offending the
630193323Sed// assembler.
631198090Srdivackydef tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
632198090Srdivacky                    "adr$p $dst, #$label", []>;
633193323Sed
634198090Srdivackydef tLEApcrelJT : T1I<(outs tGPR:$dst),
635198090Srdivacky                      (ins i32imm:$label, nohash_imm:$id, pred:$p),
636198090Srdivacky                      IIC_iALUi, "adr$p $dst, #${label}_${id}", []>;
637193323Sed
638193323Sed//===----------------------------------------------------------------------===//
639193323Sed// TLS Instructions
640193323Sed//
641193323Sed
642193323Sed// __aeabi_read_tp preserves the registers r1-r3.
643193323Sedlet isCall = 1,
644193323Sed  Defs = [R0, LR] in {
645198090Srdivacky  def tTPsoft  : TIx2<(outs), (ins), IIC_Br,
646193323Sed               "bl __aeabi_read_tp",
647193323Sed               [(set R0, ARMthread_pointer)]>;
648193323Sed}
649193323Sed
650193323Sed//===----------------------------------------------------------------------===//
651193323Sed// Non-Instruction Patterns
652193323Sed//
653193323Sed
654198090Srdivacky// Add with carry
655198090Srdivackydef : T1Pat<(addc   tGPR:$lhs, imm0_7:$rhs),
656198090Srdivacky            (tADDi3 tGPR:$lhs, imm0_7:$rhs)>;
657198090Srdivackydef : T1Pat<(addc   tGPR:$lhs, imm8_255:$rhs),
658198090Srdivacky            (tADDi8 tGPR:$lhs, imm8_255:$rhs)>;
659198090Srdivackydef : T1Pat<(addc   tGPR:$lhs, tGPR:$rhs),
660198090Srdivacky            (tADDrr tGPR:$lhs, tGPR:$rhs)>;
661198090Srdivacky
662198090Srdivacky// Subtract with carry
663198090Srdivackydef : T1Pat<(addc   tGPR:$lhs, imm0_7_neg:$rhs),
664198090Srdivacky            (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>;
665198090Srdivackydef : T1Pat<(addc   tGPR:$lhs, imm8_255_neg:$rhs),
666198090Srdivacky            (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>;
667198090Srdivackydef : T1Pat<(subc   tGPR:$lhs, tGPR:$rhs),
668198090Srdivacky            (tSUBrr tGPR:$lhs, tGPR:$rhs)>;
669198090Srdivacky
670193323Sed// ConstantPool, GlobalAddress
671198090Srdivackydef : T1Pat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
672198090Srdivackydef : T1Pat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
673193323Sed
674193323Sed// JumpTable
675198090Srdivackydef : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
676198090Srdivacky            (tLEApcrelJT tjumptable:$dst, imm:$id)>;
677193323Sed
678193323Sed// Direct calls
679198090Srdivackydef : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>,
680198090Srdivacky      Requires<[IsThumb, IsNotDarwin]>;
681198090Srdivackydef : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>,
682198090Srdivacky      Requires<[IsThumb, IsDarwin]>;
683193323Sed
684198090Srdivackydef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>,
685198090Srdivacky      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
686198090Srdivackydef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>,
687198090Srdivacky      Requires<[IsThumb, HasV5T, IsDarwin]>;
688198090Srdivacky
689193323Sed// Indirect calls to ARM routines
690198090Srdivackydef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>,
691198090Srdivacky      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
692198090Srdivackydef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>,
693198090Srdivacky      Requires<[IsThumb, HasV5T, IsDarwin]>;
694193323Sed
695193323Sed// zextload i1 -> zextload i8
696195340Seddef : T1Pat<(zextloadi1 t_addrmode_s1:$addr),
697195340Sed            (tLDRB t_addrmode_s1:$addr)>;
698193323Sed
699193323Sed// extload -> zextload
700195340Seddef : T1Pat<(extloadi1  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
701195340Seddef : T1Pat<(extloadi8  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
702195340Seddef : T1Pat<(extloadi16 t_addrmode_s2:$addr),  (tLDRH t_addrmode_s2:$addr)>;
703193323Sed
704198090Srdivacky// If it's impossible to use [r,r] address mode for sextload, select to
705198090Srdivacky// ldr{b|h} + sxt{b|h} instead.
706198090Srdivackydef : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
707198090Srdivacky            (tSXTB (tLDRB t_addrmode_s1:$addr))>,
708198090Srdivacky      Requires<[IsThumb1Only, HasV6]>;
709198090Srdivackydef : T1Pat<(sextloadi16 t_addrmode_s2:$addr),
710198090Srdivacky            (tSXTH (tLDRH t_addrmode_s2:$addr))>,
711198090Srdivacky      Requires<[IsThumb1Only, HasV6]>;
712198090Srdivacky
713198090Srdivackydef : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
714198090Srdivacky            (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>;
715198090Srdivackydef : T1Pat<(sextloadi16 t_addrmode_s1:$addr),
716198090Srdivacky            (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>;
717198090Srdivacky
718193323Sed// Large immediate handling.
719193323Sed
720193323Sed// Two piece imms.
721195098Seddef : T1Pat<(i32 thumb_immshifted:$src),
722195098Sed            (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
723195098Sed                    (thumb_immshifted_shamt imm:$src))>;
724193323Sed
725195098Seddef : T1Pat<(i32 imm0_255_comp:$src),
726195098Sed            (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
727