ARMInstrThumb.td revision 193323
1//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the Thumb instruction set.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// Thumb specific DAG Nodes.
16//
17
18def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall,
19                      [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
20
21def imm_neg_XFORM : SDNodeXForm<imm, [{
22  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
23}]>;
24def imm_comp_XFORM : SDNodeXForm<imm, [{
25  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
26}]>;
27
28
29/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7].
30def imm0_7 : PatLeaf<(i32 imm), [{
31  return (uint32_t)N->getZExtValue() < 8;
32}]>;
33def imm0_7_neg : PatLeaf<(i32 imm), [{
34  return (uint32_t)-N->getZExtValue() < 8;
35}], imm_neg_XFORM>;
36
37def imm0_255 : PatLeaf<(i32 imm), [{
38  return (uint32_t)N->getZExtValue() < 256;
39}]>;
40def imm0_255_comp : PatLeaf<(i32 imm), [{
41  return ~((uint32_t)N->getZExtValue()) < 256;
42}]>;
43
44def imm8_255 : PatLeaf<(i32 imm), [{
45  return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256;
46}]>;
47def imm8_255_neg : PatLeaf<(i32 imm), [{
48  unsigned Val = -N->getZExtValue();
49  return Val >= 8 && Val < 256;
50}], imm_neg_XFORM>;
51
52// Break imm's up into two pieces: an immediate + a left shift.
53// This uses thumb_immshifted to match and thumb_immshifted_val and
54// thumb_immshifted_shamt to get the val/shift pieces.
55def thumb_immshifted : PatLeaf<(imm), [{
56  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
57}]>;
58
59def thumb_immshifted_val : SDNodeXForm<imm, [{
60  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
61  return CurDAG->getTargetConstant(V, MVT::i32);
62}]>;
63
64def thumb_immshifted_shamt : SDNodeXForm<imm, [{
65  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
66  return CurDAG->getTargetConstant(V, MVT::i32);
67}]>;
68
69// Define Thumb specific addressing modes.
70
71// t_addrmode_rr := reg + reg
72//
73def t_addrmode_rr : Operand<i32>,
74                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
75  let PrintMethod = "printThumbAddrModeRROperand";
76  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
77}
78
79// t_addrmode_s4 := reg + reg
80//                  reg + imm5 * 4
81//
82def t_addrmode_s4 : Operand<i32>,
83                    ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
84  let PrintMethod = "printThumbAddrModeS4Operand";
85  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
86}
87
88// t_addrmode_s2 := reg + reg
89//                  reg + imm5 * 2
90//
91def t_addrmode_s2 : Operand<i32>,
92                    ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
93  let PrintMethod = "printThumbAddrModeS2Operand";
94  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
95}
96
97// t_addrmode_s1 := reg + reg
98//                  reg + imm5
99//
100def t_addrmode_s1 : Operand<i32>,
101                    ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
102  let PrintMethod = "printThumbAddrModeS1Operand";
103  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
104}
105
106// t_addrmode_sp := sp + imm8 * 4
107//
108def t_addrmode_sp : Operand<i32>,
109                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
110  let PrintMethod = "printThumbAddrModeSPOperand";
111  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
112}
113
114//===----------------------------------------------------------------------===//
115//  Miscellaneous Instructions.
116//
117
118let Defs = [SP], Uses = [SP] in {
119def tADJCALLSTACKUP :
120PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
121           "@ tADJCALLSTACKUP $amt1",
122           [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb]>;
123
124def tADJCALLSTACKDOWN :
125PseudoInst<(outs), (ins i32imm:$amt),
126           "@ tADJCALLSTACKDOWN $amt",
127           [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb]>;
128}
129
130let isNotDuplicable = 1 in
131def tPICADD : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp),
132                  "$cp:\n\tadd $dst, pc",
133                  [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))]>;
134
135//===----------------------------------------------------------------------===//
136//  Control Flow Instructions.
137//
138
139let isReturn = 1, isTerminator = 1 in {
140  def tBX_RET : TI<(outs), (ins), "bx lr", [(ARMretflag)]>;
141  // Alternative return instruction used by vararg functions.
142  def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), "bx $target", []>;
143}
144
145// FIXME: remove when we have a way to marking a MI with these properties.
146let isReturn = 1, isTerminator = 1 in
147def tPOP_RET : TI<(outs reglist:$dst1, variable_ops), (ins),
148                   "pop $dst1", []>;
149
150let isCall = 1,
151  Defs = [R0, R1, R2, R3, LR,
152          D0, D1, D2, D3, D4, D5, D6, D7] in {
153  def tBL  : TIx2<(outs), (ins i32imm:$func, variable_ops),
154                   "bl ${func:call}",
155                   [(ARMtcall tglobaladdr:$func)]>;
156  // ARMv5T and above
157  def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops),
158                    "blx ${func:call}",
159                    [(ARMcall tglobaladdr:$func)]>, Requires<[HasV5T]>;
160  def tBLXr : TI<(outs), (ins tGPR:$func, variable_ops),
161                  "blx $func",
162                  [(ARMtcall tGPR:$func)]>, Requires<[HasV5T]>;
163  // ARMv4T
164  def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops),
165                  "cpy lr, pc\n\tbx $func",
166                  [(ARMcall_nolink tGPR:$func)]>;
167}
168
169let isBranch = 1, isTerminator = 1 in {
170  let isBarrier = 1 in {
171    let isPredicable = 1 in
172    def tB   : TI<(outs), (ins brtarget:$target), "b $target",
173                  [(br bb:$target)]>;
174
175  // Far jump
176  def tBfar : TIx2<(outs), (ins brtarget:$target), "bl $target\t@ far jump",[]>;
177
178  def tBR_JTr : TJTI<(outs),
179                     (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
180                     "cpy pc, $target \n\t.align\t2\n$jt",
181                     [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
182  }
183}
184
185// FIXME: should be able to write a pattern for ARMBrcond, but can't use
186// a two-value operand where a dag node expects two operands. :(
187let isBranch = 1, isTerminator = 1 in
188  def tBcc : TI<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target",
189                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
190
191//===----------------------------------------------------------------------===//
192//  Load Store Instructions.
193//
194
195let canFoldAsLoad = 1 in
196def tLDR : TI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr),
197               "ldr $dst, $addr",
198               [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
199
200def tLDRB : TI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr),
201                "ldrb $dst, $addr",
202                [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
203
204def tLDRH : TI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr),
205                "ldrh $dst, $addr",
206                [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
207
208def tLDRSB : TI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
209                 "ldrsb $dst, $addr",
210                 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
211
212def tLDRSH : TI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
213                 "ldrsh $dst, $addr",
214                 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
215
216let canFoldAsLoad = 1 in
217def tLDRspi : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
218                  "ldr $dst, $addr",
219                  [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
220
221// Special instruction for restore. It cannot clobber condition register
222// when it's expanded by eliminateCallFramePseudoInstr().
223let canFoldAsLoad = 1, mayLoad = 1 in
224def tRestore : TIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
225                    "ldr $dst, $addr", []>;
226
227// Load tconstpool
228let canFoldAsLoad = 1 in
229def tLDRpci : TIs<(outs tGPR:$dst), (ins i32imm:$addr),
230                  "ldr $dst, $addr",
231                  [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
232
233// Special LDR for loads from non-pc-relative constpools.
234let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
235def tLDRcp  : TIs<(outs tGPR:$dst), (ins i32imm:$addr),
236                  "ldr $dst, $addr", []>;
237
238def tSTR : TI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr),
239               "str $src, $addr",
240               [(store tGPR:$src, t_addrmode_s4:$addr)]>;
241
242def tSTRB : TI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr),
243                 "strb $src, $addr",
244                 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
245
246def tSTRH : TI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr),
247                 "strh $src, $addr",
248                 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
249
250def tSTRspi : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
251                   "str $src, $addr",
252                   [(store tGPR:$src, t_addrmode_sp:$addr)]>;
253
254let mayStore = 1 in {
255// Special instruction for spill. It cannot clobber condition register
256// when it's expanded by eliminateCallFramePseudoInstr().
257def tSpill : TIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
258                  "str $src, $addr", []>;
259}
260
261//===----------------------------------------------------------------------===//
262//  Load / store multiple Instructions.
263//
264
265// TODO: A7-44: LDMIA - load multiple
266
267let mayLoad = 1 in
268def tPOP : TI<(outs reglist:$dst1, variable_ops), (ins),
269               "pop $dst1", []>;
270
271let mayStore = 1 in
272def tPUSH : TI<(outs), (ins reglist:$src1, variable_ops),
273                "push $src1", []>;
274
275//===----------------------------------------------------------------------===//
276//  Arithmetic Instructions.
277//
278
279// Add with carry
280def tADC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
281               "adc $dst, $rhs",
282               [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
283
284def tADDS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
285               "add $dst, $lhs, $rhs",
286               [(set tGPR:$dst, (addc tGPR:$lhs, tGPR:$rhs))]>;
287
288
289def tADDi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
290                "add $dst, $lhs, $rhs",
291                [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
292
293def tADDi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
294                 "add $dst, $rhs",
295                 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
296
297def tADDrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
298                "add $dst, $lhs, $rhs",
299                [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
300
301def tADDhirr : TIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs),
302                   "add $dst, $rhs @ addhirr", []>;
303
304def tADDrPCi : TI<(outs tGPR:$dst), (ins i32imm:$rhs),
305                  "add $dst, pc, $rhs * 4", []>;
306
307def tADDrSPi : TI<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs),
308                  "add $dst, $sp, $rhs * 4 @ addrspi", []>;
309
310def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
311                  "add $dst, $rhs * 4", []>;
312
313def tAND : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
314                "and $dst, $rhs",
315                [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
316
317def tASRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
318                "asr $dst, $lhs, $rhs",
319                [(set tGPR:$dst, (sra tGPR:$lhs, imm:$rhs))]>;
320
321def tASRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
322                 "asr $dst, $rhs",
323                 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
324
325def tBIC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
326               "bic $dst, $rhs",
327               [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
328
329
330def tCMN : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
331              "cmn $lhs, $rhs",
332              [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
333
334def tCMPi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
335               "cmp $lhs, $rhs",
336               [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
337
338def tCMPr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
339               "cmp $lhs, $rhs",
340               [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
341
342def tTST  : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
343               "tst $lhs, $rhs",
344               [(ARMcmpNZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
345
346def tCMNNZ : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
347                "cmn $lhs, $rhs",
348                [(ARMcmpNZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
349
350def tCMPNZi8 : TI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
351                 "cmp $lhs, $rhs",
352                 [(ARMcmpNZ tGPR:$lhs, imm0_255:$rhs)]>;
353
354def tCMPNZr : TI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
355                 "cmp $lhs, $rhs",
356                 [(ARMcmpNZ tGPR:$lhs, tGPR:$rhs)]>;
357
358// TODO: A7-37: CMP(3) - cmp hi regs
359
360def tEOR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
361               "eor $dst, $rhs",
362               [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
363
364def tLSLri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
365                "lsl $dst, $lhs, $rhs",
366                [(set tGPR:$dst, (shl tGPR:$lhs, imm:$rhs))]>;
367
368def tLSLrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
369                 "lsl $dst, $rhs",
370                 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
371
372def tLSRri : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
373                "lsr $dst, $lhs, $rhs",
374                [(set tGPR:$dst, (srl tGPR:$lhs, imm:$rhs))]>;
375
376def tLSRrr : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
377                 "lsr $dst, $rhs",
378                 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
379
380// FIXME: This is not rematerializable because mov changes the condition code.
381def tMOVi8 : TI<(outs tGPR:$dst), (ins i32imm:$src),
382                 "mov $dst, $src",
383                 [(set tGPR:$dst, imm0_255:$src)]>;
384
385// TODO: A7-73: MOV(2) - mov setting flag.
386
387
388// Note: MOV(2) of two low regs updates the flags, so we emit this as 'cpy',
389// which is MOV(3).  This also supports high registers.
390def tMOVr       : TI<(outs tGPR:$dst), (ins tGPR:$src),
391                      "cpy $dst, $src", []>;
392def tMOVhir2lor : TI<(outs tGPR:$dst), (ins GPR:$src),
393                      "cpy $dst, $src\t@ hir2lor", []>;
394def tMOVlor2hir : TI<(outs GPR:$dst), (ins tGPR:$src),
395                      "cpy $dst, $src\t@ lor2hir", []>;
396def tMOVhir2hir : TI<(outs GPR:$dst), (ins GPR:$src),
397                      "cpy $dst, $src\t@ hir2hir", []>;
398
399def tMUL : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
400               "mul $dst, $rhs",
401               [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
402
403def tMVN : TI<(outs tGPR:$dst), (ins tGPR:$src),
404              "mvn $dst, $src",
405              [(set tGPR:$dst, (not tGPR:$src))]>;
406
407def tNEG : TI<(outs tGPR:$dst), (ins tGPR:$src),
408              "neg $dst, $src",
409              [(set tGPR:$dst, (ineg tGPR:$src))]>;
410
411def tORR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
412               "orr $dst, $rhs",
413               [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
414
415
416def tREV : TI<(outs tGPR:$dst), (ins tGPR:$src),
417              "rev $dst, $src",
418              [(set tGPR:$dst, (bswap tGPR:$src))]>,
419              Requires<[IsThumb, HasV6]>;
420
421def tREV16 : TI<(outs tGPR:$dst), (ins tGPR:$src),
422                "rev16 $dst, $src",
423                [(set tGPR:$dst,
424                    (or (and (srl tGPR:$src, 8), 0xFF),
425                        (or (and (shl tGPR:$src, 8), 0xFF00),
426                            (or (and (srl tGPR:$src, 8), 0xFF0000),
427                                (and (shl tGPR:$src, 8), 0xFF000000)))))]>,
428                Requires<[IsThumb, HasV6]>;
429
430def tREVSH : TI<(outs tGPR:$dst), (ins tGPR:$src),
431                "revsh $dst, $src",
432                [(set tGPR:$dst,
433                   (sext_inreg
434                     (or (srl (and tGPR:$src, 0xFFFF), 8),
435                         (shl tGPR:$src, 8)), i16))]>,
436                Requires<[IsThumb, HasV6]>;
437
438def tROR : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
439                "ror $dst, $rhs",
440                [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
441
442
443// Subtract with carry
444def tSBC : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
445                "sbc $dst, $rhs",
446                [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
447
448def tSUBS : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
449                "sub $dst, $lhs, $rhs",
450               [(set tGPR:$dst, (subc tGPR:$lhs, tGPR:$rhs))]>;
451
452
453// TODO: A7-96: STMIA - store multiple.
454
455def tSUBi3 : TI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
456                "sub $dst, $lhs, $rhs",
457                [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
458
459def tSUBi8 : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
460                  "sub $dst, $rhs",
461                  [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
462
463def tSUBrr : TI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
464                "sub $dst, $lhs, $rhs",
465                [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
466
467def tSUBspi : TIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
468                  "sub $dst, $rhs * 4", []>;
469
470def tSXTB  : TI<(outs tGPR:$dst), (ins tGPR:$src),
471                "sxtb $dst, $src",
472                [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
473                Requires<[IsThumb, HasV6]>;
474def tSXTH  : TI<(outs tGPR:$dst), (ins tGPR:$src),
475                "sxth $dst, $src",
476                [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
477                Requires<[IsThumb, HasV6]>;
478
479
480def tUXTB  : TI<(outs tGPR:$dst), (ins tGPR:$src),
481                "uxtb $dst, $src",
482                [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
483                Requires<[IsThumb, HasV6]>;
484def tUXTH  : TI<(outs tGPR:$dst), (ins tGPR:$src),
485                "uxth $dst, $src",
486                [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
487                Requires<[IsThumb, HasV6]>;
488
489
490// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
491// Expanded by the scheduler into a branch sequence.
492let usesCustomDAGSchedInserter = 1 in  // Expanded by the scheduler.
493  def tMOVCCr :
494  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
495              "@ tMOVCCr $cc",
496              [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
497
498// tLEApcrel - Load a pc-relative address into a register without offending the
499// assembler.
500def tLEApcrel : TIx2<(outs tGPR:$dst), (ins i32imm:$label),
501                    !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
502                                          "${:private}PCRELL${:uid}+4))\n"),
503                               !strconcat("\tmov $dst, #PCRELV${:uid}\n",
504                                  "${:private}PCRELL${:uid}:\n\tadd $dst, pc")),
505                    []>;
506
507def tLEApcrelJT : TIx2<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id),
508          !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
509                                         "${:private}PCRELL${:uid}+4))\n"),
510                     !strconcat("\tmov $dst, #PCRELV${:uid}\n",
511                                "${:private}PCRELL${:uid}:\n\tadd $dst, pc")),
512                    []>;
513
514//===----------------------------------------------------------------------===//
515// TLS Instructions
516//
517
518// __aeabi_read_tp preserves the registers r1-r3.
519let isCall = 1,
520  Defs = [R0, LR] in {
521  def tTPsoft  : TIx2<(outs), (ins),
522               "bl __aeabi_read_tp",
523               [(set R0, ARMthread_pointer)]>;
524}
525
526//===----------------------------------------------------------------------===//
527// Non-Instruction Patterns
528//
529
530// ConstantPool, GlobalAddress
531def : ThumbPat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
532def : ThumbPat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
533
534// JumpTable
535def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
536               (tLEApcrelJT tjumptable:$dst, imm:$id)>;
537
538// Direct calls
539def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
540def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
541
542// Indirect calls to ARM routines
543def : ThumbV5Pat<(ARMcall tGPR:$dst), (tBLXr tGPR:$dst)>;
544
545// zextload i1 -> zextload i8
546def : ThumbPat<(zextloadi1 t_addrmode_s1:$addr),
547               (tLDRB t_addrmode_s1:$addr)>;
548
549// extload -> zextload
550def : ThumbPat<(extloadi1  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
551def : ThumbPat<(extloadi8  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
552def : ThumbPat<(extloadi16 t_addrmode_s2:$addr),  (tLDRH t_addrmode_s2:$addr)>;
553
554// Large immediate handling.
555
556// Two piece imms.
557def : ThumbPat<(i32 thumb_immshifted:$src),
558               (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
559                       (thumb_immshifted_shamt imm:$src))>;
560
561def : ThumbPat<(i32 imm0_255_comp:$src),
562               (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
563