ARMInstrThumb.td revision 226633
1//===- ARMInstrThumb.td - Thumb support for ARM ------------*- tablegen -*-===//
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, SDNPOptInGlue, SDNPOutGlue,
20                       SDNPVariadic]>;
21
22def imm_sr_XFORM: SDNodeXForm<imm, [{
23  unsigned Imm = N->getZExtValue();
24  return CurDAG->getTargetConstant((Imm == 32 ? 0 : Imm), MVT::i32);
25}]>;
26def ThumbSRImmAsmOperand: AsmOperandClass { let Name = "ImmThumbSR"; }
27def imm_sr : Operand<i32>, PatLeaf<(imm), [{
28  uint64_t Imm = N->getZExtValue();
29  return Imm > 0 && Imm <= 32;
30}], imm_sr_XFORM> {
31  let PrintMethod = "printThumbSRImm";
32  let ParserMatchClass = ThumbSRImmAsmOperand;
33}
34
35def imm_neg_XFORM : SDNodeXForm<imm, [{
36  return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
37}]>;
38def imm_comp_XFORM : SDNodeXForm<imm, [{
39  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
40}]>;
41
42def imm0_7_neg : PatLeaf<(i32 imm), [{
43  return (uint32_t)-N->getZExtValue() < 8;
44}], imm_neg_XFORM>;
45
46def imm0_255_comp : PatLeaf<(i32 imm), [{
47  return ~((uint32_t)N->getZExtValue()) < 256;
48}]>;
49
50def imm8_255 : ImmLeaf<i32, [{
51  return Imm >= 8 && Imm < 256;
52}]>;
53def imm8_255_neg : PatLeaf<(i32 imm), [{
54  unsigned Val = -N->getZExtValue();
55  return Val >= 8 && Val < 256;
56}], imm_neg_XFORM>;
57
58// Break imm's up into two pieces: an immediate + a left shift. This uses
59// thumb_immshifted to match and thumb_immshifted_val and thumb_immshifted_shamt
60// to get the val/shift pieces.
61def thumb_immshifted : PatLeaf<(imm), [{
62  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
63}]>;
64
65def thumb_immshifted_val : SDNodeXForm<imm, [{
66  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
67  return CurDAG->getTargetConstant(V, MVT::i32);
68}]>;
69
70def thumb_immshifted_shamt : SDNodeXForm<imm, [{
71  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
72  return CurDAG->getTargetConstant(V, MVT::i32);
73}]>;
74
75// ADR instruction labels.
76def t_adrlabel : Operand<i32> {
77  let EncoderMethod = "getThumbAdrLabelOpValue";
78}
79
80// Scaled 4 immediate.
81def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; }
82def t_imm0_1020s4 : Operand<i32> {
83  let PrintMethod = "printThumbS4ImmOperand";
84  let ParserMatchClass = t_imm0_1020s4_asmoperand;
85  let OperandType = "OPERAND_IMMEDIATE";
86}
87
88def t_imm0_508s4_asmoperand: AsmOperandClass { let Name = "Imm0_508s4"; }
89def t_imm0_508s4 : Operand<i32> {
90  let PrintMethod = "printThumbS4ImmOperand";
91  let ParserMatchClass = t_imm0_508s4_asmoperand;
92  let OperandType = "OPERAND_IMMEDIATE";
93}
94
95// Define Thumb specific addressing modes.
96
97let OperandType = "OPERAND_PCREL" in {
98def t_brtarget : Operand<OtherVT> {
99  let EncoderMethod = "getThumbBRTargetOpValue";
100  let DecoderMethod = "DecodeThumbBROperand";
101}
102
103def t_bcctarget : Operand<i32> {
104  let EncoderMethod = "getThumbBCCTargetOpValue";
105  let DecoderMethod = "DecodeThumbBCCTargetOperand";
106}
107
108def t_cbtarget : Operand<i32> {
109  let EncoderMethod = "getThumbCBTargetOpValue";
110  let DecoderMethod = "DecodeThumbCmpBROperand";
111}
112
113def t_bltarget : Operand<i32> {
114  let EncoderMethod = "getThumbBLTargetOpValue";
115  let DecoderMethod = "DecodeThumbBLTargetOperand";
116}
117
118def t_blxtarget : Operand<i32> {
119  let EncoderMethod = "getThumbBLXTargetOpValue";
120  let DecoderMethod = "DecodeThumbBLXOffset";
121}
122}
123
124// t_addrmode_rr := reg + reg
125//
126def t_addrmode_rr_asm_operand : AsmOperandClass { let Name = "MemThumbRR"; }
127def t_addrmode_rr : Operand<i32>,
128                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
129  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
130  let PrintMethod = "printThumbAddrModeRROperand";
131  let DecoderMethod = "DecodeThumbAddrModeRR";
132  let ParserMatchClass = t_addrmode_rr_asm_operand;
133  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
134}
135
136// t_addrmode_rrs := reg + reg
137//
138// We use separate scaled versions because the Select* functions need
139// to explicitly check for a matching constant and return false here so that
140// the reg+imm forms will match instead. This is a horrible way to do that,
141// as it forces tight coupling between the methods, but it's how selectiondag
142// currently works.
143def t_addrmode_rrs1 : Operand<i32>,
144                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> {
145  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
146  let PrintMethod = "printThumbAddrModeRROperand";
147  let DecoderMethod = "DecodeThumbAddrModeRR";
148  let ParserMatchClass = t_addrmode_rr_asm_operand;
149  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
150}
151def t_addrmode_rrs2 : Operand<i32>,
152                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> {
153  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
154  let DecoderMethod = "DecodeThumbAddrModeRR";
155  let PrintMethod = "printThumbAddrModeRROperand";
156  let ParserMatchClass = t_addrmode_rr_asm_operand;
157  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
158}
159def t_addrmode_rrs4 : Operand<i32>,
160                      ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> {
161  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
162  let DecoderMethod = "DecodeThumbAddrModeRR";
163  let PrintMethod = "printThumbAddrModeRROperand";
164  let ParserMatchClass = t_addrmode_rr_asm_operand;
165  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
166}
167
168// t_addrmode_is4 := reg + imm5 * 4
169//
170def t_addrmode_is4_asm_operand : AsmOperandClass { let Name = "MemThumbRIs4"; }
171def t_addrmode_is4 : Operand<i32>,
172                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> {
173  let EncoderMethod = "getAddrModeISOpValue";
174  let DecoderMethod = "DecodeThumbAddrModeIS";
175  let PrintMethod = "printThumbAddrModeImm5S4Operand";
176  let ParserMatchClass = t_addrmode_is4_asm_operand;
177  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
178}
179
180// t_addrmode_is2 := reg + imm5 * 2
181//
182def t_addrmode_is2_asm_operand : AsmOperandClass { let Name = "MemThumbRIs2"; }
183def t_addrmode_is2 : Operand<i32>,
184                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> {
185  let EncoderMethod = "getAddrModeISOpValue";
186  let DecoderMethod = "DecodeThumbAddrModeIS";
187  let PrintMethod = "printThumbAddrModeImm5S2Operand";
188  let ParserMatchClass = t_addrmode_is2_asm_operand;
189  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
190}
191
192// t_addrmode_is1 := reg + imm5
193//
194def t_addrmode_is1_asm_operand : AsmOperandClass { let Name = "MemThumbRIs1"; }
195def t_addrmode_is1 : Operand<i32>,
196                     ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> {
197  let EncoderMethod = "getAddrModeISOpValue";
198  let DecoderMethod = "DecodeThumbAddrModeIS";
199  let PrintMethod = "printThumbAddrModeImm5S1Operand";
200  let ParserMatchClass = t_addrmode_is1_asm_operand;
201  let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
202}
203
204// t_addrmode_sp := sp + imm8 * 4
205//
206// FIXME: This really shouldn't have an explicit SP operand at all. It should
207// be implicit, just like in the instruction encoding itself.
208def t_addrmode_sp_asm_operand : AsmOperandClass { let Name = "MemThumbSPI"; }
209def t_addrmode_sp : Operand<i32>,
210                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
211  let EncoderMethod = "getAddrModeThumbSPOpValue";
212  let DecoderMethod = "DecodeThumbAddrModeSP";
213  let PrintMethod = "printThumbAddrModeSPOperand";
214  let ParserMatchClass = t_addrmode_sp_asm_operand;
215  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
216}
217
218// t_addrmode_pc := <label> => pc + imm8 * 4
219//
220def t_addrmode_pc : Operand<i32> {
221  let EncoderMethod = "getAddrModePCOpValue";
222  let DecoderMethod = "DecodeThumbAddrModePC";
223}
224
225//===----------------------------------------------------------------------===//
226//  Miscellaneous Instructions.
227//
228
229// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
230// from removing one half of the matched pairs. That breaks PEI, which assumes
231// these will always be in pairs, and asserts if it finds otherwise. Better way?
232let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
233def tADJCALLSTACKUP :
234  PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
235             [(ARMcallseq_end imm:$amt1, imm:$amt2)]>,
236            Requires<[IsThumb, IsThumb1Only]>;
237
238def tADJCALLSTACKDOWN :
239  PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
240             [(ARMcallseq_start imm:$amt)]>,
241            Requires<[IsThumb, IsThumb1Only]>;
242}
243
244class T1SystemEncoding<bits<8> opc>
245  : T1Encoding<0b101111> {
246  let Inst{9-8} = 0b11;
247  let Inst{7-0} = opc;
248}
249
250def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "", []>,
251           T1SystemEncoding<0x00>, // A8.6.110
252        Requires<[IsThumb2]>;
253
254def tYIELD : T1pI<(outs), (ins), NoItinerary, "yield", "", []>,
255           T1SystemEncoding<0x10>; // A8.6.410
256
257def tWFE : T1pI<(outs), (ins), NoItinerary, "wfe", "", []>,
258           T1SystemEncoding<0x20>; // A8.6.408
259
260def tWFI : T1pI<(outs), (ins), NoItinerary, "wfi", "", []>,
261           T1SystemEncoding<0x30>; // A8.6.409
262
263def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", []>,
264           T1SystemEncoding<0x40>; // A8.6.157
265
266// The imm operand $val can be used by a debugger to store more information
267// about the breakpoint.
268def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val",
269                []>,
270           T1Encoding<0b101111> {
271  let Inst{9-8} = 0b10;
272  // A8.6.22
273  bits<8> val;
274  let Inst{7-0} = val;
275}
276
277def tSETEND : T1I<(outs), (ins setend_op:$end), NoItinerary, "setend\t$end",
278                  []>, T1Encoding<0b101101> {
279  bits<1> end;
280  // A8.6.156
281  let Inst{9-5} = 0b10010;
282  let Inst{4}   = 1;
283  let Inst{3}   = end;
284  let Inst{2-0} = 0b000;
285}
286
287// Change Processor State is a system instruction -- for disassembly only.
288def tCPS : T1I<(outs), (ins imod_op:$imod, iflags_op:$iflags),
289                NoItinerary, "cps$imod $iflags", []>,
290           T1Misc<0b0110011> {
291  // A8.6.38 & B6.1.1
292  bit imod;
293  bits<3> iflags;
294
295  let Inst{4}   = imod;
296  let Inst{3}   = 0;
297  let Inst{2-0} = iflags;
298  let DecoderMethod = "DecodeThumbCPS";
299}
300
301// For both thumb1 and thumb2.
302let isNotDuplicable = 1, isCodeGenOnly = 1 in
303def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, "",
304                  [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>,
305              T1Special<{0,0,?,?}> {
306  // A8.6.6
307  bits<3> dst;
308  let Inst{6-3} = 0b1111; // Rm = pc
309  let Inst{2-0} = dst;
310}
311
312// ADD <Rd>, sp, #<imm8>
313// FIXME: This should not be marked as having side effects, and it should be
314// rematerializable. Clearing the side effect bit causes miscompilations,
315// probably because the instruction can be moved around.
316def tADDrSPi : T1pI<(outs tGPR:$dst), (ins GPRsp:$sp, t_imm0_1020s4:$imm),
317                    IIC_iALUi, "add", "\t$dst, $sp, $imm", []>,
318               T1Encoding<{1,0,1,0,1,?}> {
319  // A6.2 & A8.6.8
320  bits<3> dst;
321  bits<8> imm;
322  let Inst{10-8} = dst;
323  let Inst{7-0}  = imm;
324  let DecoderMethod = "DecodeThumbAddSpecialReg";
325}
326
327// ADD sp, sp, #<imm7>
328def tADDspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
329                     IIC_iALUi, "add", "\t$Rdn, $imm", []>,
330              T1Misc<{0,0,0,0,0,?,?}> {
331  // A6.2.5 & A8.6.8
332  bits<7> imm;
333  let Inst{6-0} = imm;
334  let DecoderMethod = "DecodeThumbAddSPImm";
335}
336
337// SUB sp, sp, #<imm7>
338// FIXME: The encoding and the ASM string don't match up.
339def tSUBspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
340                    IIC_iALUi, "sub", "\t$Rdn, $imm", []>,
341              T1Misc<{0,0,0,0,1,?,?}> {
342  // A6.2.5 & A8.6.214
343  bits<7> imm;
344  let Inst{6-0} = imm;
345  let DecoderMethod = "DecodeThumbAddSPImm";
346}
347
348// Can optionally specify SP as a three operand instruction.
349def : tInstAlias<"add${p} sp, sp, $imm",
350                 (tADDspi SP, t_imm0_508s4:$imm, pred:$p)>;
351def : tInstAlias<"sub${p} sp, sp, $imm",
352                 (tSUBspi SP, t_imm0_508s4:$imm, pred:$p)>;
353
354// ADD <Rm>, sp
355def tADDrSP : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPRsp:$sp), IIC_iALUr,
356                  "add", "\t$Rdn, $sp, $Rn", []>,
357              T1Special<{0,0,?,?}> {
358  // A8.6.9 Encoding T1
359  bits<4> Rdn;
360  let Inst{7}   = Rdn{3};
361  let Inst{6-3} = 0b1101;
362  let Inst{2-0} = Rdn{2-0};
363  let DecoderMethod = "DecodeThumbAddSPReg";
364}
365
366// ADD sp, <Rm>
367def tADDspr : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, GPR:$Rm), IIC_iALUr,
368                  "add", "\t$Rdn, $Rm", []>,
369              T1Special<{0,0,?,?}> {
370  // A8.6.9 Encoding T2
371  bits<4> Rm;
372  let Inst{7} = 1;
373  let Inst{6-3} = Rm;
374  let Inst{2-0} = 0b101;
375  let DecoderMethod = "DecodeThumbAddSPReg";
376}
377
378//===----------------------------------------------------------------------===//
379//  Control Flow Instructions.
380//
381
382// Indirect branches
383let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
384  def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>,
385            T1Special<{1,1,0,?}> {
386    // A6.2.3 & A8.6.25
387    bits<4> Rm;
388    let Inst{6-3} = Rm;
389    let Inst{2-0} = 0b000;
390  }
391}
392
393let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
394  def tBX_RET : tPseudoExpand<(outs), (ins pred:$p), 2, IIC_Br,
395                   [(ARMretflag)], (tBX LR, pred:$p)>;
396
397  // Alternative return instruction used by vararg functions.
398  def tBX_RET_vararg : tPseudoExpand<(outs), (ins tGPR:$Rm, pred:$p),
399                   2, IIC_Br, [],
400                   (tBX GPR:$Rm, pred:$p)>;
401}
402
403// All calls clobber the non-callee saved registers. SP is marked as a use to
404// prevent stack-pointer assignments that appear immediately before calls from
405// potentially appearing dead.
406let isCall = 1,
407  // On non-Darwin platforms R9 is callee-saved.
408  Defs = [R0,  R1,  R2,  R3,  R12, LR, QQQQ0, QQQQ2, QQQQ3, CPSR, FPSCR],
409  Uses = [SP] in {
410  // Also used for Thumb2
411  def tBL  : TIx2<0b11110, 0b11, 1,
412                  (outs), (ins pred:$p, t_bltarget:$func, variable_ops), IIC_Br,
413                  "bl${p}\t$func",
414                  [(ARMtcall tglobaladdr:$func)]>,
415             Requires<[IsThumb, IsNotDarwin]> {
416    bits<22> func;
417    let Inst{26} = func{21};
418    let Inst{25-16} = func{20-11};
419    let Inst{13} = 1;
420    let Inst{11} = 1;
421    let Inst{10-0} = func{10-0};
422  }
423
424  // ARMv5T and above, also used for Thumb2
425  def tBLXi : TIx2<0b11110, 0b11, 0,
426                 (outs), (ins pred:$p, t_blxtarget:$func, variable_ops), IIC_Br,
427                   "blx${p}\t$func",
428                   [(ARMcall tglobaladdr:$func)]>,
429              Requires<[IsThumb, HasV5T, IsNotDarwin]> {
430    bits<21> func;
431    let Inst{25-16} = func{20-11};
432    let Inst{13} = 1;
433    let Inst{11} = 1;
434    let Inst{10-1} = func{10-1};
435    let Inst{0} = 0; // func{0} is assumed zero
436  }
437
438  // Also used for Thumb2
439  def tBLXr : TI<(outs), (ins pred:$p, GPR:$func, variable_ops), IIC_Br,
440                  "blx${p}\t$func",
441                  [(ARMtcall GPR:$func)]>,
442              Requires<[IsThumb, HasV5T, IsNotDarwin]>,
443              T1Special<{1,1,1,?}> { // A6.2.3 & A8.6.24;
444    bits<4> func;
445    let Inst{6-3} = func;
446    let Inst{2-0} = 0b000;
447  }
448
449  // ARMv4T
450  def tBX_CALL : tPseudoInst<(outs), (ins tGPR:$func, variable_ops),
451                  4, IIC_Br,
452                  [(ARMcall_nolink tGPR:$func)]>,
453            Requires<[IsThumb, IsThumb1Only, IsNotDarwin]>;
454}
455
456let isCall = 1,
457  // On Darwin R9 is call-clobbered.
458  // R7 is marked as a use to prevent frame-pointer assignments from being
459  // moved above / below calls.
460  Defs = [R0,  R1,  R2,  R3,  R9,  R12, LR, QQQQ0, QQQQ2, QQQQ3, CPSR, FPSCR],
461  Uses = [R7, SP] in {
462  // Also used for Thumb2
463  def tBLr9 : tPseudoExpand<(outs), (ins pred:$p, t_bltarget:$func, variable_ops),
464                          4, IIC_Br, [(ARMtcall tglobaladdr:$func)],
465                          (tBL pred:$p, t_bltarget:$func)>,
466              Requires<[IsThumb, IsDarwin]>;
467
468  // ARMv5T and above, also used for Thumb2
469  def tBLXi_r9 : tPseudoExpand<(outs), (ins pred:$p, t_blxtarget:$func, variable_ops),
470                      4, IIC_Br, [(ARMcall tglobaladdr:$func)],
471                      (tBLXi pred:$p, t_blxtarget:$func)>,
472                 Requires<[IsThumb, HasV5T, IsDarwin]>;
473
474  // Also used for Thumb2
475  def tBLXr_r9 : tPseudoExpand<(outs), (ins pred:$p, GPR:$func, variable_ops),
476                    2, IIC_Br, [(ARMtcall GPR:$func)],
477                    (tBLXr pred:$p, GPR:$func)>,
478                 Requires<[IsThumb, HasV5T, IsDarwin]>;
479
480  // ARMv4T
481  def tBXr9_CALL : tPseudoInst<(outs), (ins tGPR:$func, variable_ops),
482                   4, IIC_Br,
483                   [(ARMcall_nolink tGPR:$func)]>,
484              Requires<[IsThumb, IsThumb1Only, IsDarwin]>;
485}
486
487let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
488  let isPredicable = 1 in
489  def tB   : T1pI<(outs), (ins t_brtarget:$target), IIC_Br,
490                 "b", "\t$target", [(br bb:$target)]>,
491             T1Encoding<{1,1,1,0,0,?}> {
492    bits<11> target;
493    let Inst{10-0} = target;
494  }
495
496  // Far jump
497  // Just a pseudo for a tBL instruction. Needed to let regalloc know about
498  // the clobber of LR.
499  let Defs = [LR] in
500  def tBfar : tPseudoExpand<(outs), (ins t_bltarget:$target, pred:$p),
501                          4, IIC_Br, [], (tBL pred:$p, t_bltarget:$target)>;
502
503  def tBR_JTr : tPseudoInst<(outs),
504                      (ins tGPR:$target, i32imm:$jt, i32imm:$id),
505                      0, IIC_Br,
506                      [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]> {
507    list<Predicate> Predicates = [IsThumb, IsThumb1Only];
508  }
509}
510
511// FIXME: should be able to write a pattern for ARMBrcond, but can't use
512// a two-value operand where a dag node expects two operands. :(
513let isBranch = 1, isTerminator = 1 in
514  def tBcc : T1I<(outs), (ins t_bcctarget:$target, pred:$p), IIC_Br,
515                 "b${p}\t$target",
516                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
517             T1BranchCond<{1,1,0,1}> {
518  bits<4> p;
519  bits<8> target;
520  let Inst{11-8} = p;
521  let Inst{7-0} = target;
522}
523
524// Tail calls
525let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
526  // Darwin versions.
527  let Defs = [R0, R1, R2, R3, R9, R12, QQQQ0, QQQQ2, QQQQ3, PC],
528      Uses = [SP] in {
529    // tTAILJMPd: Darwin version uses a Thumb2 branch (no Thumb1 tail calls
530    // on Darwin), so it's in ARMInstrThumb2.td.
531    def tTAILJMPr : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
532                     4, IIC_Br, [],
533                     (tBX GPR:$dst, (ops 14, zero_reg))>,
534                     Requires<[IsThumb, IsDarwin]>;
535  }
536  // Non-Darwin versions (the difference is R9).
537  let Defs = [R0, R1, R2, R3, R12, QQQQ0, QQQQ2, QQQQ3, PC],
538      Uses = [SP] in {
539    def tTAILJMPdND : tPseudoExpand<(outs),
540                   (ins t_brtarget:$dst, pred:$p, variable_ops),
541                   4, IIC_Br, [],
542                   (tB t_brtarget:$dst, pred:$p)>,
543                 Requires<[IsThumb, IsNotDarwin]>;
544    def tTAILJMPrND : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
545                     4, IIC_Br, [],
546                     (tBX GPR:$dst, (ops 14, zero_reg))>,
547                     Requires<[IsThumb, IsNotDarwin]>;
548  }
549}
550
551
552// A8.6.218 Supervisor Call (Software Interrupt)
553// A8.6.16 B: Encoding T1
554// If Inst{11-8} == 0b1111 then SEE SVC
555let isCall = 1, Uses = [SP] in
556def tSVC : T1pI<(outs), (ins imm0_255:$imm), IIC_Br,
557                "svc", "\t$imm", []>, Encoding16 {
558  bits<8> imm;
559  let Inst{15-12} = 0b1101;
560  let Inst{11-8}  = 0b1111;
561  let Inst{7-0}   = imm;
562}
563
564// The assembler uses 0xDEFE for a trap instruction.
565let isBarrier = 1, isTerminator = 1 in
566def tTRAP : TI<(outs), (ins), IIC_Br,
567               "trap", [(trap)]>, Encoding16 {
568  let Inst = 0xdefe;
569}
570
571//===----------------------------------------------------------------------===//
572//  Load Store Instructions.
573//
574
575// Loads: reg/reg and reg/imm5
576let canFoldAsLoad = 1, isReMaterializable = 1 in
577multiclass thumb_ld_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
578                              Operand AddrMode_r, Operand AddrMode_i,
579                              AddrMode am, InstrItinClass itin_r,
580                              InstrItinClass itin_i, string asm,
581                              PatFrag opnode> {
582  def r : // reg/reg
583    T1pILdStEncode<reg_opc,
584                   (outs tGPR:$Rt), (ins AddrMode_r:$addr),
585                   am, itin_r, asm, "\t$Rt, $addr",
586                   [(set tGPR:$Rt, (opnode AddrMode_r:$addr))]>;
587  def i : // reg/imm5
588    T1pILdStEncodeImm<imm_opc, 1 /* Load */,
589                      (outs tGPR:$Rt), (ins AddrMode_i:$addr),
590                      am, itin_i, asm, "\t$Rt, $addr",
591                      [(set tGPR:$Rt, (opnode AddrMode_i:$addr))]>;
592}
593// Stores: reg/reg and reg/imm5
594multiclass thumb_st_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
595                              Operand AddrMode_r, Operand AddrMode_i,
596                              AddrMode am, InstrItinClass itin_r,
597                              InstrItinClass itin_i, string asm,
598                              PatFrag opnode> {
599  def r : // reg/reg
600    T1pILdStEncode<reg_opc,
601                   (outs), (ins tGPR:$Rt, AddrMode_r:$addr),
602                   am, itin_r, asm, "\t$Rt, $addr",
603                   [(opnode tGPR:$Rt, AddrMode_r:$addr)]>;
604  def i : // reg/imm5
605    T1pILdStEncodeImm<imm_opc, 0 /* Store */,
606                      (outs), (ins tGPR:$Rt, AddrMode_i:$addr),
607                      am, itin_i, asm, "\t$Rt, $addr",
608                      [(opnode tGPR:$Rt, AddrMode_i:$addr)]>;
609}
610
611// A8.6.57 & A8.6.60
612defm tLDR  : thumb_ld_rr_ri_enc<0b100, 0b0110, t_addrmode_rrs4,
613                                t_addrmode_is4, AddrModeT1_4,
614                                IIC_iLoad_r, IIC_iLoad_i, "ldr",
615                                UnOpFrag<(load node:$Src)>>;
616
617// A8.6.64 & A8.6.61
618defm tLDRB : thumb_ld_rr_ri_enc<0b110, 0b0111, t_addrmode_rrs1,
619                                t_addrmode_is1, AddrModeT1_1,
620                                IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrb",
621                                UnOpFrag<(zextloadi8 node:$Src)>>;
622
623// A8.6.76 & A8.6.73
624defm tLDRH : thumb_ld_rr_ri_enc<0b101, 0b1000, t_addrmode_rrs2,
625                                t_addrmode_is2, AddrModeT1_2,
626                                IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrh",
627                                UnOpFrag<(zextloadi16 node:$Src)>>;
628
629let AddedComplexity = 10 in
630def tLDRSB :                    // A8.6.80
631  T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
632                 AddrModeT1_1, IIC_iLoad_bh_r,
633                 "ldrsb", "\t$Rt, $addr",
634                 [(set tGPR:$Rt, (sextloadi8 t_addrmode_rr:$addr))]>;
635
636let AddedComplexity = 10 in
637def tLDRSH :                    // A8.6.84
638  T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
639                 AddrModeT1_2, IIC_iLoad_bh_r,
640                 "ldrsh", "\t$Rt, $addr",
641                 [(set tGPR:$Rt, (sextloadi16 t_addrmode_rr:$addr))]>;
642
643let canFoldAsLoad = 1 in
644def tLDRspi : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
645                    "ldr", "\t$Rt, $addr",
646                    [(set tGPR:$Rt, (load t_addrmode_sp:$addr))]>,
647              T1LdStSP<{1,?,?}> {
648  bits<3> Rt;
649  bits<8> addr;
650  let Inst{10-8} = Rt;
651  let Inst{7-0} = addr;
652}
653
654// Load tconstpool
655// FIXME: Use ldr.n to work around a Darwin assembler bug.
656let canFoldAsLoad = 1, isReMaterializable = 1, isCodeGenOnly = 1 in
657def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i,
658                  "ldr", ".n\t$Rt, $addr",
659                  [(set tGPR:$Rt, (load (ARMWrapper tconstpool:$addr)))]>,
660              T1Encoding<{0,1,0,0,1,?}> {
661  // A6.2 & A8.6.59
662  bits<3> Rt;
663  bits<8> addr;
664  let Inst{10-8} = Rt;
665  let Inst{7-0}  = addr;
666}
667
668// FIXME: Remove this entry when the above ldr.n workaround is fixed.
669// For disassembly use only.
670def tLDRpciDIS : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i,
671                       "ldr", "\t$Rt, $addr",
672                       [/* disassembly only */]>,
673                 T1Encoding<{0,1,0,0,1,?}> {
674  // A6.2 & A8.6.59
675  bits<3> Rt;
676  bits<8> addr;
677  let Inst{10-8} = Rt;
678  let Inst{7-0}  = addr;
679}
680
681// A8.6.194 & A8.6.192
682defm tSTR  : thumb_st_rr_ri_enc<0b000, 0b0110, t_addrmode_rrs4,
683                                t_addrmode_is4, AddrModeT1_4,
684                                IIC_iStore_r, IIC_iStore_i, "str",
685                                BinOpFrag<(store node:$LHS, node:$RHS)>>;
686
687// A8.6.197 & A8.6.195
688defm tSTRB : thumb_st_rr_ri_enc<0b010, 0b0111, t_addrmode_rrs1,
689                                t_addrmode_is1, AddrModeT1_1,
690                                IIC_iStore_bh_r, IIC_iStore_bh_i, "strb",
691                                BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
692
693// A8.6.207 & A8.6.205
694defm tSTRH : thumb_st_rr_ri_enc<0b001, 0b1000, t_addrmode_rrs2,
695                               t_addrmode_is2, AddrModeT1_2,
696                               IIC_iStore_bh_r, IIC_iStore_bh_i, "strh",
697                               BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
698
699
700def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
701                    "str", "\t$Rt, $addr",
702                    [(store tGPR:$Rt, t_addrmode_sp:$addr)]>,
703              T1LdStSP<{0,?,?}> {
704  bits<3> Rt;
705  bits<8> addr;
706  let Inst{10-8} = Rt;
707  let Inst{7-0} = addr;
708}
709
710//===----------------------------------------------------------------------===//
711//  Load / store multiple Instructions.
712//
713
714// These require base address to be written back or one of the loaded regs.
715let neverHasSideEffects = 1 in {
716
717let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
718def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
719        IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
720  bits<3> Rn;
721  bits<8> regs;
722  let Inst{10-8} = Rn;
723  let Inst{7-0}  = regs;
724}
725
726// Writeback version is just a pseudo, as there's no encoding difference.
727// Writeback happens iff the base register is not in the destination register
728// list.
729def tLDMIA_UPD :
730    InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
731                 "$Rn = $wb", IIC_iLoad_mu>,
732    PseudoInstExpansion<(tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)> {
733  let Size = 2;
734  let OutOperandList = (outs GPR:$wb);
735  let InOperandList = (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops);
736  let Pattern = [];
737  let isCodeGenOnly = 1;
738  let isPseudo = 1;
739  list<Predicate> Predicates = [IsThumb];
740}
741
742// There is no non-writeback version of STM for Thumb.
743let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
744def tSTMIA_UPD : Thumb1I<(outs GPR:$wb),
745                         (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
746                         AddrModeNone, 2, IIC_iStore_mu,
747                         "stm${p}\t$Rn!, $regs", "$Rn = $wb", []>,
748                     T1Encoding<{1,1,0,0,0,?}> {
749  bits<3> Rn;
750  bits<8> regs;
751  let Inst{10-8} = Rn;
752  let Inst{7-0}  = regs;
753}
754
755} // neverHasSideEffects
756
757def : InstAlias<"ldm${p} $Rn!, $regs",
758                (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)>,
759        Requires<[IsThumb, IsThumb1Only]>;
760
761let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
762def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
763               IIC_iPop,
764               "pop${p}\t$regs", []>,
765           T1Misc<{1,1,0,?,?,?,?}> {
766  bits<16> regs;
767  let Inst{8}   = regs{15};
768  let Inst{7-0} = regs{7-0};
769}
770
771let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
772def tPUSH : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
773                IIC_iStore_m,
774                "push${p}\t$regs", []>,
775            T1Misc<{0,1,0,?,?,?,?}> {
776  bits<16> regs;
777  let Inst{8}   = regs{14};
778  let Inst{7-0} = regs{7-0};
779}
780
781//===----------------------------------------------------------------------===//
782//  Arithmetic Instructions.
783//
784
785// Helper classes for encoding T1pI patterns:
786class T1pIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
787                   string opc, string asm, list<dag> pattern>
788    : T1pI<oops, iops, itin, opc, asm, pattern>,
789      T1DataProcessing<opA> {
790  bits<3> Rm;
791  bits<3> Rn;
792  let Inst{5-3} = Rm;
793  let Inst{2-0} = Rn;
794}
795class T1pIMiscEncode<bits<7> opA, dag oops, dag iops, InstrItinClass itin,
796                     string opc, string asm, list<dag> pattern>
797    : T1pI<oops, iops, itin, opc, asm, pattern>,
798      T1Misc<opA> {
799  bits<3> Rm;
800  bits<3> Rd;
801  let Inst{5-3} = Rm;
802  let Inst{2-0} = Rd;
803}
804
805// Helper classes for encoding T1sI patterns:
806class T1sIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
807                   string opc, string asm, list<dag> pattern>
808    : T1sI<oops, iops, itin, opc, asm, pattern>,
809      T1DataProcessing<opA> {
810  bits<3> Rd;
811  bits<3> Rn;
812  let Inst{5-3} = Rn;
813  let Inst{2-0} = Rd;
814}
815class T1sIGenEncode<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
816                    string opc, string asm, list<dag> pattern>
817    : T1sI<oops, iops, itin, opc, asm, pattern>,
818      T1General<opA> {
819  bits<3> Rm;
820  bits<3> Rn;
821  bits<3> Rd;
822  let Inst{8-6} = Rm;
823  let Inst{5-3} = Rn;
824  let Inst{2-0} = Rd;
825}
826class T1sIGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
827                       string opc, string asm, list<dag> pattern>
828    : T1sI<oops, iops, itin, opc, asm, pattern>,
829      T1General<opA> {
830  bits<3> Rd;
831  bits<3> Rm;
832  let Inst{5-3} = Rm;
833  let Inst{2-0} = Rd;
834}
835
836// Helper classes for encoding T1sIt patterns:
837class T1sItDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
838                    string opc, string asm, list<dag> pattern>
839    : T1sIt<oops, iops, itin, opc, asm, pattern>,
840      T1DataProcessing<opA> {
841  bits<3> Rdn;
842  bits<3> Rm;
843  let Inst{5-3} = Rm;
844  let Inst{2-0} = Rdn;
845}
846class T1sItGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
847                        string opc, string asm, list<dag> pattern>
848    : T1sIt<oops, iops, itin, opc, asm, pattern>,
849      T1General<opA> {
850  bits<3> Rdn;
851  bits<8> imm8;
852  let Inst{10-8} = Rdn;
853  let Inst{7-0}  = imm8;
854}
855
856// Add with carry register
857let isCommutable = 1, Uses = [CPSR] in
858def tADC :                      // A8.6.2
859  T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
860                "adc", "\t$Rdn, $Rm",
861                [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>;
862
863// Add immediate
864def tADDi3 :                    // A8.6.4 T1
865  T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
866                   IIC_iALUi,
867                   "add", "\t$Rd, $Rm, $imm3",
868                   [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]> {
869  bits<3> imm3;
870  let Inst{8-6} = imm3;
871}
872
873def tADDi8 :                    // A8.6.4 T2
874  T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
875                    (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
876                    "add", "\t$Rdn, $imm8",
877                    [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>;
878
879// Add register
880let isCommutable = 1 in
881def tADDrr :                    // A8.6.6 T1
882  T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
883                IIC_iALUr,
884                "add", "\t$Rd, $Rn, $Rm",
885                [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>;
886
887let neverHasSideEffects = 1 in
888def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
889                     "add", "\t$Rdn, $Rm", []>,
890               T1Special<{0,0,?,?}> {
891  // A8.6.6 T2
892  bits<4> Rdn;
893  bits<4> Rm;
894  let Inst{7}   = Rdn{3};
895  let Inst{6-3} = Rm;
896  let Inst{2-0} = Rdn{2-0};
897}
898
899// AND register
900let isCommutable = 1 in
901def tAND :                      // A8.6.12
902  T1sItDPEncode<0b0000, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
903                IIC_iBITr,
904                "and", "\t$Rdn, $Rm",
905                [(set tGPR:$Rdn, (and tGPR:$Rn, tGPR:$Rm))]>;
906
907// ASR immediate
908def tASRri :                    // A8.6.14
909  T1sIGenEncodeImm<{0,1,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
910                   IIC_iMOVsi,
911                   "asr", "\t$Rd, $Rm, $imm5",
912                   [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm_sr:$imm5)))]> {
913  bits<5> imm5;
914  let Inst{10-6} = imm5;
915}
916
917// ASR register
918def tASRrr :                    // A8.6.15
919  T1sItDPEncode<0b0100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
920                IIC_iMOVsr,
921                "asr", "\t$Rdn, $Rm",
922                [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>;
923
924// BIC register
925def tBIC :                      // A8.6.20
926  T1sItDPEncode<0b1110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
927                IIC_iBITr,
928                "bic", "\t$Rdn, $Rm",
929                [(set tGPR:$Rdn, (and tGPR:$Rn, (not tGPR:$Rm)))]>;
930
931// CMN register
932let isCompare = 1, Defs = [CPSR] in {
933//FIXME: Disable CMN, as CCodes are backwards from compare expectations
934//       Compare-to-zero still works out, just not the relationals
935//def tCMN :                     // A8.6.33
936//  T1pIDPEncode<0b1011, (outs), (ins tGPR:$lhs, tGPR:$rhs),
937//               IIC_iCMPr,
938//               "cmn", "\t$lhs, $rhs",
939//               [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
940
941def tCMNz :                     // A8.6.33
942  T1pIDPEncode<0b1011, (outs), (ins tGPR:$Rn, tGPR:$Rm),
943               IIC_iCMPr,
944               "cmn", "\t$Rn, $Rm",
945               [(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm))]>;
946
947} // isCompare = 1, Defs = [CPSR]
948
949// CMP immediate
950let isCompare = 1, Defs = [CPSR] in {
951def tCMPi8 : T1pI<(outs), (ins tGPR:$Rn, imm0_255:$imm8), IIC_iCMPi,
952                  "cmp", "\t$Rn, $imm8",
953                  [(ARMcmp tGPR:$Rn, imm0_255:$imm8)]>,
954             T1General<{1,0,1,?,?}> {
955  // A8.6.35
956  bits<3> Rn;
957  bits<8> imm8;
958  let Inst{10-8} = Rn;
959  let Inst{7-0}  = imm8;
960}
961
962// CMP register
963def tCMPr :                     // A8.6.36 T1
964  T1pIDPEncode<0b1010, (outs), (ins tGPR:$Rn, tGPR:$Rm),
965               IIC_iCMPr,
966               "cmp", "\t$Rn, $Rm",
967               [(ARMcmp tGPR:$Rn, tGPR:$Rm)]>;
968
969def tCMPhir : T1pI<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_iCMPr,
970                   "cmp", "\t$Rn, $Rm", []>,
971              T1Special<{0,1,?,?}> {
972  // A8.6.36 T2
973  bits<4> Rm;
974  bits<4> Rn;
975  let Inst{7}   = Rn{3};
976  let Inst{6-3} = Rm;
977  let Inst{2-0} = Rn{2-0};
978}
979} // isCompare = 1, Defs = [CPSR]
980
981
982// XOR register
983let isCommutable = 1 in
984def tEOR :                      // A8.6.45
985  T1sItDPEncode<0b0001, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
986                IIC_iBITr,
987                "eor", "\t$Rdn, $Rm",
988                [(set tGPR:$Rdn, (xor tGPR:$Rn, tGPR:$Rm))]>;
989
990// LSL immediate
991def tLSLri :                    // A8.6.88
992  T1sIGenEncodeImm<{0,0,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_31:$imm5),
993                   IIC_iMOVsi,
994                   "lsl", "\t$Rd, $Rm, $imm5",
995                   [(set tGPR:$Rd, (shl tGPR:$Rm, (i32 imm:$imm5)))]> {
996  bits<5> imm5;
997  let Inst{10-6} = imm5;
998}
999
1000// LSL register
1001def tLSLrr :                    // A8.6.89
1002  T1sItDPEncode<0b0010, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1003                IIC_iMOVsr,
1004                "lsl", "\t$Rdn, $Rm",
1005                [(set tGPR:$Rdn, (shl tGPR:$Rn, tGPR:$Rm))]>;
1006
1007// LSR immediate
1008def tLSRri :                    // A8.6.90
1009  T1sIGenEncodeImm<{0,0,1,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
1010                   IIC_iMOVsi,
1011                   "lsr", "\t$Rd, $Rm, $imm5",
1012                   [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm_sr:$imm5)))]> {
1013  bits<5> imm5;
1014  let Inst{10-6} = imm5;
1015}
1016
1017// LSR register
1018def tLSRrr :                    // A8.6.91
1019  T1sItDPEncode<0b0011, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1020                IIC_iMOVsr,
1021                "lsr", "\t$Rdn, $Rm",
1022                [(set tGPR:$Rdn, (srl tGPR:$Rn, tGPR:$Rm))]>;
1023
1024// Move register
1025let isMoveImm = 1 in
1026def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi,
1027                  "mov", "\t$Rd, $imm8",
1028                  [(set tGPR:$Rd, imm0_255:$imm8)]>,
1029             T1General<{1,0,0,?,?}> {
1030  // A8.6.96
1031  bits<3> Rd;
1032  bits<8> imm8;
1033  let Inst{10-8} = Rd;
1034  let Inst{7-0}  = imm8;
1035}
1036// Because we have an explicit tMOVSr below, we need an alias to handle
1037// the immediate "movs" form here. Blech.
1038def : tInstAlias <"movs $Rdn, $imm",
1039                 (tMOVi8 tGPR:$Rdn, CPSR, imm0_255:$imm, 14, 0)>;
1040
1041// A7-73: MOV(2) - mov setting flag.
1042
1043let neverHasSideEffects = 1 in {
1044def tMOVr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone,
1045                      2, IIC_iMOVr,
1046                      "mov", "\t$Rd, $Rm", "", []>,
1047                  T1Special<{1,0,?,?}> {
1048  // A8.6.97
1049  bits<4> Rd;
1050  bits<4> Rm;
1051  let Inst{7}   = Rd{3};
1052  let Inst{6-3} = Rm;
1053  let Inst{2-0} = Rd{2-0};
1054}
1055let Defs = [CPSR] in
1056def tMOVSr      : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
1057                      "movs\t$Rd, $Rm", []>, Encoding16 {
1058  // A8.6.97
1059  bits<3> Rd;
1060  bits<3> Rm;
1061  let Inst{15-6} = 0b0000000000;
1062  let Inst{5-3}  = Rm;
1063  let Inst{2-0}  = Rd;
1064}
1065} // neverHasSideEffects
1066
1067// Multiply register
1068let isCommutable = 1 in
1069def tMUL :                      // A8.6.105 T1
1070  Thumb1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), AddrModeNone, 2,
1071           IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", "$Rm = $Rd",
1072           [(set tGPR:$Rd, (mul tGPR:$Rn, tGPR:$Rm))]>,
1073      T1DataProcessing<0b1101> {
1074  bits<3> Rd;
1075  bits<3> Rn;
1076  let Inst{5-3} = Rn;
1077  let Inst{2-0} = Rd;
1078  let AsmMatchConverter = "cvtThumbMultiply";
1079}
1080
1081def :tInstAlias<"mul${s}${p} $Rdm, $Rn", (tMUL tGPR:$Rdm, s_cc_out:$s, tGPR:$Rn,
1082                                               pred:$p)>;
1083
1084// Move inverse register
1085def tMVN :                      // A8.6.107
1086  T1sIDPEncode<0b1111, (outs tGPR:$Rd), (ins tGPR:$Rn), IIC_iMVNr,
1087               "mvn", "\t$Rd, $Rn",
1088               [(set tGPR:$Rd, (not tGPR:$Rn))]>;
1089
1090// Bitwise or register
1091let isCommutable = 1 in
1092def tORR :                      // A8.6.114
1093  T1sItDPEncode<0b1100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1094                IIC_iBITr,
1095                "orr", "\t$Rdn, $Rm",
1096                [(set tGPR:$Rdn, (or tGPR:$Rn, tGPR:$Rm))]>;
1097
1098// Swaps
1099def tREV :                      // A8.6.134
1100  T1pIMiscEncode<{1,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1101                 IIC_iUNAr,
1102                 "rev", "\t$Rd, $Rm",
1103                 [(set tGPR:$Rd, (bswap tGPR:$Rm))]>,
1104                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1105
1106def tREV16 :                    // A8.6.135
1107  T1pIMiscEncode<{1,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1108                 IIC_iUNAr,
1109                 "rev16", "\t$Rd, $Rm",
1110             [(set tGPR:$Rd, (rotr (bswap tGPR:$Rm), (i32 16)))]>,
1111                Requires<[IsThumb, IsThumb1Only, HasV6]>;
1112
1113def tREVSH :                    // A8.6.136
1114  T1pIMiscEncode<{1,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1115                 IIC_iUNAr,
1116                 "revsh", "\t$Rd, $Rm",
1117                 [(set tGPR:$Rd, (sra (bswap tGPR:$Rm), (i32 16)))]>,
1118                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1119
1120// Rotate right register
1121def tROR :                      // A8.6.139
1122  T1sItDPEncode<0b0111, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1123                IIC_iMOVsr,
1124                "ror", "\t$Rdn, $Rm",
1125                [(set tGPR:$Rdn, (rotr tGPR:$Rn, tGPR:$Rm))]>;
1126
1127// Negate register
1128def tRSB :                      // A8.6.141
1129  T1sIDPEncode<0b1001, (outs tGPR:$Rd), (ins tGPR:$Rn),
1130               IIC_iALUi,
1131               "rsb", "\t$Rd, $Rn, #0",
1132               [(set tGPR:$Rd, (ineg tGPR:$Rn))]>;
1133
1134def : tInstAlias<"neg${s}${p} $Rd, $Rm",
1135                 (tRSB tGPR:$Rd, s_cc_out:$s, tGPR:$Rm, pred:$p)>;
1136
1137// Subtract with carry register
1138let Uses = [CPSR] in
1139def tSBC :                      // A8.6.151
1140  T1sItDPEncode<0b0110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
1141                IIC_iALUr,
1142                "sbc", "\t$Rdn, $Rm",
1143                [(set tGPR:$Rdn, (sube tGPR:$Rn, tGPR:$Rm))]>;
1144
1145// Subtract immediate
1146def tSUBi3 :                    // A8.6.210 T1
1147  T1sIGenEncodeImm<0b01111, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
1148                   IIC_iALUi,
1149                   "sub", "\t$Rd, $Rm, $imm3",
1150                   [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7_neg:$imm3))]> {
1151  bits<3> imm3;
1152  let Inst{8-6} = imm3;
1153}
1154
1155def tSUBi8 :                    // A8.6.210 T2
1156  T1sItGenEncodeImm<{1,1,1,?,?}, (outs tGPR:$Rdn),
1157                    (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
1158                    "sub", "\t$Rdn, $imm8",
1159                    [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255_neg:$imm8))]>;
1160
1161// Subtract register
1162def tSUBrr :                    // A8.6.212
1163  T1sIGenEncode<0b01101, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
1164                IIC_iALUr,
1165                "sub", "\t$Rd, $Rn, $Rm",
1166                [(set tGPR:$Rd, (sub tGPR:$Rn, tGPR:$Rm))]>;
1167
1168// Sign-extend byte
1169def tSXTB :                     // A8.6.222
1170  T1pIMiscEncode<{0,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1171                 IIC_iUNAr,
1172                 "sxtb", "\t$Rd, $Rm",
1173                 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i8))]>,
1174                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1175
1176// Sign-extend short
1177def tSXTH :                     // A8.6.224
1178  T1pIMiscEncode<{0,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1179                 IIC_iUNAr,
1180                 "sxth", "\t$Rd, $Rm",
1181                 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i16))]>,
1182                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1183
1184// Test
1185let isCompare = 1, isCommutable = 1, Defs = [CPSR] in
1186def tTST :                      // A8.6.230
1187  T1pIDPEncode<0b1000, (outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iTSTr,
1188               "tst", "\t$Rn, $Rm",
1189               [(ARMcmpZ (and_su tGPR:$Rn, tGPR:$Rm), 0)]>;
1190
1191// Zero-extend byte
1192def tUXTB :                     // A8.6.262
1193  T1pIMiscEncode<{0,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1194                 IIC_iUNAr,
1195                 "uxtb", "\t$Rd, $Rm",
1196                 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFF))]>,
1197                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1198
1199// Zero-extend short
1200def tUXTH :                     // A8.6.264
1201  T1pIMiscEncode<{0,0,1,0,1,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
1202                 IIC_iUNAr,
1203                 "uxth", "\t$Rd, $Rm",
1204                 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFFFF))]>,
1205                 Requires<[IsThumb, IsThumb1Only, HasV6]>;
1206
1207// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation.
1208// Expanded after instruction selection into a branch sequence.
1209let usesCustomInserter = 1 in  // Expanded after instruction selection.
1210  def tMOVCCr_pseudo :
1211  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
1212              NoItinerary,
1213             [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
1214
1215// tLEApcrel - Load a pc-relative address into a register without offending the
1216// assembler.
1217
1218def tADR : T1I<(outs tGPR:$Rd), (ins t_adrlabel:$addr, pred:$p),
1219               IIC_iALUi, "adr{$p}\t$Rd, $addr", []>,
1220               T1Encoding<{1,0,1,0,0,?}> {
1221  bits<3> Rd;
1222  bits<8> addr;
1223  let Inst{10-8} = Rd;
1224  let Inst{7-0} = addr;
1225  let DecoderMethod = "DecodeThumbAddSpecialReg";
1226}
1227
1228let neverHasSideEffects = 1, isReMaterializable = 1 in
1229def tLEApcrel   : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p),
1230                              2, IIC_iALUi, []>;
1231
1232def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd),
1233                              (ins i32imm:$label, nohash_imm:$id, pred:$p),
1234                              2, IIC_iALUi, []>;
1235
1236//===----------------------------------------------------------------------===//
1237// TLS Instructions
1238//
1239
1240// __aeabi_read_tp preserves the registers r1-r3.
1241// This is a pseudo inst so that we can get the encoding right,
1242// complete with fixup for the aeabi_read_tp function.
1243let isCall = 1, Defs = [R0, R12, LR, CPSR], Uses = [SP] in
1244def tTPsoft : tPseudoInst<(outs), (ins), 4, IIC_Br,
1245                          [(set R0, ARMthread_pointer)]>;
1246
1247//===----------------------------------------------------------------------===//
1248// SJLJ Exception handling intrinsics
1249//
1250
1251// eh_sjlj_setjmp() is an instruction sequence to store the return address and
1252// save #0 in R0 for the non-longjmp case.  Since by its nature we may be coming
1253// from some other function to get here, and we're using the stack frame for the
1254// containing function to save/restore registers, we can't keep anything live in
1255// regs across the eh_sjlj_setjmp(), else it will almost certainly have been
1256// tromped upon when we get here from a longjmp(). We force everything out of
1257// registers except for our own input by listing the relevant registers in
1258// Defs. By doing so, we also cause the prologue/epilogue code to actively
1259// preserve all of the callee-saved resgisters, which is exactly what we want.
1260// $val is a scratch register for our use.
1261let Defs = [ R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7, R12, CPSR ],
1262    hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in
1263def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
1264                                  AddrModeNone, 0, NoItinerary, "","",
1265                          [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
1266
1267// FIXME: Non-Darwin version(s)
1268let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
1269    Defs = [ R7, LR, SP ] in
1270def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
1271                              AddrModeNone, 0, IndexModeNone,
1272                              Pseudo, NoItinerary, "", "",
1273                              [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
1274                             Requires<[IsThumb, IsDarwin]>;
1275
1276//===----------------------------------------------------------------------===//
1277// Non-Instruction Patterns
1278//
1279
1280// Comparisons
1281def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
1282            (tCMPi8  tGPR:$Rn, imm0_255:$imm8)>;
1283def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
1284            (tCMPr   tGPR:$Rn, tGPR:$Rm)>;
1285
1286// Add with carry
1287def : T1Pat<(addc   tGPR:$lhs, imm0_7:$rhs),
1288            (tADDi3 tGPR:$lhs, imm0_7:$rhs)>;
1289def : T1Pat<(addc   tGPR:$lhs, imm8_255:$rhs),
1290            (tADDi8 tGPR:$lhs, imm8_255:$rhs)>;
1291def : T1Pat<(addc   tGPR:$lhs, tGPR:$rhs),
1292            (tADDrr tGPR:$lhs, tGPR:$rhs)>;
1293
1294// Subtract with carry
1295def : T1Pat<(addc   tGPR:$lhs, imm0_7_neg:$rhs),
1296            (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>;
1297def : T1Pat<(addc   tGPR:$lhs, imm8_255_neg:$rhs),
1298            (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>;
1299def : T1Pat<(subc   tGPR:$lhs, tGPR:$rhs),
1300            (tSUBrr tGPR:$lhs, tGPR:$rhs)>;
1301
1302// ConstantPool, GlobalAddress
1303def : T1Pat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
1304def : T1Pat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
1305
1306// JumpTable
1307def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1308            (tLEApcrelJT tjumptable:$dst, imm:$id)>;
1309
1310// Direct calls
1311def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>,
1312      Requires<[IsThumb, IsNotDarwin]>;
1313def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>,
1314      Requires<[IsThumb, IsDarwin]>;
1315
1316def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>,
1317      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
1318def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>,
1319      Requires<[IsThumb, HasV5T, IsDarwin]>;
1320
1321// Indirect calls to ARM routines
1322def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>,
1323      Requires<[IsThumb, HasV5T, IsNotDarwin]>;
1324def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>,
1325      Requires<[IsThumb, HasV5T, IsDarwin]>;
1326
1327// zextload i1 -> zextload i8
1328def : T1Pat<(zextloadi1 t_addrmode_rrs1:$addr),
1329            (tLDRBr t_addrmode_rrs1:$addr)>;
1330def : T1Pat<(zextloadi1 t_addrmode_is1:$addr),
1331            (tLDRBi t_addrmode_is1:$addr)>;
1332
1333// extload -> zextload
1334def : T1Pat<(extloadi1  t_addrmode_rrs1:$addr), (tLDRBr t_addrmode_rrs1:$addr)>;
1335def : T1Pat<(extloadi1  t_addrmode_is1:$addr),  (tLDRBi t_addrmode_is1:$addr)>;
1336def : T1Pat<(extloadi8  t_addrmode_rrs1:$addr), (tLDRBr t_addrmode_rrs1:$addr)>;
1337def : T1Pat<(extloadi8  t_addrmode_is1:$addr),  (tLDRBi t_addrmode_is1:$addr)>;
1338def : T1Pat<(extloadi16 t_addrmode_rrs2:$addr), (tLDRHr t_addrmode_rrs2:$addr)>;
1339def : T1Pat<(extloadi16 t_addrmode_is2:$addr),  (tLDRHi t_addrmode_is2:$addr)>;
1340
1341// If it's impossible to use [r,r] address mode for sextload, select to
1342// ldr{b|h} + sxt{b|h} instead.
1343def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
1344            (tSXTB (tLDRBi t_addrmode_is1:$addr))>,
1345      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1346def : T1Pat<(sextloadi8 t_addrmode_rrs1:$addr),
1347            (tSXTB (tLDRBr t_addrmode_rrs1:$addr))>,
1348      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1349def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
1350            (tSXTH (tLDRHi t_addrmode_is2:$addr))>,
1351      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1352def : T1Pat<(sextloadi16 t_addrmode_rrs2:$addr),
1353            (tSXTH (tLDRHr t_addrmode_rrs2:$addr))>,
1354      Requires<[IsThumb, IsThumb1Only, HasV6]>;
1355
1356def : T1Pat<(sextloadi8 t_addrmode_rrs1:$addr),
1357            (tASRri (tLSLri (tLDRBr t_addrmode_rrs1:$addr), 24), 24)>;
1358def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
1359            (tASRri (tLSLri (tLDRBi t_addrmode_is1:$addr), 24), 24)>;
1360def : T1Pat<(sextloadi16 t_addrmode_rrs2:$addr),
1361            (tASRri (tLSLri (tLDRHr t_addrmode_rrs2:$addr), 16), 16)>;
1362def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
1363            (tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>;
1364
1365def : T1Pat<(atomic_load_8 t_addrmode_is1:$src),
1366             (tLDRBi t_addrmode_is1:$src)>;
1367def : T1Pat<(atomic_load_8 t_addrmode_rrs1:$src),
1368             (tLDRBr t_addrmode_rrs1:$src)>;
1369def : T1Pat<(atomic_load_16 t_addrmode_is2:$src),
1370             (tLDRHi t_addrmode_is2:$src)>;
1371def : T1Pat<(atomic_load_16 t_addrmode_rrs2:$src),
1372             (tLDRHr t_addrmode_rrs2:$src)>;
1373def : T1Pat<(atomic_load_32 t_addrmode_is4:$src),
1374             (tLDRi t_addrmode_is4:$src)>;
1375def : T1Pat<(atomic_load_32 t_addrmode_rrs4:$src),
1376             (tLDRr t_addrmode_rrs4:$src)>;
1377def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val),
1378             (tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>;
1379def : T1Pat<(atomic_store_8 t_addrmode_rrs1:$ptr, tGPR:$val),
1380             (tSTRBr tGPR:$val, t_addrmode_rrs1:$ptr)>;
1381def : T1Pat<(atomic_store_16 t_addrmode_is2:$ptr, tGPR:$val),
1382             (tSTRHi tGPR:$val, t_addrmode_is2:$ptr)>;
1383def : T1Pat<(atomic_store_16 t_addrmode_rrs2:$ptr, tGPR:$val),
1384             (tSTRHr tGPR:$val, t_addrmode_rrs2:$ptr)>;
1385def : T1Pat<(atomic_store_32 t_addrmode_is4:$ptr, tGPR:$val),
1386             (tSTRi tGPR:$val, t_addrmode_is4:$ptr)>;
1387def : T1Pat<(atomic_store_32 t_addrmode_rrs4:$ptr, tGPR:$val),
1388             (tSTRr tGPR:$val, t_addrmode_rrs4:$ptr)>;
1389
1390// Large immediate handling.
1391
1392// Two piece imms.
1393def : T1Pat<(i32 thumb_immshifted:$src),
1394            (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
1395                    (thumb_immshifted_shamt imm:$src))>;
1396
1397def : T1Pat<(i32 imm0_255_comp:$src),
1398            (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>;
1399
1400// Pseudo instruction that combines ldr from constpool and add pc. This should
1401// be expanded into two instructions late to allow if-conversion and
1402// scheduling.
1403let isReMaterializable = 1 in
1404def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
1405                             NoItinerary,
1406               [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
1407                                           imm:$cp))]>,
1408               Requires<[IsThumb, IsThumb1Only]>;
1409
1410// Pseudo-instruction for merged POP and return.
1411// FIXME: remove when we have a way to marking a MI with these properties.
1412let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1413    hasExtraDefRegAllocReq = 1 in
1414def tPOP_RET : tPseudoExpand<(outs), (ins pred:$p, reglist:$regs, variable_ops),
1415                           2, IIC_iPop_Br, [],
1416                           (tPOP pred:$p, reglist:$regs)>;
1417
1418// Indirect branch using "mov pc, $Rm"
1419let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
1420  def tBRIND : tPseudoExpand<(outs), (ins GPR:$Rm, pred:$p),
1421                  2, IIC_Br, [(brind GPR:$Rm)],
1422                  (tMOVr PC, GPR:$Rm, pred:$p)>;
1423}
1424
1425
1426// In Thumb1, "nop" is encoded as a "mov r8, r8". Technically, the bf00
1427// encoding is available on ARMv6K, but we don't differentiate that finely.
1428def : InstAlias<"nop", (tMOVr R8, R8, 14, 0)>,Requires<[IsThumb, IsThumb1Only]>;
1429
1430
1431// For round-trip assembly/disassembly, we have to handle a CPS instruction
1432// without any iflags. That's not, strictly speaking, valid syntax, but it's
1433// a useful extention and assembles to defined behaviour (the insn does
1434// nothing).
1435def : tInstAlias<"cps$imod", (tCPS imod_op:$imod, 0)>;
1436def : tInstAlias<"cps$imod", (tCPS imod_op:$imod, 0)>;
1437