blob: 2b9c9d42f8c093d9da523aa2feedb395a67e5ce1 [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
549def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
550 (ins t2addrmode_imm8:$addr),
551 AddrModeT2_i8, IndexModePre,
552 "ldr", " $dst, $addr!", "$addr.base = $base_wb",
553 []>;
554
555def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
556 (ins GPR:$base, t2am_imm8_offset:$offset),
557 AddrModeT2_i8, IndexModePost,
558 "ldr", " $dst, [$base], $offset", "$base = $base_wb",
559 []>;
560
561def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
562 (ins t2addrmode_imm8:$addr),
563 AddrModeT2_i8, IndexModePre,
564 "ldrb", " $dst, $addr!", "$addr.base = $base_wb",
565 []>;
566def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
567 (ins GPR:$base, t2am_imm8_offset:$offset),
568 AddrModeT2_i8, IndexModePost,
569 "ldrb", " $dst, [$base], $offset", "$base = $base_wb",
570 []>;
571
572def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
573 (ins t2addrmode_imm8:$addr),
574 AddrModeT2_i8, IndexModePre,
575 "ldrh", " $dst, $addr!", "$addr.base = $base_wb",
576 []>;
577def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
578 (ins GPR:$base, t2am_imm8_offset:$offset),
579 AddrModeT2_i8, IndexModePost,
580 "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
581 []>;
582
Evan Cheng4fbb9962009-07-02 23:16:11 +0000583def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
584 (ins t2addrmode_imm8:$addr),
585 AddrModeT2_i8, IndexModePre,
586 "ldrsb", " $dst, $addr!", "$addr.base = $base_wb",
587 []>;
588def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
589 (ins GPR:$base, t2am_imm8_offset:$offset),
590 AddrModeT2_i8, IndexModePost,
591 "ldrsb", " $dst, [$base], $offset", "$base = $base_wb",
592 []>;
593
594def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
595 (ins t2addrmode_imm8:$addr),
596 AddrModeT2_i8, IndexModePre,
597 "ldrsh", " $dst, $addr!", "$addr.base = $base_wb",
598 []>;
599def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
600 (ins GPR:$base, t2am_imm8_offset:$offset),
601 AddrModeT2_i8, IndexModePost,
602 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
603 []>;
604
David Goodwin73b8f162009-06-30 22:11:34 +0000605// Store
Evan Chenge88d5ce2009-07-02 07:28:31 +0000606defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
607defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
608defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
David Goodwin73b8f162009-06-30 22:11:34 +0000609
David Goodwin6647cea2009-06-30 22:50:01 +0000610// Store doubleword
611let mayLoad = 1 in
612def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
613 "strd", " $src, $addr", []>;
614
Evan Cheng6d94f112009-07-03 00:06:39 +0000615// Indexed stores
616def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb),
617 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
618 AddrModeT2_i8, IndexModePre,
619 "str", " $src, [$base, $offset]!", "$base = $base_wb",
620 [(set GPR:$base_wb,
621 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
622
623def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
624 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
625 AddrModeT2_i8, IndexModePost,
626 "str", " $src, [$base], $offset", "$base = $base_wb",
627 [(set GPR:$base_wb,
628 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
629
630def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb),
631 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
632 AddrModeT2_i8, IndexModePre,
633 "strh", " $src, [$base, $offset]!", "$base = $base_wb",
634 [(set GPR:$base_wb,
635 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
636
637def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
638 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
639 AddrModeT2_i8, IndexModePost,
640 "strh", " $src, [$base], $offset", "$base = $base_wb",
641 [(set GPR:$base_wb,
642 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
643
644def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb),
645 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
646 AddrModeT2_i8, IndexModePre,
647 "strb", " $src, [$base, $offset]!", "$base = $base_wb",
648 [(set GPR:$base_wb,
649 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
650
651def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
652 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
653 AddrModeT2_i8, IndexModePost,
654 "strb", " $src, [$base], $offset", "$base = $base_wb",
655 [(set GPR:$base_wb,
656 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
657
David Goodwind1fa1202009-07-01 00:01:13 +0000658
659// Address computation and loads and stores in PIC mode.
660let isNotDuplicable = 1, AddedComplexity = 10 in {
661let canFoldAsLoad = 1 in
662def t2PICLDR : T2I_picld<"ldr", UnOpFrag<(load node:$Src)>>;
663
664def t2PICLDRH : T2I_picld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
665def t2PICLDRB : T2I_picld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
666def t2PICLDRSH : T2I_picld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
667def t2PICLDRSB : T2I_picld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
668
669def t2PICSTR : T2I_picst<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
670def t2PICSTRH : T2I_picst<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
671def t2PICSTRB : T2I_picst<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
672} // isNotDuplicable = 1, AddedComplexity = 10
673
Evan Cheng9cb9e672009-06-27 02:26:13 +0000674//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000675// Move Instructions.
676//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000677
Evan Chengf49810c2009-06-23 17:48:47 +0000678let neverHasSideEffects = 1 in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000679def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src),
680 "mov", " $dst, $src", []>;
Evan Chengf49810c2009-06-23 17:48:47 +0000681
Evan Chenga67efd12009-06-23 19:39:13 +0000682let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin83b35932009-06-26 16:10:07 +0000683def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
684 "mov", " $dst, $src",
685 [(set GPR:$dst, t2_so_imm:$src)]>;
686
687let isReMaterializable = 1, isAsCheapAsAMove = 1 in
688def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src),
689 "movw", " $dst, $src",
690 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000691
Evan Chengf49810c2009-06-23 17:48:47 +0000692// FIXME: Also available in ARM mode.
Evan Cheng3850a6a2009-06-23 05:23:49 +0000693let Constraints = "$src = $dst" in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000694def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
695 "movt", " $dst, $imm",
696 [(set GPR:$dst,
697 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000698
699//===----------------------------------------------------------------------===//
700// Arithmetic Instructions.
701//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000702
Evan Cheng8de898a2009-06-26 00:19:44 +0000703defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chenga67efd12009-06-23 19:39:13 +0000704defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000705
Evan Chengf49810c2009-06-23 17:48:47 +0000706// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Cheng8de898a2009-06-26 00:19:44 +0000707defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000708defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000709
Evan Cheng8de898a2009-06-26 00:19:44 +0000710defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
711defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000712
713// RSB, RSC
Evan Cheng1e249e32009-06-25 20:59:23 +0000714defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
715defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng62674222009-06-25 23:34:10 +0000716defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000717
718// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Cheng9cb9e672009-06-27 02:26:13 +0000719def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
720 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
721def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
722 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000723
724
Evan Chengf49810c2009-06-23 17:48:47 +0000725//===----------------------------------------------------------------------===//
Evan Chenga67efd12009-06-23 19:39:13 +0000726// Shift and rotate Instructions.
727//
728
729defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
730defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
731defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
732defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
733
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000734def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src),
735 "mov", " $dst, $src, rrx",
736 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000737
738//===----------------------------------------------------------------------===//
Evan Chengf49810c2009-06-23 17:48:47 +0000739// Bitwise Instructions.
740//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000741
Evan Cheng8de898a2009-06-26 00:19:44 +0000742defm t2AND : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
743defm t2ORR : T2I_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
744defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000745
Evan Chenga67efd12009-06-23 19:39:13 +0000746defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000747
Evan Cheng9cb9e672009-06-27 02:26:13 +0000748def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
749 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000750
Evan Chenga67efd12009-06-23 19:39:13 +0000751defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000752
Evan Cheng9cb9e672009-06-27 02:26:13 +0000753def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
754 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000755
David Goodwindcdaebc2009-06-26 23:13:13 +0000756// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
757let AddedComplexity = 1 in
Evan Chenga67efd12009-06-23 19:39:13 +0000758defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000759
Evan Cheng9cb9e672009-06-27 02:26:13 +0000760def : T2Pat<(t2_so_imm_not:$src),
761 (t2MVNi t2_so_imm_not:$src)>;
David Goodwin0919a912009-06-25 23:11:21 +0000762
Evan Chengf49810c2009-06-23 17:48:47 +0000763// A8.6.17 BFC - Bitfield clear
764// FIXME: Also available in ARM mode.
765let Constraints = "$src = $dst" in
766def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000767 "bfc", " $dst, $imm",
Evan Chengf49810c2009-06-23 17:48:47 +0000768 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
769
770// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
771
772//===----------------------------------------------------------------------===//
773// Multiply Instructions.
774//
Evan Cheng8de898a2009-06-26 00:19:44 +0000775let isCommutable = 1 in
Evan Chengf49810c2009-06-23 17:48:47 +0000776def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000777 "mul", " $dst, $a, $b",
Evan Chengf49810c2009-06-23 17:48:47 +0000778 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
779
780def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000781 "mla", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000782 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
783
784def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000785 "mls", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000786 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
787
788// FIXME: SMULL, etc.
789
790//===----------------------------------------------------------------------===//
791// Misc. Arithmetic Instructions.
792//
793
Evan Chengf49810c2009-06-23 17:48:47 +0000794def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000795 "clz", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000796 [(set GPR:$dst, (ctlz GPR:$src))]>;
797
798def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000799 "rev", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000800 [(set GPR:$dst, (bswap GPR:$src))]>;
801
802def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000803 "rev16", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000804 [(set GPR:$dst,
805 (or (and (srl GPR:$src, (i32 8)), 0xFF),
806 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
807 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
808 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
809
810/////
811/// A8.6.137 REVSH
812/////
813def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000814 "revsh", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000815 [(set GPR:$dst,
816 (sext_inreg
817 (or (srl (and GPR:$src, 0xFFFF), (i32 8)),
818 (shl GPR:$src, (i32 8))), i16))]>;
819
820// FIXME: PKHxx etc.
821
822//===----------------------------------------------------------------------===//
823// Comparison Instructions...
824//
825
826defm t2CMP : T2I_cmp_is<"cmp",
827 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000828defm t2CMPz : T2I_cmp_is<"cmp",
829 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000830
831defm t2CMN : T2I_cmp_is<"cmn",
832 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000833defm t2CMNz : T2I_cmp_is<"cmn",
834 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000835
Evan Cheng9cb9e672009-06-27 02:26:13 +0000836def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
837 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000838
David Goodwinc0309b42009-06-29 15:33:01 +0000839def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng9cb9e672009-06-27 02:26:13 +0000840 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000841
David Goodwinbaeb9112009-06-29 22:49:42 +0000842defm t2TST : T2I_cmp_is<"tst",
843 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
844defm t2TEQ : T2I_cmp_is<"teq",
845 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000846
847// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
848// Short range conditional branch. Looks awesome for loops. Need to figure
849// out how to use this one.
850
851// FIXME: Conditional moves
852
David Goodwin5e47a9a2009-06-30 18:04:13 +0000853//===----------------------------------------------------------------------===//
854// Control-Flow Instructions
855//
856
857let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
858let isPredicable = 1 in
859def t2B : T2XI<(outs), (ins brtarget:$target),
860 "b $target",
861 [(br bb:$target)]>;
862
David Goodwinc9a59b52009-06-30 19:50:22 +0000863let isNotDuplicable = 1, isIndirectBranch = 1 in {
864def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
865 "mov pc, $target \n$jt",
866 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
867
868def t2BR_JTm :
869 T2JTI<(outs),
870 (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
871 "ldr pc, $target \n$jt",
872 [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
873 imm:$id)]>;
874
875def t2BR_JTadd :
876 T2JTI<(outs),
877 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
878 "add pc, $target, $idx \n$jt",
879 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
880} // isNotDuplicate, isIndirectBranch
881} // isBranch, isTerminator, isBarrier
David Goodwin5e47a9a2009-06-30 18:04:13 +0000882
883// FIXME: should be able to write a pattern for ARMBrcond, but can't use
884// a two-value operand where a dag node expects two operands. :(
885let isBranch = 1, isTerminator = 1 in
886def t2Bcc : T2I<(outs), (ins brtarget:$target),
887 "b", " $target",
888 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000889
890//===----------------------------------------------------------------------===//
891// Non-Instruction Patterns
892//
893
Evan Chenga09b9ca2009-06-24 23:47:58 +0000894// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng9cb9e672009-06-27 02:26:13 +0000895def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
896def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
897def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
898 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000899
Evan Chengf49810c2009-06-23 17:48:47 +0000900// Large immediate handling.
901
Evan Cheng9cb9e672009-06-27 02:26:13 +0000902def : T2Pat<(i32 imm:$src),
903 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;