blob: fc21982e811701e07d43ed0e7d6808a02ffd6b29 [file] [log] [blame]
Anton Korobeynikovd4022c32009-05-29 23:41:08 +00001//===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the Thumb2 instruction set.
11//
12//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +000013
14// Shifted operands. No register controlled shifts for Thumb2.
15// Note: We do not support rrx shifted operands yet.
16def t2_so_reg : Operand<i32>, // reg imm
Evan Cheng9cb9e672009-06-27 02:26:13 +000017 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
Anton Korobeynikov52237112009-06-17 18:13:58 +000018 [shl,srl,sra,rotr]> {
Evan Cheng9cb9e672009-06-27 02:26:13 +000019 let PrintMethod = "printT2SOOperand";
Anton Korobeynikov52237112009-06-17 18:13:58 +000020 let MIOperandInfo = (ops GPR, i32imm);
21}
22
Evan Chengf49810c2009-06-23 17:48:47 +000023// t2_so_imm_XFORM - Return a t2_so_imm value packed into the format
24// described for t2_so_imm def below.
25def t2_so_imm_XFORM : SDNodeXForm<imm, [{
26 return CurDAG->getTargetConstant(
27 ARM_AM::getT2SOImmVal(N->getZExtValue()), MVT::i32);
Anton Korobeynikov52237112009-06-17 18:13:58 +000028}]>;
29
Evan Chengf49810c2009-06-23 17:48:47 +000030// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
31def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
32 return CurDAG->getTargetConstant(
33 ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())), MVT::i32);
Anton Korobeynikov52237112009-06-17 18:13:58 +000034}]>;
35
Evan Chengf49810c2009-06-23 17:48:47 +000036// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
37def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
38 return CurDAG->getTargetConstant(
39 ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())), MVT::i32);
40}]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +000041
Evan Chengf49810c2009-06-23 17:48:47 +000042// t2_so_imm - Match a 32-bit immediate operand, which is an
43// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
44// immediate splatted into multiple bytes of the word. t2_so_imm values are
45// represented in the imm field in the same 12-bit form that they are encoded
46// into t2_so_imm instructions: the 8-bit immediate is the least significant bits
47// [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
48def t2_so_imm : Operand<i32>,
49 PatLeaf<(imm), [{
50 return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
51 }], t2_so_imm_XFORM> {
52 let PrintMethod = "printT2SOImmOperand";
53}
Anton Korobeynikov52237112009-06-17 18:13:58 +000054
Evan Chengf49810c2009-06-23 17:48:47 +000055// t2_so_imm_not - Match an immediate that is a complement
56// of a t2_so_imm.
57def t2_so_imm_not : Operand<i32>,
58 PatLeaf<(imm), [{
59 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
60 }], t2_so_imm_not_XFORM> {
61 let PrintMethod = "printT2SOImmOperand";
62}
63
64// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
65def t2_so_imm_neg : Operand<i32>,
66 PatLeaf<(imm), [{
67 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
68 }], t2_so_imm_neg_XFORM> {
69 let PrintMethod = "printT2SOImmOperand";
70}
71
Evan Chenga67efd12009-06-23 19:39:13 +000072/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
73def imm1_31 : PatLeaf<(i32 imm), [{
74 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
75}]>;
76
Evan Chengf49810c2009-06-23 17:48:47 +000077/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
78def imm0_4095 : PatLeaf<(i32 imm), [{
79 return (uint32_t)N->getZExtValue() < 4096;
80}]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +000081
82def imm0_4095_neg : PatLeaf<(i32 imm), [{
Evan Chengf49810c2009-06-23 17:48:47 +000083 return (uint32_t)(-N->getZExtValue()) < 4096;
Anton Korobeynikov52237112009-06-17 18:13:58 +000084}], imm_neg_XFORM>;
85
Evan Chengf49810c2009-06-23 17:48:47 +000086/// imm0_65535 predicate - True if the 32-bit immediate is in the range
87/// [0.65535].
88def imm0_65535 : PatLeaf<(i32 imm), [{
89 return (uint32_t)N->getZExtValue() < 65536;
Anton Korobeynikov52237112009-06-17 18:13:58 +000090}]>;
91
Evan Chengf49810c2009-06-23 17:48:47 +000092/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
93/// e.g., 0xf000ffff
94def bf_inv_mask_imm : Operand<i32>,
95 PatLeaf<(imm), [{
96 uint32_t v = (uint32_t)N->getZExtValue();
97 if (v == 0xffffffff)
98 return 0;
99 // naive checker. should do better, but simple is best for now since it's
100 // more likely to be correct.
101 while (v & 1) v >>= 1; // shift off the leading 1's
102 if (v)
103 {
104 while (!(v & 1)) v >>=1; // shift off the mask
105 while (v & 1) v >>= 1; // shift off the trailing 1's
106 }
107 // if this is a mask for clearing a bitfield, what's left should be zero.
108 return (v == 0);
109}] > {
110 let PrintMethod = "printBitfieldInvMaskImmOperand";
111}
112
113/// Split a 32-bit immediate into two 16 bit parts.
114def t2_lo16 : SDNodeXForm<imm, [{
115 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
116 MVT::i32);
117}]>;
118
119def t2_hi16 : SDNodeXForm<imm, [{
120 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
121}]>;
122
123def t2_lo16AllZero : PatLeaf<(i32 imm), [{
124 // Returns true if all low 16-bits are 0.
125 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
126 }], t2_hi16>;
127
Evan Cheng9cb9e672009-06-27 02:26:13 +0000128
Evan Cheng055b0312009-06-29 07:51:04 +0000129// Define Thumb2 specific addressing modes.
130
131// t2addrmode_imm12 := reg + imm12
132def t2addrmode_imm12 : Operand<i32>,
133 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
134 let PrintMethod = "printT2AddrModeImm12Operand";
135 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
136}
137
Evan Chenge88d5ce2009-07-02 07:28:31 +0000138// t2addrmode_imm8 := reg - imm8
Evan Cheng055b0312009-06-29 07:51:04 +0000139def t2addrmode_imm8 : Operand<i32>,
140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
141 let PrintMethod = "printT2AddrModeImm8Operand";
142 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
143}
144
Evan Cheng6d94f112009-07-03 00:06:39 +0000145def t2am_imm8_offset : Operand<i32>,
146 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
Evan Chenge88d5ce2009-07-02 07:28:31 +0000147 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
148}
149
David Goodwin6647cea2009-06-30 22:50:01 +0000150// t2addrmode_imm8s4 := reg + (imm8 << 2)
151def t2addrmode_imm8s4 : Operand<i32>,
152 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
153 let PrintMethod = "printT2AddrModeImm8Operand";
154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
155}
156
Evan Cheng055b0312009-06-29 07:51:04 +0000157// t2addrmode_so_reg := reg + reg << imm2
158def t2addrmode_so_reg : Operand<i32>,
159 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
160 let PrintMethod = "printT2AddrModeSoRegOperand";
161 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
162}
163
164
Anton Korobeynikov52237112009-06-17 18:13:58 +0000165//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000166// Multiclass helpers...
Anton Korobeynikov52237112009-06-17 18:13:58 +0000167//
168
Evan Chenga67efd12009-06-23 19:39:13 +0000169/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000170/// unary operation that produces a value. These are predicable and can be
171/// changed to modify CPSR.
Evan Chenga67efd12009-06-23 19:39:13 +0000172multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
173 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000174 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
175 opc, " $dst, $src",
Evan Chenga67efd12009-06-23 19:39:13 +0000176 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
177 let isAsCheapAsAMove = Cheap;
178 let isReMaterializable = ReMat;
179 }
180 // register
181 def r : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000182 opc, " $dst, $src",
Evan Chenga67efd12009-06-23 19:39:13 +0000183 [(set GPR:$dst, (opnode GPR:$src))]>;
184 // shifted register
185 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000186 opc, " $dst, $src",
187 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000188}
189
190/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000191// binary operation that produces a value. These are predicable and can be
192/// changed to modify CPSR.
Evan Cheng8de898a2009-06-26 00:19:44 +0000193multiclass T2I_bin_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000194 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000195 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
196 opc, " $dst, $lhs, $rhs",
197 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000198 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000199 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
200 opc, " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000201 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
202 let isCommutable = Commutable;
203 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000204 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000205 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
206 opc, " $dst, $lhs, $rhs",
207 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000208}
209
Evan Cheng1e249e32009-06-25 20:59:23 +0000210/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
211/// reversed. It doesn't define the 'rr' form since it's handled by its
212/// T2I_bin_irs counterpart.
213multiclass T2I_rbin_is<string opc, PatFrag opnode> {
Evan Chengf49810c2009-06-23 17:48:47 +0000214 // shifted imm
215 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000216 opc, " $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000217 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
218 // shifted register
219 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000220 opc, " $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000221 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
222}
223
Evan Chenga67efd12009-06-23 19:39:13 +0000224/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
Anton Korobeynikov52237112009-06-17 18:13:58 +0000225/// instruction modifies the CPSR register.
226let Defs = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000227multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000228 // shifted imm
Evan Chengf49810c2009-06-23 17:48:47 +0000229 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000230 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000231 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000232 // register
233 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000234 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000235 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
236 let isCommutable = Commutable;
237 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000238 // shifted register
Evan Chengf49810c2009-06-23 17:48:47 +0000239 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000240 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000241 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000242}
243}
244
Evan Chenga67efd12009-06-23 19:39:13 +0000245/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
246/// patterns for a binary operation that produces a value.
Evan Cheng8de898a2009-06-26 00:19:44 +0000247multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
Evan Chengf49810c2009-06-23 17:48:47 +0000248 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000249 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
250 opc, " $dst, $lhs, $rhs",
251 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000252 // 12-bit imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000253 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
254 !strconcat(opc, "w"), " $dst, $lhs, $rhs",
255 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000256 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000257 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
258 opc, " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000259 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
260 let isCommutable = Commutable;
261 }
Evan Chengf49810c2009-06-23 17:48:47 +0000262 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000263 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
264 opc, " $dst, $lhs, $rhs",
265 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000266}
267
Evan Cheng62674222009-06-25 23:34:10 +0000268/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng1e249e32009-06-25 20:59:23 +0000269/// binary operation that produces a value and use and define the carry bit.
270/// It's not predicable.
Evan Cheng62674222009-06-25 23:34:10 +0000271let Uses = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000272multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000273 // shifted imm
Evan Cheng62674222009-06-25 23:34:10 +0000274 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000275 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000276 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000277 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000278 // register
Evan Cheng62674222009-06-25 23:34:10 +0000279 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000280 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000281 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000282 Requires<[IsThumb2, CarryDefIsUnused]> {
Evan Cheng8de898a2009-06-26 00:19:44 +0000283 let isCommutable = Commutable;
284 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000285 // shifted register
Evan Cheng62674222009-06-25 23:34:10 +0000286 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000287 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000288 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000289 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng62674222009-06-25 23:34:10 +0000290 // Carry setting variants
291 // shifted imm
292 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
293 !strconcat(opc, "s $dst, $lhs, $rhs"),
294 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000295 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000296 let Defs = [CPSR];
297 }
298 // register
299 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
300 !strconcat(opc, "s $dst, $lhs, $rhs"),
301 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000302 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000303 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000304 let isCommutable = Commutable;
305 }
Evan Cheng62674222009-06-25 23:34:10 +0000306 // shifted register
307 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
308 !strconcat(opc, "s $dst, $lhs, $rhs"),
309 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000310 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000311 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000312 }
Evan Chengf49810c2009-06-23 17:48:47 +0000313}
314}
315
Evan Cheng62674222009-06-25 23:34:10 +0000316/// T2I_rsc_is - Same as T2I_adde_sube_irs except the order of operands are
Evan Cheng1e249e32009-06-25 20:59:23 +0000317/// reversed. It doesn't define the 'rr' form since it's handled by its
Evan Cheng62674222009-06-25 23:34:10 +0000318/// T2I_adde_sube_irs counterpart.
Evan Cheng1e249e32009-06-25 20:59:23 +0000319let Defs = [CPSR], Uses = [CPSR] in {
Evan Cheng62674222009-06-25 23:34:10 +0000320multiclass T2I_rsc_is<string opc, PatFrag opnode> {
Evan Cheng1e249e32009-06-25 20:59:23 +0000321 // shifted imm
Evan Cheng62674222009-06-25 23:34:10 +0000322 def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
323 opc, " $dst, $rhs, $lhs",
324 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000325 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000326 // shifted register
Evan Cheng62674222009-06-25 23:34:10 +0000327 def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
328 opc, " $dst, $rhs, $lhs",
329 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000330 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng62674222009-06-25 23:34:10 +0000331 // shifted imm
332 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
Evan Cheng1e249e32009-06-25 20:59:23 +0000333 !strconcat(opc, "s $dst, $rhs, $lhs"),
Evan Cheng62674222009-06-25 23:34:10 +0000334 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000335 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000336 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000337 }
Evan Cheng62674222009-06-25 23:34:10 +0000338 // shifted register
339 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
340 !strconcat(opc, "s $dst, $rhs, $lhs"),
341 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000342 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000343 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000344 }
Evan Cheng1e249e32009-06-25 20:59:23 +0000345}
346}
347
348/// T2I_rbin_s_is - Same as T2I_bin_s_irs except the order of operands are
349/// reversed. It doesn't define the 'rr' form since it's handled by its
350/// T2I_bin_s_irs counterpart.
351let Defs = [CPSR] in {
352multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
Evan Chengf49810c2009-06-23 17:48:47 +0000353 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000354 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
355 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
356 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000357 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000358 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
359 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
360 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000361}
362}
363
Evan Chenga67efd12009-06-23 19:39:13 +0000364/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
365// rotate operation that produces a value.
366multiclass T2I_sh_ir<string opc, PatFrag opnode> {
367 // 5-bit imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000368 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
369 opc, " $dst, $lhs, $rhs",
370 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000371 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000372 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
373 opc, " $dst, $lhs, $rhs",
374 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000375}
Evan Chengf49810c2009-06-23 17:48:47 +0000376
Evan Chenga67efd12009-06-23 19:39:13 +0000377/// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
378/// patterns. Similar to T2I_bin_irs except the instruction does not produce
Evan Chengf49810c2009-06-23 17:48:47 +0000379/// a explicit result, only implicitly set CPSR.
380let Uses = [CPSR] in {
381multiclass T2I_cmp_is<string opc, PatFrag opnode> {
382 // shifted imm
383 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000384 opc, " $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000385 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000386 // register
387 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000388 opc, " $lhs, $rhs",
Evan Chenga67efd12009-06-23 19:39:13 +0000389 [(opnode GPR:$lhs, GPR:$rhs)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000390 // shifted register
391 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000392 opc, " $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000393 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000394}
395}
396
Evan Chengf3c21b82009-06-30 02:15:48 +0000397/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
398multiclass T2I_ld<string opc, PatFrag opnode> {
399 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr),
400 opc, " $dst, $addr",
401 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
402 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr),
403 opc, " $dst, $addr",
404 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
405 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr),
406 opc, " $dst, $addr",
407 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
408 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr),
409 opc, " $dst, $addr",
410 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>;
411}
412
David Goodwin73b8f162009-06-30 22:11:34 +0000413/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
414multiclass T2I_st<string opc, PatFrag opnode> {
415 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr),
416 opc, " $src, $addr",
417 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
418 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr),
419 opc, " $src, $addr",
420 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
421 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr),
422 opc, " $src, $addr",
423 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
424}
425
David Goodwind1fa1202009-07-01 00:01:13 +0000426/// T2I_picld - Defines the PIC load pattern.
427class T2I_picld<string opc, PatFrag opnode> :
428 T2I<(outs GPR:$dst), (ins addrmodepc:$addr),
429 !strconcat("${addr:label}:\n\t", opc), " $dst, $addr",
430 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
431
432/// T2I_picst - Defines the PIC store pattern.
433class T2I_picst<string opc, PatFrag opnode> :
434 T2I<(outs), (ins GPR:$src, addrmodepc:$addr),
435 !strconcat("${addr:label}:\n\t", opc), " $src, $addr",
436 [(opnode GPR:$src, addrmodepc:$addr)]>;
437
Anton Korobeynikov52237112009-06-17 18:13:58 +0000438//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000439// Instructions
440//===----------------------------------------------------------------------===//
441
442//===----------------------------------------------------------------------===//
Evan Chenga09b9ca2009-06-24 23:47:58 +0000443// Miscellaneous Instructions.
444//
445
446let isNotDuplicable = 1 in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000447def t2PICADD : T2XI<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp),
448 "$cp:\n\tadd $dst, pc",
449 [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))]>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000450
451
452// LEApcrel - Load a pc-relative address into a register without offending the
453// assembler.
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000454def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p),
Evan Chenga09b9ca2009-06-24 23:47:58 +0000455 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
456 "${:private}PCRELL${:uid}+8))\n"),
457 !strconcat("${:private}PCRELL${:uid}:\n\t",
458 "add$p $dst, pc, #PCRELV${:uid}")),
459 []>;
460
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000461def t2LEApcrelJT : T2XI<(outs GPR:$dst),
Evan Chenga09b9ca2009-06-24 23:47:58 +0000462 (ins i32imm:$label, i32imm:$id, pred:$p),
463 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
464 "${:private}PCRELL${:uid}+8))\n"),
465 !strconcat("${:private}PCRELL${:uid}:\n\t",
466 "add$p $dst, pc, #PCRELV${:uid}")),
467 []>;
468
Evan Chengb6c29d52009-06-25 01:21:30 +0000469// ADD rd, sp, #so_imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000470def t2ADDrSPi : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
471 "add $dst, $sp, $imm",
472 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000473
474// ADD rd, sp, #imm12
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000475def t2ADDrSPi12 : T2XI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$imm),
476 "addw $dst, $sp, $imm",
477 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000478
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000479def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
480 "addw $dst, $sp, $rhs",
481 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000482
483
Evan Chenga09b9ca2009-06-24 23:47:58 +0000484//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000485// Load / store Instructions.
486//
487
Evan Cheng055b0312009-06-29 07:51:04 +0000488// Load
Evan Chengf3c21b82009-06-30 02:15:48 +0000489let canFoldAsLoad = 1 in
490defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000491
Evan Chengf3c21b82009-06-30 02:15:48 +0000492// Loads with zero extension
493defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
494defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000495
Evan Chengf3c21b82009-06-30 02:15:48 +0000496// Loads with sign extension
497defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
498defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000499
Evan Chengf3c21b82009-06-30 02:15:48 +0000500let mayLoad = 1 in {
501// Load doubleword
David Goodwin6647cea2009-06-30 22:50:01 +0000502def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr),
Evan Chengf3c21b82009-06-30 02:15:48 +0000503 "ldrd", " $dst, $addr", []>;
504def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr),
505 "ldrd", " $dst, $addr", []>;
506}
507
508// zextload i1 -> zextload i8
509def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
510 (t2LDRBi12 t2addrmode_imm12:$addr)>;
511def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
512 (t2LDRBi8 t2addrmode_imm8:$addr)>;
513def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
514 (t2LDRBs t2addrmode_so_reg:$addr)>;
515def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
516 (t2LDRBpci tconstpool:$addr)>;
517
518// extload -> zextload
519// FIXME: Reduce the number of patterns by legalizing extload to zextload
520// earlier?
521def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
522 (t2LDRBi12 t2addrmode_imm12:$addr)>;
523def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
524 (t2LDRBi8 t2addrmode_imm8:$addr)>;
525def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
526 (t2LDRBs t2addrmode_so_reg:$addr)>;
527def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
528 (t2LDRBpci tconstpool:$addr)>;
529
530def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
531 (t2LDRBi12 t2addrmode_imm12:$addr)>;
532def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
533 (t2LDRBi8 t2addrmode_imm8:$addr)>;
534def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
535 (t2LDRBs t2addrmode_so_reg:$addr)>;
536def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
537 (t2LDRBpci tconstpool:$addr)>;
538
539def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
540 (t2LDRHi12 t2addrmode_imm12:$addr)>;
541def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
542 (t2LDRHi8 t2addrmode_imm8:$addr)>;
543def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
544 (t2LDRHs t2addrmode_so_reg:$addr)>;
545def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
546 (t2LDRHpci tconstpool:$addr)>;
Evan Cheng055b0312009-06-29 07:51:04 +0000547
Evan Chenge88d5ce2009-07-02 07:28:31 +0000548// Indexed loads
Evan Cheng78236f82009-07-03 00:08:19 +0000549let mayLoad = 1 in {
Evan Chenge88d5ce2009-07-02 07:28:31 +0000550def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
551 (ins t2addrmode_imm8:$addr),
552 AddrModeT2_i8, IndexModePre,
553 "ldr", " $dst, $addr!", "$addr.base = $base_wb",
554 []>;
555
556def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
557 (ins GPR:$base, t2am_imm8_offset:$offset),
558 AddrModeT2_i8, IndexModePost,
559 "ldr", " $dst, [$base], $offset", "$base = $base_wb",
560 []>;
561
562def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
563 (ins t2addrmode_imm8:$addr),
564 AddrModeT2_i8, IndexModePre,
565 "ldrb", " $dst, $addr!", "$addr.base = $base_wb",
566 []>;
567def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
568 (ins GPR:$base, t2am_imm8_offset:$offset),
569 AddrModeT2_i8, IndexModePost,
570 "ldrb", " $dst, [$base], $offset", "$base = $base_wb",
571 []>;
572
573def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
574 (ins t2addrmode_imm8:$addr),
575 AddrModeT2_i8, IndexModePre,
576 "ldrh", " $dst, $addr!", "$addr.base = $base_wb",
577 []>;
578def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
579 (ins GPR:$base, t2am_imm8_offset:$offset),
580 AddrModeT2_i8, IndexModePost,
581 "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
582 []>;
583
Evan Cheng4fbb9962009-07-02 23:16:11 +0000584def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
585 (ins t2addrmode_imm8:$addr),
586 AddrModeT2_i8, IndexModePre,
587 "ldrsb", " $dst, $addr!", "$addr.base = $base_wb",
588 []>;
589def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
590 (ins GPR:$base, t2am_imm8_offset:$offset),
591 AddrModeT2_i8, IndexModePost,
592 "ldrsb", " $dst, [$base], $offset", "$base = $base_wb",
593 []>;
594
595def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
596 (ins t2addrmode_imm8:$addr),
597 AddrModeT2_i8, IndexModePre,
598 "ldrsh", " $dst, $addr!", "$addr.base = $base_wb",
599 []>;
600def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
601 (ins GPR:$base, t2am_imm8_offset:$offset),
602 AddrModeT2_i8, IndexModePost,
603 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
604 []>;
Evan Cheng78236f82009-07-03 00:08:19 +0000605}
Evan Cheng4fbb9962009-07-02 23:16:11 +0000606
David Goodwin73b8f162009-06-30 22:11:34 +0000607// Store
Evan Chenge88d5ce2009-07-02 07:28:31 +0000608defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
609defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
610defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
David Goodwin73b8f162009-06-30 22:11:34 +0000611
David Goodwin6647cea2009-06-30 22:50:01 +0000612// Store doubleword
613let mayLoad = 1 in
614def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
615 "strd", " $src, $addr", []>;
616
Evan Cheng6d94f112009-07-03 00:06:39 +0000617// Indexed stores
618def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb),
619 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
620 AddrModeT2_i8, IndexModePre,
621 "str", " $src, [$base, $offset]!", "$base = $base_wb",
622 [(set GPR:$base_wb,
623 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
624
625def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
626 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
627 AddrModeT2_i8, IndexModePost,
628 "str", " $src, [$base], $offset", "$base = $base_wb",
629 [(set GPR:$base_wb,
630 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
631
632def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb),
633 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
634 AddrModeT2_i8, IndexModePre,
635 "strh", " $src, [$base, $offset]!", "$base = $base_wb",
636 [(set GPR:$base_wb,
637 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
638
639def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
640 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
641 AddrModeT2_i8, IndexModePost,
642 "strh", " $src, [$base], $offset", "$base = $base_wb",
643 [(set GPR:$base_wb,
644 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
645
646def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb),
647 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
648 AddrModeT2_i8, IndexModePre,
649 "strb", " $src, [$base, $offset]!", "$base = $base_wb",
650 [(set GPR:$base_wb,
651 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
652
653def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
654 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
655 AddrModeT2_i8, IndexModePost,
656 "strb", " $src, [$base], $offset", "$base = $base_wb",
657 [(set GPR:$base_wb,
658 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
659
David Goodwind1fa1202009-07-01 00:01:13 +0000660
661// Address computation and loads and stores in PIC mode.
662let isNotDuplicable = 1, AddedComplexity = 10 in {
663let canFoldAsLoad = 1 in
664def t2PICLDR : T2I_picld<"ldr", UnOpFrag<(load node:$Src)>>;
665
666def t2PICLDRH : T2I_picld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
667def t2PICLDRB : T2I_picld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
668def t2PICLDRSH : T2I_picld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
669def t2PICLDRSB : T2I_picld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
670
671def t2PICSTR : T2I_picst<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
672def t2PICSTRH : T2I_picst<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
673def t2PICSTRB : T2I_picst<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
674} // isNotDuplicable = 1, AddedComplexity = 10
675
Evan Cheng2889cce2009-07-03 00:18:36 +0000676
677//===----------------------------------------------------------------------===//
678// Load / store multiple Instructions.
679//
680
681let mayLoad = 1 in
682def t2LDM : T2XI<(outs),
683 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
684 "ldm${p}${addr:submode} $addr, $dst1", []>;
685
686let mayStore = 1 in
687def t2STM : T2XI<(outs),
688 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
689 "stm${p}${addr:submode} $addr, $src1", []>;
690
Evan Cheng9cb9e672009-06-27 02:26:13 +0000691//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000692// Move Instructions.
693//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000694
Evan Chengf49810c2009-06-23 17:48:47 +0000695let neverHasSideEffects = 1 in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000696def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src),
697 "mov", " $dst, $src", []>;
Evan Chengf49810c2009-06-23 17:48:47 +0000698
Evan Chenga67efd12009-06-23 19:39:13 +0000699let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin83b35932009-06-26 16:10:07 +0000700def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
701 "mov", " $dst, $src",
702 [(set GPR:$dst, t2_so_imm:$src)]>;
703
704let isReMaterializable = 1, isAsCheapAsAMove = 1 in
705def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src),
706 "movw", " $dst, $src",
707 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000708
Evan Chengf49810c2009-06-23 17:48:47 +0000709// FIXME: Also available in ARM mode.
Evan Cheng3850a6a2009-06-23 05:23:49 +0000710let Constraints = "$src = $dst" in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000711def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
712 "movt", " $dst, $imm",
713 [(set GPR:$dst,
714 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000715
716//===----------------------------------------------------------------------===//
717// Arithmetic Instructions.
718//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000719
Evan Cheng8de898a2009-06-26 00:19:44 +0000720defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chenga67efd12009-06-23 19:39:13 +0000721defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000722
Evan Chengf49810c2009-06-23 17:48:47 +0000723// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Cheng8de898a2009-06-26 00:19:44 +0000724defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000725defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000726
Evan Cheng8de898a2009-06-26 00:19:44 +0000727defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
728defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000729
730// RSB, RSC
Evan Cheng1e249e32009-06-25 20:59:23 +0000731defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
732defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng62674222009-06-25 23:34:10 +0000733defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000734
735// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Cheng9cb9e672009-06-27 02:26:13 +0000736def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
737 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
738def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
739 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000740
741
Evan Chengf49810c2009-06-23 17:48:47 +0000742//===----------------------------------------------------------------------===//
Evan Chenga67efd12009-06-23 19:39:13 +0000743// Shift and rotate Instructions.
744//
745
746defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
747defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
748defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
749defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
750
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000751def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src),
752 "mov", " $dst, $src, rrx",
753 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000754
755//===----------------------------------------------------------------------===//
Evan Chengf49810c2009-06-23 17:48:47 +0000756// Bitwise Instructions.
757//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000758
Evan Cheng8de898a2009-06-26 00:19:44 +0000759defm t2AND : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
760defm t2ORR : T2I_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
761defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000762
Evan Chenga67efd12009-06-23 19:39:13 +0000763defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000764
Evan Cheng9cb9e672009-06-27 02:26:13 +0000765def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
766 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000767
Evan Chenga67efd12009-06-23 19:39:13 +0000768defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000769
Evan Cheng9cb9e672009-06-27 02:26:13 +0000770def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
771 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000772
David Goodwindcdaebc2009-06-26 23:13:13 +0000773// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
774let AddedComplexity = 1 in
Evan Chenga67efd12009-06-23 19:39:13 +0000775defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000776
Evan Cheng9cb9e672009-06-27 02:26:13 +0000777def : T2Pat<(t2_so_imm_not:$src),
778 (t2MVNi t2_so_imm_not:$src)>;
David Goodwin0919a912009-06-25 23:11:21 +0000779
Evan Chengf49810c2009-06-23 17:48:47 +0000780// A8.6.17 BFC - Bitfield clear
781// FIXME: Also available in ARM mode.
782let Constraints = "$src = $dst" in
783def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000784 "bfc", " $dst, $imm",
Evan Chengf49810c2009-06-23 17:48:47 +0000785 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
786
787// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
788
789//===----------------------------------------------------------------------===//
790// Multiply Instructions.
791//
Evan Cheng8de898a2009-06-26 00:19:44 +0000792let isCommutable = 1 in
Evan Chengf49810c2009-06-23 17:48:47 +0000793def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000794 "mul", " $dst, $a, $b",
Evan Chengf49810c2009-06-23 17:48:47 +0000795 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
796
797def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000798 "mla", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000799 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
800
801def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000802 "mls", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000803 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
804
805// FIXME: SMULL, etc.
806
807//===----------------------------------------------------------------------===//
808// Misc. Arithmetic Instructions.
809//
810
Evan Chengf49810c2009-06-23 17:48:47 +0000811def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000812 "clz", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000813 [(set GPR:$dst, (ctlz GPR:$src))]>;
814
815def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000816 "rev", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000817 [(set GPR:$dst, (bswap GPR:$src))]>;
818
819def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000820 "rev16", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000821 [(set GPR:$dst,
822 (or (and (srl GPR:$src, (i32 8)), 0xFF),
823 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
824 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
825 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
826
827/////
828/// A8.6.137 REVSH
829/////
830def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000831 "revsh", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000832 [(set GPR:$dst,
833 (sext_inreg
834 (or (srl (and GPR:$src, 0xFFFF), (i32 8)),
835 (shl GPR:$src, (i32 8))), i16))]>;
836
837// FIXME: PKHxx etc.
838
839//===----------------------------------------------------------------------===//
840// Comparison Instructions...
841//
842
843defm t2CMP : T2I_cmp_is<"cmp",
844 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000845defm t2CMPz : T2I_cmp_is<"cmp",
846 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000847
848defm t2CMN : T2I_cmp_is<"cmn",
849 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000850defm t2CMNz : T2I_cmp_is<"cmn",
851 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000852
Evan Cheng9cb9e672009-06-27 02:26:13 +0000853def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
854 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000855
David Goodwinc0309b42009-06-29 15:33:01 +0000856def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng9cb9e672009-06-27 02:26:13 +0000857 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000858
David Goodwinbaeb9112009-06-29 22:49:42 +0000859defm t2TST : T2I_cmp_is<"tst",
860 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
861defm t2TEQ : T2I_cmp_is<"teq",
862 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000863
864// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
865// Short range conditional branch. Looks awesome for loops. Need to figure
866// out how to use this one.
867
868// FIXME: Conditional moves
869
David Goodwin5e47a9a2009-06-30 18:04:13 +0000870//===----------------------------------------------------------------------===//
871// Control-Flow Instructions
872//
873
874let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
875let isPredicable = 1 in
876def t2B : T2XI<(outs), (ins brtarget:$target),
877 "b $target",
878 [(br bb:$target)]>;
879
David Goodwinc9a59b52009-06-30 19:50:22 +0000880let isNotDuplicable = 1, isIndirectBranch = 1 in {
881def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
882 "mov pc, $target \n$jt",
883 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
884
885def t2BR_JTm :
886 T2JTI<(outs),
887 (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
888 "ldr pc, $target \n$jt",
889 [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
890 imm:$id)]>;
891
892def t2BR_JTadd :
893 T2JTI<(outs),
894 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
895 "add pc, $target, $idx \n$jt",
896 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
897} // isNotDuplicate, isIndirectBranch
898} // isBranch, isTerminator, isBarrier
David Goodwin5e47a9a2009-06-30 18:04:13 +0000899
900// FIXME: should be able to write a pattern for ARMBrcond, but can't use
901// a two-value operand where a dag node expects two operands. :(
902let isBranch = 1, isTerminator = 1 in
903def t2Bcc : T2I<(outs), (ins brtarget:$target),
904 "b", " $target",
905 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000906
907//===----------------------------------------------------------------------===//
908// Non-Instruction Patterns
909//
910
Evan Chenga09b9ca2009-06-24 23:47:58 +0000911// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng9cb9e672009-06-27 02:26:13 +0000912def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
913def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
914def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
915 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000916
Evan Chengf49810c2009-06-23 17:48:47 +0000917// Large immediate handling.
918
Evan Cheng9cb9e672009-06-27 02:26:13 +0000919def : T2Pat<(i32 imm:$src),
920 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;