xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMInstrThumb.td (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
1//===-- ARMInstrThumb.td - Thumb support for ARM -----------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the Thumb instruction set.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// Thumb specific DAG Nodes.
15//
16
17def imm_sr_XFORM: SDNodeXForm<imm, [{
18  unsigned Imm = N->getZExtValue();
19  return CurDAG->getTargetConstant((Imm == 32 ? 0 : Imm), SDLoc(N), MVT::i32);
20}]>;
21def ThumbSRImmAsmOperand: ImmAsmOperand<1,32> { let Name = "ImmThumbSR"; }
22def imm_sr : Operand<i32>, PatLeaf<(imm), [{
23  uint64_t Imm = N->getZExtValue();
24  return Imm > 0 && Imm <= 32;
25}], imm_sr_XFORM> {
26  let PrintMethod = "printThumbSRImm";
27  let ParserMatchClass = ThumbSRImmAsmOperand;
28}
29
30def imm0_7_neg : PatLeaf<(i32 imm), [{
31  return (uint32_t)-N->getZExtValue() < 8;
32}], imm_neg_XFORM>;
33
34def ThumbModImmNeg1_7AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg1_7"; }
35def mod_imm1_7_neg : Operand<i32>, PatLeaf<(imm), [{
36    unsigned Value = -(unsigned)N->getZExtValue();
37    return 0 < Value && Value < 8;
38  }], imm_neg_XFORM> {
39  let ParserMatchClass = ThumbModImmNeg1_7AsmOperand;
40}
41
42def ThumbModImmNeg8_255AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg8_255"; }
43def mod_imm8_255_neg : Operand<i32>, PatLeaf<(imm), [{
44    unsigned Value = -(unsigned)N->getZExtValue();
45    return 7 < Value && Value < 256;
46  }], imm_neg_XFORM> {
47  let ParserMatchClass = ThumbModImmNeg8_255AsmOperand;
48}
49
50
51def imm0_255_comp : PatLeaf<(i32 imm), [{
52  return ~((uint32_t)N->getZExtValue()) < 256;
53}]>;
54
55def imm8_255_neg : PatLeaf<(i32 imm), [{
56  unsigned Val = -N->getZExtValue();
57  return Val >= 8 && Val < 256;
58}], imm_neg_XFORM>;
59
60// Break imm's up into two pieces: an immediate + a left shift. This uses
61// thumb_immshifted to match and thumb_immshifted_val and thumb_immshifted_shamt
62// to get the val/shift pieces.
63def thumb_immshifted : PatLeaf<(imm), [{
64  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
65}]>;
66
67def thumb_immshifted_val : SDNodeXForm<imm, [{
68  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
69  return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i32);
70}]>;
71
72def thumb_immshifted_shamt : SDNodeXForm<imm, [{
73  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
74  return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i32);
75}]>;
76
77def imm256_510 : ImmLeaf<i32, [{
78  return Imm >= 256 && Imm < 511;
79}]>;
80
81def thumb_imm256_510_addend : SDNodeXForm<imm, [{
82  return CurDAG->getTargetConstant(N->getZExtValue() - 255, SDLoc(N), MVT::i32);
83}]>;
84
85// Scaled 4 immediate.
86def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; }
87def t_imm0_1020s4 : Operand<i32> {
88  let PrintMethod = "printThumbS4ImmOperand";
89  let ParserMatchClass = t_imm0_1020s4_asmoperand;
90  let OperandType = "OPERAND_IMMEDIATE";
91}
92
93def t_imm0_508s4_asmoperand: AsmOperandClass { let Name = "Imm0_508s4"; }
94def t_imm0_508s4 : Operand<i32> {
95  let PrintMethod = "printThumbS4ImmOperand";
96  let ParserMatchClass = t_imm0_508s4_asmoperand;
97  let OperandType = "OPERAND_IMMEDIATE";
98}
99// Alias use only, so no printer is necessary.
100def t_imm0_508s4_neg_asmoperand: AsmOperandClass { let Name = "Imm0_508s4Neg"; }
101def t_imm0_508s4_neg : Operand<i32> {
102  let ParserMatchClass = t_imm0_508s4_neg_asmoperand;
103  let OperandType = "OPERAND_IMMEDIATE";
104}
105
106// Define Thumb specific addressing modes.
107
108// unsigned 8-bit, 2-scaled memory offset
109class OperandUnsignedOffset_b8s2 : AsmOperandClass {
110  let Name = "UnsignedOffset_b8s2";
111  let PredicateMethod = "isUnsignedOffset<8, 2>";
112}
113
114def UnsignedOffset_b8s2 : OperandUnsignedOffset_b8s2;
115
116// thumb style PC relative operand. signed, 8 bits magnitude,
117// two bits shift. can be represented as either [pc, #imm], #imm,
118// or relocatable expression...
119def ThumbMemPC : AsmOperandClass {
120  let Name = "ThumbMemPC";
121}
122
123let OperandType = "OPERAND_PCREL" in {
124def t_brtarget : Operand<OtherVT> {
125  let EncoderMethod = "getThumbBRTargetOpValue";
126  let DecoderMethod = "DecodeThumbBROperand";
127}
128
129// ADR instruction labels.
130def t_adrlabel : Operand<i32> {
131  let EncoderMethod = "getThumbAdrLabelOpValue";
132  let PrintMethod = "printAdrLabelOperand<2>";
133  let ParserMatchClass = UnsignedOffset_b8s2;
134}
135
136
137def thumb_br_target : Operand<OtherVT> {
138  let ParserMatchClass = ThumbBranchTarget;
139  let EncoderMethod = "getThumbBranchTargetOpValue";
140  let OperandType = "OPERAND_PCREL";
141}
142
143def thumb_bl_target : Operand<i32> {
144  let ParserMatchClass = ThumbBranchTarget;
145  let EncoderMethod = "getThumbBLTargetOpValue";
146  let DecoderMethod = "DecodeThumbBLTargetOperand";
147}
148
149// Target for BLX *from* thumb mode.
150def thumb_blx_target : Operand<i32> {
151  let ParserMatchClass = ARMBranchTarget;
152  let EncoderMethod = "getThumbBLXTargetOpValue";
153  let DecoderMethod = "DecodeThumbBLXOffset";
154}
155
156def thumb_bcc_target : Operand<OtherVT> {
157  let ParserMatchClass = ThumbBranchTarget;
158  let EncoderMethod = "getThumbBCCTargetOpValue";
159  let DecoderMethod = "DecodeThumbBCCTargetOperand";
160}
161
162def thumb_cb_target : Operand<OtherVT> {
163  let ParserMatchClass = ThumbBranchTarget;
164  let EncoderMethod = "getThumbCBTargetOpValue";
165  let DecoderMethod = "DecodeThumbCmpBROperand";
166}
167
168// t_addrmode_pc := <label> => pc + imm8 * 4
169//
170def t_addrmode_pc : MemOperand {
171  let EncoderMethod = "getAddrModePCOpValue";
172  let DecoderMethod = "DecodeThumbAddrModePC";
173  let PrintMethod = "printThumbLdrLabelOperand";
174  let ParserMatchClass = ThumbMemPC;
175}
176}
177
178// t_addrmode_rr := reg + reg
179//
180def t_addrmode_rr_asm_operand : AsmOperandClass { let Name = "MemThumbRR"; }
181def t_addrmode_rr : MemOperand,
182                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
183  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
184  let PrintMethod = "printThumbAddrModeRROperand";
185  let DecoderMethod = "DecodeThumbAddrModeRR";
186  let ParserMatchClass = t_addrmode_rr_asm_operand;
187  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
188}
189
190// t_addrmode_rr_sext := reg + reg
191//
192// This is similar to t_addrmode_rr, but uses different heuristics for
193// ldrsb/ldrsh.
194def t_addrmode_rr_sext : MemOperand,
195                    ComplexPattern<i32, 2, "SelectThumbAddrModeRRSext", []> {
196  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
197  let PrintMethod = "printThumbAddrModeRROperand";
198  let DecoderMethod = "DecodeThumbAddrModeRR";
199  let ParserMatchClass = t_addrmode_rr_asm_operand;
200  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
201}
202
203// t_addrmode_rrs := reg + reg
204//
205// We use separate scaled versions because the Select* functions need
206// to explicitly check for a matching constant and return false here so that
207// the reg+imm forms will match instead. This is a horrible way to do that,
208// as it forces tight coupling between the methods, but it's how selectiondag
209// currently works.
210def t_addrmode_rrs1 : MemOperand,
211                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> {
212  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
213  let PrintMethod = "printThumbAddrModeRROperand";
214  let DecoderMethod = "DecodeThumbAddrModeRR";
215  let ParserMatchClass = t_addrmode_rr_asm_operand;
216  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
217}
218def t_addrmode_rrs2 : MemOperand,
219                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> {
220  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
221  let DecoderMethod = "DecodeThumbAddrModeRR";
222  let PrintMethod = "printThumbAddrModeRROperand";
223  let ParserMatchClass = t_addrmode_rr_asm_operand;
224  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
225}
226def t_addrmode_rrs4 : MemOperand,
227                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> {
228  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
229  let DecoderMethod = "DecodeThumbAddrModeRR";
230  let PrintMethod = "printThumbAddrModeRROperand";
231  let ParserMatchClass = t_addrmode_rr_asm_operand;
232  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
233}
234
235// t_addrmode_is4 := reg + imm5 * 4
236//
237def t_addrmode_is4_asm_operand : AsmOperandClass { let Name = "MemThumbRIs4"; }
238def t_addrmode_is4 : MemOperand,
239                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> {
240  let EncoderMethod = "getAddrModeISOpValue";
241  let DecoderMethod = "DecodeThumbAddrModeIS";
242  let PrintMethod = "printThumbAddrModeImm5S4Operand";
243  let ParserMatchClass = t_addrmode_is4_asm_operand;
244  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
245}
246
247// t_addrmode_is2 := reg + imm5 * 2
248//
249def t_addrmode_is2_asm_operand : AsmOperandClass { let Name = "MemThumbRIs2"; }
250def t_addrmode_is2 : MemOperand,
251                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> {
252  let EncoderMethod = "getAddrModeISOpValue";
253  let DecoderMethod = "DecodeThumbAddrModeIS";
254  let PrintMethod = "printThumbAddrModeImm5S2Operand";
255  let ParserMatchClass = t_addrmode_is2_asm_operand;
256  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
257}
258
259// t_addrmode_is1 := reg + imm5
260//
261def t_addrmode_is1_asm_operand : AsmOperandClass { let Name = "MemThumbRIs1"; }
262def t_addrmode_is1 : MemOperand,
263                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> {
264  let EncoderMethod = "getAddrModeISOpValue";
265  let DecoderMethod = "DecodeThumbAddrModeIS";
266  let PrintMethod = "printThumbAddrModeImm5S1Operand";
267  let ParserMatchClass = t_addrmode_is1_asm_operand;
268  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
269}
270
271// t_addrmode_sp := sp + imm8 * 4
272//
273// FIXME: This really shouldn't have an explicit SP operand at all. It should
274// be implicit, just like in the instruction encoding itself.
275def t_addrmode_sp_asm_operand : AsmOperandClass { let Name = "MemThumbSPI"; }
276def t_addrmode_sp : MemOperand,
277                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
278  let EncoderMethod = "getAddrModeThumbSPOpValue";
279  let DecoderMethod = "DecodeThumbAddrModeSP";
280  let PrintMethod = "printThumbAddrModeSPOperand";
281  let ParserMatchClass = t_addrmode_sp_asm_operand;
282  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
283}
284
285// Inspects parent to determine whether an or instruction can be implemented as
286// an add (i.e. whether we know overflow won't occur in the add).
287def AddLikeOrOp : ComplexPattern<i32, 1, "SelectAddLikeOr", [],
288                                 [SDNPWantParent]>;
289
290// Pattern to exclude immediates from matching
291def non_imm32 : PatLeaf<(i32 GPR), [{ return !isa<ConstantSDNode>(N); }]>;
292
293//===----------------------------------------------------------------------===//
294//  Miscellaneous Instructions.
295//
296
297// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
298// from removing one half of the matched pairs. That breaks PEI, which assumes
299// these will always be in pairs, and asserts if it finds otherwise. Better way?
300let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
301def tADJCALLSTACKUP :
302  PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
303             [(ARMcallseq_end imm:$amt1, imm:$amt2)]>,
304            Requires<[IsThumb, IsThumb1Only]>;
305
306def tADJCALLSTACKDOWN :
307  PseudoInst<(outs), (ins i32imm:$amt, i32imm:$amt2), NoItinerary,
308             [(ARMcallseq_start imm:$amt, imm:$amt2)]>,
309            Requires<[IsThumb, IsThumb1Only]>;
310}
311
312class T1SystemEncoding<bits<8> opc>
313  : T1Encoding<0b101111> {
314  let Inst{9-8} = 0b11;
315  let Inst{7-0} = opc;
316}
317
318def tHINT : T1pI<(outs), (ins imm0_15:$imm), NoItinerary, "hint", "\t$imm",
319                 [(int_arm_hint imm0_15:$imm)]>,
320            T1SystemEncoding<0x00>,
321            Requires<[IsThumb, HasV6M]> {
322  bits<4> imm;
323  let Inst{7-4} = imm;
324}
325
326// Note: When EmitPriority == 1, the alias will be used for printing
327class tHintAlias<string Asm, dag Result, bit EmitPriority = 0> : tInstAlias<Asm, Result, EmitPriority> {
328  let Predicates = [IsThumb, HasV6M];
329}
330
331def : tHintAlias<"nop$p", (tHINT 0, pred:$p), 1>; // A8.6.110
332def : tHintAlias<"yield$p", (tHINT 1, pred:$p), 1>; // A8.6.410
333def : tHintAlias<"wfe$p", (tHINT 2, pred:$p), 1>; // A8.6.408
334def : tHintAlias<"wfi$p", (tHINT 3, pred:$p), 1>; // A8.6.409
335def : tHintAlias<"sev$p", (tHINT 4, pred:$p), 1>; // A8.6.157
336def : tInstAlias<"sevl$p", (tHINT 5, pred:$p), 1> {
337  let Predicates = [IsThumb2, HasV8];
338}
339
340// The imm operand $val can be used by a debugger to store more information
341// about the breakpoint.
342def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val",
343                []>,
344           T1Encoding<0b101111> {
345  let Inst{9-8} = 0b10;
346  // A8.6.22
347  bits<8> val;
348  let Inst{7-0} = val;
349}
350// default immediate for breakpoint mnemonic
351def : InstAlias<"bkpt", (tBKPT 0), 0>, Requires<[IsThumb]>;
352
353def tHLT : T1I<(outs), (ins imm0_63:$val), NoItinerary, "hlt\t$val",
354                []>, T1Encoding<0b101110>, Requires<[IsThumb, HasV8]> {
355  let Inst{9-6} = 0b1010;
356  bits<6> val;
357  let Inst{5-0} = val;
358}
359
360def tSETEND : T1I<(outs), (ins setend_op:$end), NoItinerary, "setend\t$end",
361                  []>, T1Encoding<0b101101>, Requires<[IsThumb, IsNotMClass]>, Deprecated<HasV8Ops> {
362  bits<1> end;
363  // A8.6.156
364  let Inst{9-5} = 0b10010;
365  let Inst{4}   = 1;
366  let Inst{3}   = end;
367  let Inst{2-0} = 0b000;
368}
369
370// Change Processor State is a system instruction -- for disassembly only.
371def tCPS : T1I<(outs), (ins imod_op:$imod, iflags_op:$iflags),
372                NoItinerary, "cps$imod $iflags", []>,
373           T1Misc<0b0110011> {
374  // A8.6.38 & B6.1.1
375  bit imod;
376  bits<3> iflags;
377
378  let Inst{4}   = imod;
379  let Inst{3}   = 0;
380  let Inst{2-0} = iflags;
381  let DecoderMethod = "DecodeThumbCPS";
382}
383
384// For both thumb1 and thumb2.
385let isNotDuplicable = 1, isCodeGenOnly = 1 in
386def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, "",
387                  [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>,
388              T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
389  // A8.6.6
390  bits<3> dst;
391  let Inst{6-3} = 0b1111; // Rm = pc
392  let Inst{2-0} = dst;
393}
394
395// ADD <Rd>, sp, #<imm8>
396// FIXME: This should not be marked as having side effects, and it should be
397// rematerializable. Clearing the side effect bit causes miscompilations,
398// probably because the instruction can be moved around.
399def tADDrSPi : T1pI<(outs tGPR:$dst), (ins GPRsp:$sp, t_imm0_1020s4:$imm),
400                    IIC_iALUi, "add", "\t$dst, $sp, $imm", []>,
401               T1Encoding<{1,0,1,0,1,?}>, Sched<[WriteALU]> {
402  // A6.2 & A8.6.8
403  bits<3> dst;
404  bits<8> imm;
405  let Inst{10-8} = dst;
406  let Inst{7-0}  = imm;
407  let DecoderMethod = "DecodeThumbAddSpecialReg";
408}
409
410// Thumb1 frame lowering is rather fragile, we hope to be able to use
411// tADDrSPi, but we may need to insert a sequence that clobbers CPSR.
412def tADDframe : PseudoInst<(outs tGPR:$dst), (ins i32imm:$base, i32imm:$offset),
413                           NoItinerary, []>,
414                Requires<[IsThumb, IsThumb1Only]> {
415  let Defs = [CPSR];
416}
417
418// ADD sp, sp, #<imm7>
419def tADDspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
420                     IIC_iALUi, "add", "\t$Rdn, $imm", []>,
421              T1Misc<{0,0,0,0,0,?,?}>, Sched<[WriteALU]> {
422  // A6.2.5 & A8.6.8
423  bits<7> imm;
424  let Inst{6-0} = imm;
425  let DecoderMethod = "DecodeThumbAddSPImm";
426}
427
428// SUB sp, sp, #<imm7>
429// FIXME: The encoding and the ASM string don't match up.
430def tSUBspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
431                    IIC_iALUi, "sub", "\t$Rdn, $imm", []>,
432              T1Misc<{0,0,0,0,1,?,?}>, Sched<[WriteALU]> {
433  // A6.2.5 & A8.6.214
434  bits<7> imm;
435  let Inst{6-0} = imm;
436  let DecoderMethod = "DecodeThumbAddSPImm";
437}
438
439def : tInstSubst<"add${p} sp, $imm",
440                 (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
441def : tInstSubst<"add${p} sp, sp, $imm",
442                 (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
443
444// Can optionally specify SP as a three operand instruction.
445def : tInstAlias<"add${p} sp, sp, $imm",
446                 (tADDspi SP, t_imm0_508s4:$imm, pred:$p)>;
447def : tInstAlias<"sub${p} sp, sp, $imm",
448                 (tSUBspi SP, t_imm0_508s4:$imm, pred:$p)>;
449
450// ADD <Rm>, sp
451def tADDrSP : T1pI<(outs GPR:$Rdn), (ins GPRsp:$sp, GPR:$Rn), IIC_iALUr,
452                   "add", "\t$Rdn, $sp, $Rn", []>,
453              T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
454  // A8.6.9 Encoding T1
455  bits<4> Rdn;
456  let Inst{7}   = Rdn{3};
457  let Inst{6-3} = 0b1101;
458  let Inst{2-0} = Rdn{2-0};
459  let DecoderMethod = "DecodeThumbAddSPReg";
460}
461
462// ADD sp, <Rm>
463def tADDspr : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, GPR:$Rm), IIC_iALUr,
464                  "add", "\t$Rdn, $Rm", []>,
465              T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
466  // A8.6.9 Encoding T2
467  bits<4> Rm;
468  let Inst{7} = 1;
469  let Inst{6-3} = Rm;
470  let Inst{2-0} = 0b101;
471  let DecoderMethod = "DecodeThumbAddSPReg";
472}
473
474//===----------------------------------------------------------------------===//
475//  Control Flow Instructions.
476//
477
478// Indirect branches
479let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
480  def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>,
481            T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
482    // A6.2.3 & A8.6.25
483    bits<4> Rm;
484    let Inst{6-3} = Rm;
485    let Inst{2-0} = 0b000;
486    let Unpredictable{2-0} = 0b111;
487  }
488  def tBXNS : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bxns${p}\t$Rm", []>,
489              Requires<[IsThumb, Has8MSecExt]>,
490              T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
491    bits<4> Rm;
492    let Inst{6-3} = Rm;
493    let Inst{2-0} = 0b100;
494    let Unpredictable{1-0} = 0b11;
495  }
496}
497
498let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
499  def tBX_RET : tPseudoExpand<(outs), (ins pred:$p), 2, IIC_Br,
500                   [(ARMretflag)], (tBX LR, pred:$p)>, Sched<[WriteBr]>;
501
502  // Alternative return instruction used by vararg functions.
503  def tBX_RET_vararg : tPseudoExpand<(outs), (ins tGPR:$Rm, pred:$p),
504                   2, IIC_Br, [],
505                   (tBX GPR:$Rm, pred:$p)>, Sched<[WriteBr]>;
506}
507
508// All calls clobber the non-callee saved registers. SP is marked as a use to
509// prevent stack-pointer assignments that appear immediately before calls from
510// potentially appearing dead.
511let isCall = 1,
512  Defs = [LR], Uses = [SP] in {
513  // Also used for Thumb2
514  def tBL  : TIx2<0b11110, 0b11, 1,
515                  (outs), (ins pred:$p, thumb_bl_target:$func), IIC_Br,
516                  "bl${p}\t$func",
517                  [(ARMcall tglobaladdr:$func)]>,
518             Requires<[IsThumb]>, Sched<[WriteBrL]> {
519    bits<24> func;
520    let Inst{26} = func{23};
521    let Inst{25-16} = func{20-11};
522    let Inst{13} = func{22};
523    let Inst{11} = func{21};
524    let Inst{10-0} = func{10-0};
525  }
526
527  // ARMv5T and above, also used for Thumb2
528  def tBLXi : TIx2<0b11110, 0b11, 0,
529                 (outs), (ins pred:$p, thumb_blx_target:$func), IIC_Br,
530                   "blx${p}\t$func", []>,
531              Requires<[IsThumb, HasV5T, IsNotMClass]>, Sched<[WriteBrL]> {
532    bits<24> func;
533    let Inst{26} = func{23};
534    let Inst{25-16} = func{20-11};
535    let Inst{13} = func{22};
536    let Inst{11} = func{21};
537    let Inst{10-1} = func{10-1};
538    let Inst{0} = 0; // func{0} is assumed zero
539  }
540
541  // Also used for Thumb2
542  def tBLXr : TI<(outs), (ins pred:$p, GPR:$func), IIC_Br,
543                  "blx${p}\t$func",
544                  [(ARMcall GPR:$func)]>,
545              Requires<[IsThumb, HasV5T]>,
546              T1Special<{1,1,1,?}>, Sched<[WriteBrL]> { // A6.2.3 & A8.6.24;
547    bits<4> func;
548    let Inst{6-3} = func;
549    let Inst{2-0} = 0b000;
550  }
551
552  // ARMv8-M Security Extensions
553  def tBLXNSr : TI<(outs), (ins pred:$p, GPRnopc:$func), IIC_Br,
554                   "blxns${p}\t$func", []>,
555                Requires<[IsThumb, Has8MSecExt]>,
556                T1Special<{1,1,1,?}>, Sched<[WriteBrL]> {
557    bits<4> func;
558    let Inst{6-3} = func;
559    let Inst{2-0} = 0b100;
560    let Unpredictable{1-0} = 0b11;
561  }
562
563  // ARMv4T
564  def tBX_CALL : tPseudoInst<(outs), (ins tGPR:$func),
565                  4, IIC_Br,
566                  [(ARMcall_nolink tGPR:$func)]>,
567            Requires<[IsThumb, IsThumb1Only]>, Sched<[WriteBr]>;
568
569  // Also used for Thumb2
570  // push lr before the call
571  def tBL_PUSHLR : tPseudoInst<(outs), (ins GPRlr:$ra, pred:$p, thumb_bl_target:$func),
572                  4, IIC_Br,
573                  []>,
574             Requires<[IsThumb]>, Sched<[WriteBr]>;
575}
576
577let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
578  let isPredicable = 1 in
579  def tB   : T1pI<(outs), (ins t_brtarget:$target), IIC_Br,
580                 "b", "\t$target", [(br bb:$target)]>,
581             T1Encoding<{1,1,1,0,0,?}>, Sched<[WriteBr]> {
582    bits<11> target;
583    let Inst{10-0} = target;
584    let AsmMatchConverter = "cvtThumbBranches";
585 }
586
587  // Far jump
588  // Just a pseudo for a tBL instruction. Needed to let regalloc know about
589  // the clobber of LR.
590  let Defs = [LR] in
591  def tBfar : tPseudoExpand<(outs), (ins thumb_bl_target:$target, pred:$p),
592                          4, IIC_Br, [],
593                          (tBL pred:$p, thumb_bl_target:$target)>,
594                          Sched<[WriteBrTbl]>;
595
596  def tBR_JTr : tPseudoInst<(outs),
597                      (ins tGPR:$target, i32imm:$jt),
598                      0, IIC_Br,
599                      [(ARMbrjt tGPR:$target, tjumptable:$jt)]>,
600                      Sched<[WriteBrTbl]> {
601    let Size = 2;
602    let isNotDuplicable = 1;
603    list<Predicate> Predicates = [IsThumb, IsThumb1Only];
604  }
605}
606
607// FIXME: should be able to write a pattern for ARMBrcond, but can't use
608// a two-value operand where a dag node expects two operands. :(
609let isBranch = 1, isTerminator = 1 in
610  def tBcc : T1I<(outs), (ins thumb_bcc_target:$target, pred:$p), IIC_Br,
611                 "b${p}\t$target",
612                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
613             T1BranchCond<{1,1,0,1}>, Sched<[WriteBr]> {
614  bits<4> p;
615  bits<8> target;
616  let Inst{11-8} = p;
617  let Inst{7-0} = target;
618  let AsmMatchConverter = "cvtThumbBranches";
619}
620
621
622// Tail calls
623let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
624  // IOS versions.
625  let Uses = [SP] in {
626    def tTAILJMPr : tPseudoExpand<(outs), (ins tcGPR:$dst),
627                     4, IIC_Br, [],
628                     (tBX GPR:$dst, (ops 14, zero_reg))>,
629                     Requires<[IsThumb]>, Sched<[WriteBr]>;
630  }
631  // tTAILJMPd: MachO version uses a Thumb2 branch (no Thumb1 tail calls
632  // on MachO), so it's in ARMInstrThumb2.td.
633  // Non-MachO version:
634  let Uses = [SP] in {
635    def tTAILJMPdND : tPseudoExpand<(outs),
636                   (ins t_brtarget:$dst, pred:$p),
637                   4, IIC_Br, [],
638                   (tB t_brtarget:$dst, pred:$p)>,
639                 Requires<[IsThumb, IsNotMachO]>, Sched<[WriteBr]>;
640  }
641}
642
643
644// A8.6.218 Supervisor Call (Software Interrupt)
645// A8.6.16 B: Encoding T1
646// If Inst{11-8} == 0b1111 then SEE SVC
647let isCall = 1, Uses = [SP] in
648def tSVC : T1pI<(outs), (ins imm0_255:$imm), IIC_Br,
649                "svc", "\t$imm", []>, Encoding16, Sched<[WriteBr]> {
650  bits<8> imm;
651  let Inst{15-12} = 0b1101;
652  let Inst{11-8}  = 0b1111;
653  let Inst{7-0}   = imm;
654}
655
656// The assembler uses 0xDEFE for a trap instruction.
657let isBarrier = 1, isTerminator = 1 in
658def tTRAP : TI<(outs), (ins), IIC_Br,
659               "trap", [(trap)]>, Encoding16, Sched<[WriteBr]> {
660  let Inst = 0xdefe;
661}
662
663//===----------------------------------------------------------------------===//
664//  Load Store Instructions.
665//
666
667// PC-relative loads need to be matched first as constant pool accesses need to
668// always be PC-relative. We do this using AddedComplexity, as the pattern is
669// simpler than the patterns of the other load instructions.
670let canFoldAsLoad = 1, isReMaterializable = 1, AddedComplexity = 10 in
671def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i,
672                  "ldr", "\t$Rt, $addr",
673                  [(set tGPR:$Rt, (load (ARMWrapper tconstpool:$addr)))]>,
674              T1Encoding<{0,1,0,0,1,?}>, Sched<[WriteLd]> {
675  // A6.2 & A8.6.59
676  bits<3> Rt;
677  bits<8> addr;
678  let Inst{10-8} = Rt;
679  let Inst{7-0}  = addr;
680}
681
682// SP-relative loads should be matched before standard immediate-offset loads as
683// it means we avoid having to move SP to another register.
684let canFoldAsLoad = 1 in
685def tLDRspi : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
686                    "ldr", "\t$Rt, $addr",
687                    [(set tGPR:$Rt, (load t_addrmode_sp:$addr))]>,
688              T1LdStSP<{1,?,?}>, Sched<[WriteLd]> {
689  bits<3> Rt;
690  bits<8> addr;
691  let Inst{10-8} = Rt;
692  let Inst{7-0} = addr;
693}
694
695// Loads: reg/reg and reg/imm5
696let canFoldAsLoad = 1, isReMaterializable = 1 in
697multiclass thumb_ld_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
698                              Operand AddrMode_r, Operand AddrMode_i,
699                              AddrMode am, InstrItinClass itin_r,
700                              InstrItinClass itin_i, string asm,
701                              PatFrag opnode> {
702  // Immediate-offset loads should be matched before register-offset loads as
703  // when the offset is a constant it's simpler to first check if it fits in the
704  // immediate offset field then fall back to register-offset if it doesn't.
705  def i : // reg/imm5
706    T1pILdStEncodeImm<imm_opc, 1 /* Load */,
707                      (outs tGPR:$Rt), (ins AddrMode_i:$addr),
708                      am, itin_i, asm, "\t$Rt, $addr",
709                      [(set tGPR:$Rt, (opnode AddrMode_i:$addr))]>;
710  // Register-offset loads are matched last.
711  def r : // reg/reg
712    T1pILdStEncode<reg_opc,
713                   (outs tGPR:$Rt), (ins AddrMode_r:$addr),
714                   am, itin_r, asm, "\t$Rt, $addr",
715                   [(set tGPR:$Rt, (opnode AddrMode_r:$addr))]>;
716}
717// Stores: reg/reg and reg/imm5
718multiclass thumb_st_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
719                              Operand AddrMode_r, Operand AddrMode_i,
720                              AddrMode am, InstrItinClass itin_r,
721                              InstrItinClass itin_i, string asm,
722                              PatFrag opnode> {
723  def i : // reg/imm5
724    T1pILdStEncodeImm<imm_opc, 0 /* Store */,
725                      (outs), (ins tGPR:$Rt, AddrMode_i:$addr),
726                      am, itin_i, asm, "\t$Rt, $addr",
727                      [(opnode tGPR:$Rt, AddrMode_i:$addr)]>;
728  def r : // reg/reg
729    T1pILdStEncode<reg_opc,
730                   (outs), (ins tGPR:$Rt, AddrMode_r:$addr),
731                   am, itin_r, asm, "\t$Rt, $addr",
732                   [(opnode tGPR:$Rt, AddrMode_r:$addr)]>;
733}
734
735// A8.6.57 & A8.6.60
736defm tLDR  : thumb_ld_rr_ri_enc<0b100, 0b0110, t_addrmode_rr,
737                                t_addrmode_is4, AddrModeT1_4,
738                                IIC_iLoad_r, IIC_iLoad_i, "ldr",
739                                load>, Sched<[WriteLd]>;
740
741// A8.6.64 & A8.6.61
742defm tLDRB : thumb_ld_rr_ri_enc<0b110, 0b0111, t_addrmode_rr,
743                                t_addrmode_is1, AddrModeT1_1,
744                                IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrb",
745                                zextloadi8>, Sched<[WriteLd]>;
746
747// A8.6.76 & A8.6.73
748defm tLDRH : thumb_ld_rr_ri_enc<0b101, 0b1000, t_addrmode_rr,
749                                t_addrmode_is2, AddrModeT1_2,
750                                IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrh",
751                                zextloadi16>, Sched<[WriteLd]>;
752
753let AddedComplexity = 10 in
754def tLDRSB :                    // A8.6.80
755  T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
756                 AddrModeT1_1, IIC_iLoad_bh_r,
757                 "ldrsb", "\t$Rt, $addr",
758                 [(set tGPR:$Rt, (sextloadi8 t_addrmode_rr_sext:$addr))]>, Sched<[WriteLd]>;
759
760let AddedComplexity = 10 in
761def tLDRSH :                    // A8.6.84
762  T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
763                 AddrModeT1_2, IIC_iLoad_bh_r,
764                 "ldrsh", "\t$Rt, $addr",
765                 [(set tGPR:$Rt, (sextloadi16 t_addrmode_rr_sext:$addr))]>, Sched<[WriteLd]>;
766
767
768def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
769                    "str", "\t$Rt, $addr",
770                    [(store tGPR:$Rt, t_addrmode_sp:$addr)]>,
771              T1LdStSP<{0,?,?}>, Sched<[WriteST]> {
772  bits<3> Rt;
773  bits<8> addr;
774  let Inst{10-8} = Rt;
775  let Inst{7-0} = addr;
776}
777
778// A8.6.194 & A8.6.192
779defm tSTR  : thumb_st_rr_ri_enc<0b000, 0b0110, t_addrmode_rr,
780                                t_addrmode_is4, AddrModeT1_4,
781                                IIC_iStore_r, IIC_iStore_i, "str",
782                                store>, Sched<[WriteST]>;
783
784// A8.6.197 & A8.6.195
785defm tSTRB : thumb_st_rr_ri_enc<0b010, 0b0111, t_addrmode_rr,
786                                t_addrmode_is1, AddrModeT1_1,
787                                IIC_iStore_bh_r, IIC_iStore_bh_i, "strb",
788                                truncstorei8>, Sched<[WriteST]>;
789
790// A8.6.207 & A8.6.205
791defm tSTRH : thumb_st_rr_ri_enc<0b001, 0b1000, t_addrmode_rr,
792                               t_addrmode_is2, AddrModeT1_2,
793                               IIC_iStore_bh_r, IIC_iStore_bh_i, "strh",
794                               truncstorei16>, Sched<[WriteST]>;
795
796
797//===----------------------------------------------------------------------===//
798//  Load / store multiple Instructions.
799//
800
801// These require base address to be written back or one of the loaded regs.
802let hasSideEffects = 0 in {
803
804let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
805def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
806        IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
807  bits<3> Rn;
808  bits<8> regs;
809  let Inst{10-8} = Rn;
810  let Inst{7-0}  = regs;
811}
812
813// Writeback version is just a pseudo, as there's no encoding difference.
814// Writeback happens iff the base register is not in the destination register
815// list.
816let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
817def tLDMIA_UPD :
818    InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
819                 "$Rn = $wb", IIC_iLoad_mu>,
820    PseudoInstExpansion<(tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)> {
821  let Size = 2;
822  let OutOperandList = (outs tGPR:$wb);
823  let InOperandList = (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops);
824  let Pattern = [];
825  let isCodeGenOnly = 1;
826  let isPseudo = 1;
827  list<Predicate> Predicates = [IsThumb];
828}
829
830// There is no non-writeback version of STM for Thumb.
831let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
832def tSTMIA_UPD : Thumb1I<(outs tGPR:$wb),
833                         (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
834                         AddrModeNone, 2, IIC_iStore_mu,
835                         "stm${p}\t$Rn!, $regs", "$Rn = $wb", []>,
836                     T1Encoding<{1,1,0,0,0,?}> {
837  bits<3> Rn;
838  bits<8> regs;
839  let Inst{10-8} = Rn;
840  let Inst{7-0}  = regs;
841}
842
843} // hasSideEffects
844
845def : InstAlias<"ldm${p} $Rn!, $regs",
846                (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs), 0>,
847        Requires<[IsThumb, IsThumb1Only]>;
848
849let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1,
850    variadicOpsAreDefs = 1 in
851def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
852               IIC_iPop,
853               "pop${p}\t$regs", []>,
854           T1Misc<{1,1,0,?,?,?,?}>, Sched<[WriteLd]> {
855  bits<16> regs;
856  let Inst{8}   = regs{15};
857  let Inst{7-0} = regs{7-0};
858}
859
860let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
861def tPUSH : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
862                IIC_iStore_m,
863                "push${p}\t$regs", []>,
864            T1Misc<{0,1,0,?,?,?,?}>, Sched<[WriteST]> {
865  bits<16> regs;
866  let Inst{8}   = regs{14};
867  let Inst{7-0} = regs{7-0};
868}
869
870//===----------------------------------------------------------------------===//
871//  Arithmetic Instructions.
872//
873
874// Helper classes for encoding T1pI patterns:
875class T1pIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
876                   string opc, string asm, list<dag> pattern>
877    : T1pI<oops, iops, itin, opc, asm, pattern>,
878      T1DataProcessing<opA> {
879  bits<3> Rm;
880  bits<3> Rn;
881  let Inst{5-3} = Rm;
882  let Inst{2-0} = Rn;
883}
884class T1pIMiscEncode<bits<7> opA, dag oops, dag iops, InstrItinClass itin,
885                     string opc, string asm, list<dag> pattern>
886    : T1pI<oops, iops, itin, opc, asm, pattern>,
887      T1Misc<opA> {
888  bits<3> Rm;
889  bits<3> Rd;
890  let Inst{5-3} = Rm;
891  let Inst{2-0} = Rd;
892}
893
894// Helper classes for encoding T1sI patterns:
895class T1sIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
896                   string opc, string asm, list<dag> pattern>
897    : T1sI<oops, iops, itin, opc, asm, pattern>,
898      T1DataProcessing<opA> {
899  bits<3> Rd;
900  bits<3> Rn;
901  let Inst{5-3} = Rn;
902  let Inst{2-0} = Rd;
903}
904class T1sIGenEncode<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
905                    string opc, string asm, list<dag> pattern>
906    : T1sI<oops, iops, itin, opc, asm, pattern>,
907      T1General<opA> {
908  bits<3> Rm;
909  bits<3> Rn;
910  bits<3> Rd;
911  let Inst{8-6} = Rm;
912  let Inst{5-3} = Rn;
913  let Inst{2-0} = Rd;
914}
915class T1sIGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
916                       string opc, string asm, list<dag> pattern>
917    : T1sI<oops, iops, itin, opc, asm, pattern>,
918      T1General<opA> {
919  bits<3> Rd;
920  bits<3> Rm;
921  let Inst{5-3} = Rm;
922  let Inst{2-0} = Rd;
923}
924
925// Helper classes for encoding T1sIt patterns:
926class T1sItDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
927                    string opc, string asm, list<dag> pattern>
928    : T1sIt<oops, iops, itin, opc, asm, pattern>,
929      T1DataProcessing<opA> {
930  bits<3> Rdn;
931  bits<3> Rm;
932  let Inst{5-3} = Rm;
933  let Inst{2-0} = Rdn;
934}
935class T1sItGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
936                        string opc, string asm, list<dag> pattern>
937    : T1sIt<oops, iops, itin, opc, asm, pattern>,
938      T1General<opA> {
939  bits<3> Rdn;
940  bits<8> imm8;
941  let Inst{10-8} = Rdn;
942  let Inst{7-0}  = imm8;
943}
944
945let isAdd = 1 in {
946  // Add with carry register
947  let isCommutable = 1, Uses = [CPSR] in
948  def tADC :                      // A8.6.2
949    T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
950                  "adc", "\t$Rdn, $Rm",
951                  []>, Sched<[WriteALU]>;
952
953  // Add immediate
954  def tADDi3 :                    // A8.6.4 T1
955    T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
956                     IIC_iALUi,
957                     "add", "\t$Rd, $Rm, $imm3",
958                     [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
959                     Sched<[WriteALU]> {
960    bits<3> imm3;
961    let Inst{8-6} = imm3;
962  }
963
964  def tADDi8 :                    // A8.6.4 T2
965    T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
966                      (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
967                      "add", "\t$Rdn, $imm8",
968                      [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
969                      Sched<[WriteALU]>;
970
971  // Add register
972  let isCommutable = 1 in
973  def tADDrr :                    // A8.6.6 T1
974    T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
975                  IIC_iALUr,
976                  "add", "\t$Rd, $Rn, $Rm",
977                  [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
978
979  /// Similar to the above except these set the 's' bit so the
980  /// instruction modifies the CPSR register.
981  ///
982  /// These opcodes will be converted to the real non-S opcodes by
983  /// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
984  let hasPostISelHook = 1, Defs = [CPSR] in {
985    let isCommutable = 1, Uses = [CPSR] in
986    def tADCS : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
987                            2, IIC_iALUr,
988                            [(set tGPR:$Rdn, CPSR, (ARMadde tGPR:$Rn, tGPR:$Rm,
989                                                            CPSR))]>,
990                Requires<[IsThumb1Only]>,
991                Sched<[WriteALU]>;
992
993    def tADDSi3 : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
994                              2, IIC_iALUi,
995                              [(set tGPR:$Rd, CPSR, (ARMaddc tGPR:$Rm,
996                                                             imm0_7:$imm3))]>,
997                  Requires<[IsThumb1Only]>,
998                  Sched<[WriteALU]>;
999
1000    def tADDSi8 : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, imm0_255:$imm8),
1001                              2, IIC_iALUi,
1002                              [(set tGPR:$Rdn, CPSR, (ARMaddc tGPR:$Rn,
1003                                                      imm8_255:$imm8))]>,
1004                  Requires<[IsThumb1Only]>,
1005                  Sched<[WriteALU]>;
1006
1007    let isCommutable = 1 in
1008    def tADDSrr : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
1009                              2, IIC_iALUr,
1010                              [(set tGPR:$Rd, CPSR, (ARMaddc tGPR:$Rn,
1011                                                             tGPR:$Rm))]>,
1012                  Requires<[IsThumb1Only]>,
1013                  Sched<[WriteALU]>;
1014  }
1015
1016  let hasSideEffects = 0 in
1017  def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
1018                       "add", "\t$Rdn, $Rm", []>,
1019                 T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
1020    // A8.6.6 T2
1021    bits<4> Rdn;
1022    bits<4> Rm;
1023    let Inst{7}   = Rdn{3};
1024    let Inst{6-3} = Rm;
1025    let Inst{2-0} = Rdn{2-0};
1026  }
1027}
1028
1029// Thumb has more flexible short encodings for ADD than ORR, so use those where
1030// possible.
1031def : T1Pat<(or AddLikeOrOp:$Rn, imm0_7:$imm), (tADDi3 $Rn, imm0_7:$imm)>;
1032
1033def : T1Pat<(or AddLikeOrOp:$Rn, imm8_255:$imm), (tADDi8 $Rn, imm8_255:$imm)>;
1034
1035def : T1Pat<(or AddLikeOrOp:$Rn, tGPR:$Rm), (tADDrr $Rn, $Rm)>;
1036
1037
1038def : tInstAlias <"add${s}${p} $Rdn, $Rm",
1039                 (tADDrr tGPR:$Rdn,s_cc_out:$s, tGPR:$Rdn, tGPR:$Rm, pred:$p)>;
1040
1041def : tInstSubst<"sub${s}${p} $rd, $rn, $imm",
1042                 (tADDi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
1043def : tInstSubst<"sub${s}${p} $rdn, $imm",
1044                 (tADDi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
1045
1046
1047// AND register
1048let isCommutable = 1 in
1049def tAND :                      // A8.6.12
1050  T1sItDPEncode<0b0000, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1051                IIC_iBITr,
1052                "and", "\t$Rdn, $Rm",
1053                [(set tGPR:$Rdn, (and tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1054
1055// ASR immediate
1056def tASRri :                    // A8.6.14
1057  T1sIGenEncodeImm<{0,1,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
1058                   IIC_iMOVsi,
1059                   "asr", "\t$Rd, $Rm, $imm5",
1060                   [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm_sr:$imm5)))]>,
1061                   Sched<[WriteALU]> {
1062  bits<5> imm5;
1063  let Inst{10-6} = imm5;
1064}
1065
1066// ASR register
1067def tASRrr :                    // A8.6.15
1068  T1sItDPEncode<0b0100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1069                IIC_iMOVsr,
1070                "asr", "\t$Rdn, $Rm",
1071                [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1072
1073// BIC register
1074def tBIC :                      // A8.6.20
1075  T1sItDPEncode<0b1110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1076                IIC_iBITr,
1077                "bic", "\t$Rdn, $Rm",
1078                [(set tGPR:$Rdn, (and tGPR:$Rn, (not tGPR:$Rm)))]>,
1079                Sched<[WriteALU]>;
1080
1081// CMN register
1082let isCompare = 1, Defs = [CPSR] in {
1083//FIXME: Disable CMN, as CCodes are backwards from compare expectations
1084//       Compare-to-zero still works out, just not the relationals
1085//def tCMN :                     // A8.6.33
1086//  T1pIDPEncode<0b1011, (outs), (ins tGPR:$lhs, tGPR:$rhs),
1087//               IIC_iCMPr,
1088//               "cmn", "\t$lhs, $rhs",
1089//               [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
1090
1091def tCMNz :                     // A8.6.33
1092  T1pIDPEncode<0b1011, (outs), (ins tGPR:$Rn, tGPR:$Rm),
1093               IIC_iCMPr,
1094               "cmn", "\t$Rn, $Rm",
1095               [(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm))]>, Sched<[WriteCMP]>;
1096
1097} // isCompare = 1, Defs = [CPSR]
1098
1099// CMP immediate
1100let isCompare = 1, Defs = [CPSR] in {
1101def tCMPi8 : T1pI<(outs), (ins tGPR:$Rn, imm0_255:$imm8), IIC_iCMPi,
1102                  "cmp", "\t$Rn, $imm8",
1103                  [(ARMcmp tGPR:$Rn, imm0_255:$imm8)]>,
1104             T1General<{1,0,1,?,?}>, Sched<[WriteCMP]> {
1105  // A8.6.35
1106  bits<3> Rn;
1107  bits<8> imm8;
1108  let Inst{10-8} = Rn;
1109  let Inst{7-0}  = imm8;
1110}
1111
1112// CMP register
1113def tCMPr :                     // A8.6.36 T1
1114  T1pIDPEncode<0b1010, (outs), (ins tGPR:$Rn, tGPR:$Rm),
1115               IIC_iCMPr,
1116               "cmp", "\t$Rn, $Rm",
1117               [(ARMcmp tGPR:$Rn, tGPR:$Rm)]>, Sched<[WriteCMP]>;
1118
1119def tCMPhir : T1pI<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_iCMPr,
1120                   "cmp", "\t$Rn, $Rm", []>,
1121              T1Special<{0,1,?,?}>, Sched<[WriteCMP]> {
1122  // A8.6.36 T2
1123  bits<4> Rm;
1124  bits<4> Rn;
1125  let Inst{7}   = Rn{3};
1126  let Inst{6-3} = Rm;
1127  let Inst{2-0} = Rn{2-0};
1128}
1129} // isCompare = 1, Defs = [CPSR]
1130
1131
1132// XOR register
1133let isCommutable = 1 in
1134def tEOR :                      // A8.6.45
1135  T1sItDPEncode<0b0001, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1136                IIC_iBITr,
1137                "eor", "\t$Rdn, $Rm",
1138                [(set tGPR:$Rdn, (xor tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1139
1140// LSL immediate
1141def tLSLri :                    // A8.6.88
1142  T1sIGenEncodeImm<{0,0,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_31:$imm5),
1143                   IIC_iMOVsi,
1144                   "lsl", "\t$Rd, $Rm, $imm5",
1145                   [(set tGPR:$Rd, (shl tGPR:$Rm, (i32 imm:$imm5)))]>,
1146                   Sched<[WriteALU]> {
1147  bits<5> imm5;
1148  let Inst{10-6} = imm5;
1149}
1150
1151// LSL register
1152def tLSLrr :                    // A8.6.89
1153  T1sItDPEncode<0b0010, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1154                IIC_iMOVsr,
1155                "lsl", "\t$Rdn, $Rm",
1156                [(set tGPR:$Rdn, (shl tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1157
1158// LSR immediate
1159def tLSRri :                    // A8.6.90
1160  T1sIGenEncodeImm<{0,0,1,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
1161                   IIC_iMOVsi,
1162                   "lsr", "\t$Rd, $Rm, $imm5",
1163                   [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm_sr:$imm5)))]>,
1164                   Sched<[WriteALU]> {
1165  bits<5> imm5;
1166  let Inst{10-6} = imm5;
1167}
1168
1169// LSR register
1170def tLSRrr :                    // A8.6.91
1171  T1sItDPEncode<0b0011, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1172                IIC_iMOVsr,
1173                "lsr", "\t$Rdn, $Rm",
1174                [(set tGPR:$Rdn, (srl tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1175
1176// Move register
1177let isMoveImm = 1 in
1178def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi,
1179                  "mov", "\t$Rd, $imm8",
1180                  [(set tGPR:$Rd, imm0_255:$imm8)]>,
1181             T1General<{1,0,0,?,?}>, Sched<[WriteALU]> {
1182  // A8.6.96
1183  bits<3> Rd;
1184  bits<8> imm8;
1185  let Inst{10-8} = Rd;
1186  let Inst{7-0}  = imm8;
1187}
1188// Because we have an explicit tMOVSr below, we need an alias to handle
1189// the immediate "movs" form here. Blech.
1190def : tInstAlias <"movs $Rdn, $imm",
1191                 (tMOVi8 tGPR:$Rdn, CPSR, imm0_255:$imm, 14, 0)>;
1192
1193// A7-73: MOV(2) - mov setting flag.
1194
1195let hasSideEffects = 0, isMoveReg = 1 in {
1196def tMOVr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone,
1197                      2, IIC_iMOVr,
1198                      "mov", "\t$Rd, $Rm", "", []>,
1199                  T1Special<{1,0,?,?}>, Sched<[WriteALU]> {
1200  // A8.6.97
1201  bits<4> Rd;
1202  bits<4> Rm;
1203  let Inst{7}   = Rd{3};
1204  let Inst{6-3} = Rm;
1205  let Inst{2-0} = Rd{2-0};
1206}
1207let Defs = [CPSR] in
1208def tMOVSr      : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
1209                      "movs\t$Rd, $Rm", []>, Encoding16, Sched<[WriteALU]> {
1210  // A8.6.97
1211  bits<3> Rd;
1212  bits<3> Rm;
1213  let Inst{15-6} = 0b0000000000;
1214  let Inst{5-3}  = Rm;
1215  let Inst{2-0}  = Rd;
1216}
1217} // hasSideEffects
1218
1219// Multiply register
1220let isCommutable = 1 in
1221def tMUL :                      // A8.6.105 T1
1222  Thumb1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), AddrModeNone, 2,
1223           IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", "$Rm = $Rd",
1224           [(set tGPR:$Rd, (mul tGPR:$Rn, tGPR:$Rm))]>,
1225      T1DataProcessing<0b1101>, Sched<[WriteMUL32, ReadMUL, ReadMUL]> {
1226  bits<3> Rd;
1227  bits<3> Rn;
1228  let Inst{5-3} = Rn;
1229  let Inst{2-0} = Rd;
1230  let AsmMatchConverter = "cvtThumbMultiply";
1231}
1232
1233def :tInstAlias<"mul${s}${p} $Rdm, $Rn", (tMUL tGPR:$Rdm, s_cc_out:$s, tGPR:$Rn,
1234                                               pred:$p)>;
1235
1236// Move inverse register
1237def tMVN :                      // A8.6.107
1238  T1sIDPEncode<0b1111, (outs tGPR:$Rd), (ins tGPR:$Rn), IIC_iMVNr,
1239               "mvn", "\t$Rd, $Rn",
1240               [(set tGPR:$Rd, (not tGPR:$Rn))]>, Sched<[WriteALU]>;
1241
1242// Bitwise or register
1243let isCommutable = 1 in
1244def tORR :                      // A8.6.114
1245  T1sItDPEncode<0b1100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1246                IIC_iBITr,
1247                "orr", "\t$Rdn, $Rm",
1248                [(set tGPR:$Rdn, (or tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
1249
1250// Swaps
1251def tREV :                      // A8.6.134
1252  T1pIMiscEncode<{1,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1253                 IIC_iUNAr,
1254                 "rev", "\t$Rd, $Rm",
1255                 [(set tGPR:$Rd, (bswap tGPR:$Rm))]>,
1256                 Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
1257
1258def tREV16 :                    // A8.6.135
1259  T1pIMiscEncode<{1,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1260                 IIC_iUNAr,
1261                 "rev16", "\t$Rd, $Rm",
1262             [(set tGPR:$Rd, (rotr (bswap tGPR:$Rm), (i32 16)))]>,
1263                Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
1264
1265def tREVSH :                    // A8.6.136
1266  T1pIMiscEncode<{1,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1267                 IIC_iUNAr,
1268                 "revsh", "\t$Rd, $Rm",
1269                 [(set tGPR:$Rd, (sra (bswap tGPR:$Rm), (i32 16)))]>,
1270                 Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
1271
1272// Rotate right register
1273def tROR :                      // A8.6.139
1274  T1sItDPEncode<0b0111, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1275                IIC_iMOVsr,
1276                "ror", "\t$Rdn, $Rm",
1277                [(set tGPR:$Rdn, (rotr tGPR:$Rn, tGPR:$Rm))]>,
1278                Sched<[WriteALU]>;
1279
1280// Negate register
1281def tRSB :                      // A8.6.141
1282  T1sIDPEncode<0b1001, (outs tGPR:$Rd), (ins tGPR:$Rn),
1283               IIC_iALUi,
1284               "rsb", "\t$Rd, $Rn, #0",
1285               [(set tGPR:$Rd, (ineg tGPR:$Rn))]>, Sched<[WriteALU]>;
1286
1287// Subtract with carry register
1288let Uses = [CPSR] in
1289def tSBC :                      // A8.6.151
1290  T1sItDPEncode<0b0110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1291                IIC_iALUr,
1292                "sbc", "\t$Rdn, $Rm",
1293                []>,
1294                Sched<[WriteALU]>;
1295
1296// Subtract immediate
1297def tSUBi3 :                    // A8.6.210 T1
1298  T1sIGenEncodeImm<0b01111, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
1299                   IIC_iALUi,
1300                   "sub", "\t$Rd, $Rm, $imm3",
1301                   [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7_neg:$imm3))]>,
1302                   Sched<[WriteALU]> {
1303  bits<3> imm3;
1304  let Inst{8-6} = imm3;
1305}
1306
1307def tSUBi8 :                    // A8.6.210 T2
1308  T1sItGenEncodeImm<{1,1,1,?,?}, (outs tGPR:$Rdn),
1309                    (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
1310                    "sub", "\t$Rdn, $imm8",
1311                    [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255_neg:$imm8))]>,
1312                    Sched<[WriteALU]>;
1313
1314def : tInstSubst<"add${s}${p} $rd, $rn, $imm",
1315                 (tSUBi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
1316
1317
1318def : tInstSubst<"add${s}${p} $rdn, $imm",
1319                 (tSUBi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
1320
1321
1322// Subtract register
1323def tSUBrr :                    // A8.6.212
1324  T1sIGenEncode<0b01101, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
1325                IIC_iALUr,
1326                "sub", "\t$Rd, $Rn, $Rm",
1327                [(set tGPR:$Rd, (sub tGPR:$Rn, tGPR:$Rm))]>,
1328                Sched<[WriteALU]>;
1329
1330def : tInstAlias <"sub${s}${p} $Rdn, $Rm",
1331                 (tSUBrr tGPR:$Rdn,s_cc_out:$s, tGPR:$Rdn, tGPR:$Rm, pred:$p)>;
1332
1333/// Similar to the above except these set the 's' bit so the
1334/// instruction modifies the CPSR register.
1335///
1336/// These opcodes will be converted to the real non-S opcodes by
1337/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
1338let hasPostISelHook = 1, Defs = [CPSR] in {
1339  let Uses = [CPSR] in
1340  def tSBCS : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1341                          2, IIC_iALUr,
1342                          [(set tGPR:$Rdn, CPSR, (ARMsube tGPR:$Rn, tGPR:$Rm,
1343                                                          CPSR))]>,
1344              Requires<[IsThumb1Only]>,
1345              Sched<[WriteALU]>;
1346
1347  def tSUBSi3 : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
1348                            2, IIC_iALUi,
1349                            [(set tGPR:$Rd, CPSR, (ARMsubc tGPR:$Rm,
1350                                                           imm0_7:$imm3))]>,
1351                Requires<[IsThumb1Only]>,
1352                Sched<[WriteALU]>;
1353
1354  def tSUBSi8 : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, imm0_255:$imm8),
1355                            2, IIC_iALUi,
1356                            [(set tGPR:$Rdn, CPSR, (ARMsubc tGPR:$Rn,
1357                                                            imm8_255:$imm8))]>,
1358                Requires<[IsThumb1Only]>,
1359                Sched<[WriteALU]>;
1360
1361  def tSUBSrr : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
1362                            2, IIC_iALUr,
1363                            [(set tGPR:$Rd, CPSR, (ARMsubc tGPR:$Rn,
1364                                                           tGPR:$Rm))]>,
1365                Requires<[IsThumb1Only]>,
1366                Sched<[WriteALU]>;
1367
1368  def tRSBS   : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn),
1369                            2, IIC_iALUr,
1370                            [(set tGPR:$Rd, CPSR, (ARMsubc 0, tGPR:$Rn))]>,
1371                Requires<[IsThumb1Only]>,
1372                Sched<[WriteALU]>;
1373
1374  def tLSLSri : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, imm0_31:$imm5),
1375                            2, IIC_iALUr,
1376                            [(set tGPR:$Rd, CPSR, (ARMlsls tGPR:$Rn, imm0_31:$imm5))]>,
1377                Requires<[IsThumb1Only]>,
1378                Sched<[WriteALU]>;
1379}
1380
1381
1382def : T1Pat<(ARMsubs tGPR:$Rn, tGPR:$Rm), (tSUBSrr $Rn, $Rm)>;
1383def : T1Pat<(ARMsubs tGPR:$Rn, imm0_7:$imm3), (tSUBSi3 $Rn, imm0_7:$imm3)>;
1384def : T1Pat<(ARMsubs tGPR:$Rn, imm0_255:$imm8), (tSUBSi8 $Rn, imm0_255:$imm8)>;
1385
1386
1387// Sign-extend byte
1388def tSXTB :                     // A8.6.222
1389  T1pIMiscEncode<{0,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1390                 IIC_iUNAr,
1391                 "sxtb", "\t$Rd, $Rm",
1392                 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i8))]>,
1393                 Requires<[IsThumb, IsThumb1Only, HasV6]>,
1394                 Sched<[WriteALU]>;
1395
1396// Sign-extend short
1397def tSXTH :                     // A8.6.224
1398  T1pIMiscEncode<{0,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1399                 IIC_iUNAr,
1400                 "sxth", "\t$Rd, $Rm",
1401                 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i16))]>,
1402                 Requires<[IsThumb, IsThumb1Only, HasV6]>,
1403                 Sched<[WriteALU]>;
1404
1405// Test
1406let isCompare = 1, isCommutable = 1, Defs = [CPSR] in
1407def tTST :                      // A8.6.230
1408  T1pIDPEncode<0b1000, (outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iTSTr,
1409               "tst", "\t$Rn, $Rm",
1410               [(ARMcmpZ (and_su tGPR:$Rn, tGPR:$Rm), 0)]>,
1411               Sched<[WriteALU]>;
1412
1413// A8.8.247  UDF - Undefined (Encoding T1)
1414def tUDF : TI<(outs), (ins imm0_255:$imm8), IIC_Br, "udf\t$imm8",
1415              [(int_arm_undefined imm0_255:$imm8)]>, Encoding16 {
1416  bits<8> imm8;
1417  let Inst{15-12} = 0b1101;
1418  let Inst{11-8} = 0b1110;
1419  let Inst{7-0} = imm8;
1420}
1421
1422def : Pat<(debugtrap), (tBKPT 0)>, Requires<[IsThumb, HasV5T]>;
1423def : Pat<(debugtrap), (tUDF 254)>, Requires<[IsThumb, NoV5T]>;
1424
1425def t__brkdiv0 : TI<(outs), (ins), IIC_Br, "__brkdiv0",
1426                    [(int_arm_undefined 249)]>, Encoding16,
1427    Requires<[IsThumb, IsWindows]> {
1428  let Inst = 0xdef9;
1429  let isTerminator = 1;
1430}
1431
1432// Zero-extend byte
1433def tUXTB :                     // A8.6.262
1434  T1pIMiscEncode<{0,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1435                 IIC_iUNAr,
1436                 "uxtb", "\t$Rd, $Rm",
1437                 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFF))]>,
1438                 Requires<[IsThumb, IsThumb1Only, HasV6]>,
1439                 Sched<[WriteALU]>;
1440
1441// Zero-extend short
1442def tUXTH :                     // A8.6.264
1443  T1pIMiscEncode<{0,0,1,0,1,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1444                 IIC_iUNAr,
1445                 "uxth", "\t$Rd, $Rm",
1446                 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFFFF))]>,
1447                 Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
1448
1449// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation.
1450// Expanded after instruction selection into a branch sequence.
1451let usesCustomInserter = 1 in  // Expanded after instruction selection.
1452  def tMOVCCr_pseudo :
1453  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, cmovpred:$p),
1454             NoItinerary,
1455             [(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, cmovpred:$p))]>;
1456
1457// tLEApcrel - Load a pc-relative address into a register without offending the
1458// assembler.
1459
1460def tADR : T1I<(outs tGPR:$Rd), (ins t_adrlabel:$addr, pred:$p),
1461               IIC_iALUi, "adr{$p}\t$Rd, $addr", []>,
1462               T1Encoding<{1,0,1,0,0,?}>, Sched<[WriteALU]> {
1463  bits<3> Rd;
1464  bits<8> addr;
1465  let Inst{10-8} = Rd;
1466  let Inst{7-0} = addr;
1467  let DecoderMethod = "DecodeThumbAddSpecialReg";
1468}
1469
1470let hasSideEffects = 0, isReMaterializable = 1 in
1471def tLEApcrel   : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p),
1472                              2, IIC_iALUi, []>, Sched<[WriteALU]>;
1473
1474let hasSideEffects = 1 in
1475def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd),
1476                              (ins i32imm:$label, pred:$p),
1477                              2, IIC_iALUi, []>, Sched<[WriteALU]>;
1478
1479// Thumb-1 doesn't have the TBB or TBH instructions, but we can synthesize them
1480// and make use of the same compressed jump table format as Thumb-2.
1481let Size = 2, isBranch = 1, isTerminator = 1, isBarrier = 1,
1482    isIndirectBranch = 1, isNotDuplicable = 1 in {
1483def tTBB_JT : tPseudoInst<(outs),
1484        (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0,
1485         IIC_Br, []>, Sched<[WriteBr]>;
1486
1487def tTBH_JT : tPseudoInst<(outs),
1488        (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0,
1489         IIC_Br, []>,  Sched<[WriteBr]>;
1490}
1491
1492//===----------------------------------------------------------------------===//
1493// TLS Instructions
1494//
1495
1496// __aeabi_read_tp preserves the registers r1-r3.
1497// This is a pseudo inst so that we can get the encoding right,
1498// complete with fixup for the aeabi_read_tp function.
1499let isCall = 1, Defs = [R0, R12, LR, CPSR], Uses = [SP] in
1500def tTPsoft : tPseudoInst<(outs), (ins), 4, IIC_Br,
1501                          [(set R0, ARMthread_pointer)]>,
1502                          Sched<[WriteBr]>;
1503
1504//===----------------------------------------------------------------------===//
1505// SJLJ Exception handling intrinsics
1506//
1507
1508// eh_sjlj_setjmp() is an instruction sequence to store the return address and
1509// save #0 in R0 for the non-longjmp case.  Since by its nature we may be coming
1510// from some other function to get here, and we're using the stack frame for the
1511// containing function to save/restore registers, we can't keep anything live in
1512// regs across the eh_sjlj_setjmp(), else it will almost certainly have been
1513// tromped upon when we get here from a longjmp(). We force everything out of
1514// registers except for our own input by listing the relevant registers in
1515// Defs. By doing so, we also cause the prologue/epilogue code to actively
1516// preserve all of the callee-saved resgisters, which is exactly what we want.
1517// $val is a scratch register for our use.
1518let Defs = [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7, R12, CPSR ],
1519    hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
1520    usesCustomInserter = 1 in
1521def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
1522                                  AddrModeNone, 0, NoItinerary, "","",
1523                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
1524
1525// FIXME: Non-IOS version(s)
1526let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
1527    Defs = [ R7, LR, SP ] in
1528def tInt_eh_sjlj_longjmp : XI<(outs), (ins tGPR:$src, tGPR:$scratch),
1529                              AddrModeNone, 0, IndexModeNone,
1530                              Pseudo, NoItinerary, "", "",
1531                              [(ARMeh_sjlj_longjmp tGPR:$src, tGPR:$scratch)]>,
1532                             Requires<[IsThumb,IsNotWindows]>;
1533
1534// (Windows is Thumb2-only)
1535let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
1536    Defs = [ R11, LR, SP ] in
1537def tInt_WIN_eh_sjlj_longjmp
1538  : XI<(outs), (ins GPR:$src, GPR:$scratch), AddrModeNone, 0, IndexModeNone,
1539       Pseudo, NoItinerary, "", "", [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
1540    Requires<[IsThumb,IsWindows]>;
1541
1542//===----------------------------------------------------------------------===//
1543// Non-Instruction Patterns
1544//
1545
1546// Comparisons
1547def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
1548            (tCMPi8  tGPR:$Rn, imm0_255:$imm8)>;
1549def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
1550            (tCMPr   tGPR:$Rn, tGPR:$Rm)>;
1551
1552// Bswap 16 with load/store
1553def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
1554            (tREV16 (tLDRHi t_addrmode_is2:$addr))>;
1555def : T1Pat<(srl (bswap (extloadi16 t_addrmode_rr:$addr)), (i32 16)),
1556            (tREV16 (tLDRHr t_addrmode_rr:$addr))>;
1557def : T1Pat<(truncstorei16 (srl (bswap tGPR:$Rn), (i32 16)),
1558                           t_addrmode_is2:$addr),
1559            (tSTRHi(tREV16 tGPR:$Rn), t_addrmode_is2:$addr)>;
1560def : T1Pat<(truncstorei16 (srl (bswap tGPR:$Rn), (i32 16)),
1561                           t_addrmode_rr:$addr),
1562            (tSTRHr (tREV16 tGPR:$Rn), t_addrmode_rr:$addr)>;
1563
1564// ConstantPool
1565def : T1Pat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
1566
1567// GlobalAddress
1568def tLDRLIT_ga_pcrel : PseudoInst<(outs tGPR:$dst), (ins i32imm:$addr),
1569                                  IIC_iLoadiALU,
1570                                  [(set tGPR:$dst,
1571                                        (ARMWrapperPIC tglobaladdr:$addr))]>,
1572                       Requires<[IsThumb, DontUseMovtInPic]>;
1573
1574def tLDRLIT_ga_abs : PseudoInst<(outs tGPR:$dst), (ins i32imm:$src),
1575                                IIC_iLoad_i,
1576                                [(set tGPR:$dst,
1577                                      (ARMWrapper tglobaladdr:$src))]>,
1578                     Requires<[IsThumb, DontUseMovt]>;
1579
1580// TLS globals
1581def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr),
1582          (tLDRLIT_ga_pcrel tglobaltlsaddr:$addr)>,
1583      Requires<[IsThumb, DontUseMovtInPic]>;
1584def : Pat<(ARMWrapper tglobaltlsaddr:$addr),
1585          (tLDRLIT_ga_abs tglobaltlsaddr:$addr)>,
1586      Requires<[IsThumb, DontUseMovt]>;
1587
1588
1589// JumpTable
1590def : T1Pat<(ARMWrapperJT tjumptable:$dst),
1591            (tLEApcrelJT tjumptable:$dst)>;
1592
1593// Direct calls
1594def : T1Pat<(ARMcall texternalsym:$func), (tBL texternalsym:$func)>,
1595      Requires<[IsThumb]>;
1596
1597// zextload i1 -> zextload i8
1598def : T1Pat<(zextloadi1 t_addrmode_is1:$addr),
1599            (tLDRBi t_addrmode_is1:$addr)>;
1600def : T1Pat<(zextloadi1 t_addrmode_rr:$addr),
1601            (tLDRBr t_addrmode_rr:$addr)>;
1602
1603// extload from the stack -> word load from the stack, as it avoids having to
1604// materialize the base in a separate register. This only works when a word
1605// load puts the byte/halfword value in the same place in the register that the
1606// byte/halfword load would, i.e. when little-endian.
1607def : T1Pat<(extloadi1  t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
1608      Requires<[IsThumb, IsThumb1Only, IsLE]>;
1609def : T1Pat<(extloadi8  t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
1610      Requires<[IsThumb, IsThumb1Only, IsLE]>;
1611def : T1Pat<(extloadi16 t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
1612      Requires<[IsThumb, IsThumb1Only, IsLE]>;
1613
1614// extload -> zextload
1615def : T1Pat<(extloadi1  t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>;
1616def : T1Pat<(extloadi1  t_addrmode_rr:$addr),  (tLDRBr t_addrmode_rr:$addr)>;
1617def : T1Pat<(extloadi8  t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>;
1618def : T1Pat<(extloadi8  t_addrmode_rr:$addr),  (tLDRBr t_addrmode_rr:$addr)>;
1619def : T1Pat<(extloadi16 t_addrmode_is2:$addr), (tLDRHi t_addrmode_is2:$addr)>;
1620def : T1Pat<(extloadi16 t_addrmode_rr:$addr),  (tLDRHr t_addrmode_rr:$addr)>;
1621
1622// post-inc loads and stores
1623
1624// post-inc LDR -> LDM r0!, {r1}. The way operands are layed out in LDMs is
1625// different to how ISel expects them for a post-inc load, so use a pseudo
1626// and expand it just after ISel.
1627let usesCustomInserter = 1, mayLoad =1,
1628    Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in
1629 def tLDR_postidx: tPseudoInst<(outs tGPR:$Rt, tGPR:$Rn_wb),
1630                               (ins tGPR:$Rn, pred:$p),
1631                               4, IIC_iStore_ru,
1632                               []>;
1633
1634// post-inc STR -> STM r0!, {r1}. The layout of this (because it doesn't def
1635// multiple registers) is the same in ISel as MachineInstr, so there's no need
1636// for a pseudo.
1637def : T1Pat<(post_store tGPR:$Rt, tGPR:$Rn, 4),
1638            (tSTMIA_UPD tGPR:$Rn, tGPR:$Rt)>;
1639
1640// If it's impossible to use [r,r] address mode for sextload, select to
1641// ldr{b|h} + sxt{b|h} instead.
1642def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
1643            (tSXTB (tLDRBi t_addrmode_is1:$addr))>,
1644      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1645def : T1Pat<(sextloadi8 t_addrmode_rr:$addr),
1646            (tSXTB (tLDRBr t_addrmode_rr:$addr))>,
1647      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1648def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
1649            (tSXTH (tLDRHi t_addrmode_is2:$addr))>,
1650      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1651def : T1Pat<(sextloadi16 t_addrmode_rr:$addr),
1652            (tSXTH (tLDRHr t_addrmode_rr:$addr))>,
1653      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1654
1655def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
1656            (tASRri (tLSLri (tLDRBi t_addrmode_is1:$addr), 24), 24)>;
1657def : T1Pat<(sextloadi8 t_addrmode_rr:$addr),
1658            (tASRri (tLSLri (tLDRBr t_addrmode_rr:$addr), 24), 24)>;
1659def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
1660            (tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>;
1661def : T1Pat<(sextloadi16 t_addrmode_rr:$addr),
1662            (tASRri (tLSLri (tLDRHr t_addrmode_rr:$addr), 16), 16)>;
1663
1664def : T1Pat<(atomic_load_8 t_addrmode_is1:$src),
1665             (tLDRBi t_addrmode_is1:$src)>;
1666def : T1Pat<(atomic_load_8 t_addrmode_rr:$src),
1667             (tLDRBr t_addrmode_rr:$src)>;
1668def : T1Pat<(atomic_load_16 t_addrmode_is2:$src),
1669             (tLDRHi t_addrmode_is2:$src)>;
1670def : T1Pat<(atomic_load_16 t_addrmode_rr:$src),
1671             (tLDRHr t_addrmode_rr:$src)>;
1672def : T1Pat<(atomic_load_32 t_addrmode_is4:$src),
1673             (tLDRi t_addrmode_is4:$src)>;
1674def : T1Pat<(atomic_load_32 t_addrmode_rr:$src),
1675             (tLDRr t_addrmode_rr:$src)>;
1676def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val),
1677             (tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>;
1678def : T1Pat<(atomic_store_8 t_addrmode_rr:$ptr, tGPR:$val),
1679             (tSTRBr tGPR:$val, t_addrmode_rr:$ptr)>;
1680def : T1Pat<(atomic_store_16 t_addrmode_is2:$ptr, tGPR:$val),
1681             (tSTRHi tGPR:$val, t_addrmode_is2:$ptr)>;
1682def : T1Pat<(atomic_store_16 t_addrmode_rr:$ptr, tGPR:$val),
1683             (tSTRHr tGPR:$val, t_addrmode_rr:$ptr)>;
1684def : T1Pat<(atomic_store_32 t_addrmode_is4:$ptr, tGPR:$val),
1685             (tSTRi tGPR:$val, t_addrmode_is4:$ptr)>;
1686def : T1Pat<(atomic_store_32 t_addrmode_rr:$ptr, tGPR:$val),
1687             (tSTRr tGPR:$val, t_addrmode_rr:$ptr)>;
1688
1689// Large immediate handling.
1690
1691// Two piece imms.
1692def : T1Pat<(i32 thumb_immshifted:$src),
1693            (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
1694                    (thumb_immshifted_shamt imm:$src))>;
1695
1696def : T1Pat<(i32 imm0_255_comp:$src),
1697            (tMVN (tMOVi8 (imm_not_XFORM imm:$src)))>;
1698
1699def : T1Pat<(i32 imm256_510:$src),
1700            (tADDi8 (tMOVi8 255),
1701                    (thumb_imm256_510_addend imm:$src))>;
1702
1703// Pseudo instruction that combines ldr from constpool and add pc. This should
1704// be expanded into two instructions late to allow if-conversion and
1705// scheduling.
1706let isReMaterializable = 1 in
1707def tLDRpci_pic : PseudoInst<(outs tGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
1708                             NoItinerary,
1709               [(set tGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
1710                                           imm:$cp))]>,
1711               Requires<[IsThumb, IsThumb1Only]>;
1712
1713// Pseudo-instruction for merged POP and return.
1714// FIXME: remove when we have a way to marking a MI with these properties.
1715let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1716    hasExtraDefRegAllocReq = 1 in
1717def tPOP_RET : tPseudoExpand<(outs), (ins pred:$p, reglist:$regs, variable_ops),
1718                           2, IIC_iPop_Br, [],
1719                           (tPOP pred:$p, reglist:$regs)>, Sched<[WriteBrL]>;
1720
1721// Indirect branch using "mov pc, $Rm"
1722let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1723  def tBRIND : tPseudoExpand<(outs), (ins GPR:$Rm, pred:$p),
1724                  2, IIC_Br, [(brind GPR:$Rm)],
1725                  (tMOVr PC, GPR:$Rm, pred:$p)>, Sched<[WriteBr]>;
1726}
1727
1728
1729// In Thumb1, "nop" is encoded as a "mov r8, r8". Technically, the bf00
1730// encoding is available on ARMv6K, but we don't differentiate that finely.
1731def : InstAlias<"nop", (tMOVr R8, R8, 14, 0), 0>, Requires<[IsThumb, IsThumb1Only]>;
1732
1733
1734// "neg" is and alias for "rsb rd, rn, #0"
1735def : tInstAlias<"neg${s}${p} $Rd, $Rm",
1736                 (tRSB tGPR:$Rd, s_cc_out:$s, tGPR:$Rm, pred:$p)>;
1737
1738
1739// Implied destination operand forms for shifts.
1740def : tInstAlias<"lsl${s}${p} $Rdm, $imm",
1741             (tLSLri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm0_31:$imm, pred:$p)>;
1742def : tInstAlias<"lsr${s}${p} $Rdm, $imm",
1743             (tLSRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
1744def : tInstAlias<"asr${s}${p} $Rdm, $imm",
1745             (tASRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
1746
1747// Pseudo instruction ldr Rt, =immediate
1748def tLDRConstPool
1749  : tAsmPseudo<"ldr${p} $Rt, $immediate",
1750               (ins tGPR:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
1751