blob: e418a4f716303dfe3c0d9d722a7e39445d29cda3 [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 Chenge88d5ce2009-07-02 07:28:31 +0000145def t2am_imm8_offset : Operand<i32> {
146 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
147}
148
David Goodwin6647cea2009-06-30 22:50:01 +0000149// t2addrmode_imm8s4 := reg + (imm8 << 2)
150def t2addrmode_imm8s4 : Operand<i32>,
151 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
152 let PrintMethod = "printT2AddrModeImm8Operand";
153 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
154}
155
Evan Cheng055b0312009-06-29 07:51:04 +0000156// t2addrmode_so_reg := reg + reg << imm2
157def t2addrmode_so_reg : Operand<i32>,
158 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
159 let PrintMethod = "printT2AddrModeSoRegOperand";
160 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
161}
162
163
Anton Korobeynikov52237112009-06-17 18:13:58 +0000164//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000165// Multiclass helpers...
Anton Korobeynikov52237112009-06-17 18:13:58 +0000166//
167
Evan Chenga67efd12009-06-23 19:39:13 +0000168/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000169/// unary operation that produces a value. These are predicable and can be
170/// changed to modify CPSR.
Evan Chenga67efd12009-06-23 19:39:13 +0000171multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
172 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000173 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
174 opc, " $dst, $src",
Evan Chenga67efd12009-06-23 19:39:13 +0000175 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
176 let isAsCheapAsAMove = Cheap;
177 let isReMaterializable = ReMat;
178 }
179 // register
180 def r : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000181 opc, " $dst, $src",
Evan Chenga67efd12009-06-23 19:39:13 +0000182 [(set GPR:$dst, (opnode GPR:$src))]>;
183 // shifted register
184 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000185 opc, " $dst, $src",
186 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000187}
188
189/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000190// binary operation that produces a value. These are predicable and can be
191/// changed to modify CPSR.
Evan Cheng8de898a2009-06-26 00:19:44 +0000192multiclass T2I_bin_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000193 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000194 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
195 opc, " $dst, $lhs, $rhs",
196 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000197 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000198 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
199 opc, " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000200 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
201 let isCommutable = Commutable;
202 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000203 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000204 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
205 opc, " $dst, $lhs, $rhs",
206 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000207}
208
Evan Cheng1e249e32009-06-25 20:59:23 +0000209/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
210/// reversed. It doesn't define the 'rr' form since it's handled by its
211/// T2I_bin_irs counterpart.
212multiclass T2I_rbin_is<string opc, PatFrag opnode> {
Evan Chengf49810c2009-06-23 17:48:47 +0000213 // shifted imm
214 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000215 opc, " $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000216 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
217 // shifted register
218 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000219 opc, " $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000220 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
221}
222
Evan Chenga67efd12009-06-23 19:39:13 +0000223/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
Anton Korobeynikov52237112009-06-17 18:13:58 +0000224/// instruction modifies the CPSR register.
225let Defs = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000226multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000227 // shifted imm
Evan Chengf49810c2009-06-23 17:48:47 +0000228 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000229 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000230 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000231 // register
232 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000233 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000234 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
235 let isCommutable = Commutable;
236 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000237 // shifted register
Evan Chengf49810c2009-06-23 17:48:47 +0000238 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000239 !strconcat(opc, "s"), " $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000240 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000241}
242}
243
Evan Chenga67efd12009-06-23 19:39:13 +0000244/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
245/// patterns for a binary operation that produces a value.
Evan Cheng8de898a2009-06-26 00:19:44 +0000246multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
Evan Chengf49810c2009-06-23 17:48:47 +0000247 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000248 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
249 opc, " $dst, $lhs, $rhs",
250 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000251 // 12-bit imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000252 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
253 !strconcat(opc, "w"), " $dst, $lhs, $rhs",
254 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000255 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000256 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
257 opc, " $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000258 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
259 let isCommutable = Commutable;
260 }
Evan Chengf49810c2009-06-23 17:48:47 +0000261 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000262 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
263 opc, " $dst, $lhs, $rhs",
264 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000265}
266
Evan Cheng62674222009-06-25 23:34:10 +0000267/// 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 +0000268/// binary operation that produces a value and use and define the carry bit.
269/// It's not predicable.
Evan Cheng62674222009-06-25 23:34:10 +0000270let Uses = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000271multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000272 // shifted imm
Evan Cheng62674222009-06-25 23:34:10 +0000273 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000274 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000275 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000276 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000277 // register
Evan Cheng62674222009-06-25 23:34:10 +0000278 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000279 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000280 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000281 Requires<[IsThumb2, CarryDefIsUnused]> {
Evan Cheng8de898a2009-06-26 00:19:44 +0000282 let isCommutable = Commutable;
283 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000284 // shifted register
Evan Cheng62674222009-06-25 23:34:10 +0000285 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
David Goodwin7ce720b2009-06-26 20:45:56 +0000286 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000287 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000288 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng62674222009-06-25 23:34:10 +0000289 // Carry setting variants
290 // shifted imm
291 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
292 !strconcat(opc, "s $dst, $lhs, $rhs"),
293 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000294 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000295 let Defs = [CPSR];
296 }
297 // register
298 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
299 !strconcat(opc, "s $dst, $lhs, $rhs"),
300 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000301 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000302 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000303 let isCommutable = Commutable;
304 }
Evan Cheng62674222009-06-25 23:34:10 +0000305 // shifted register
306 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
307 !strconcat(opc, "s $dst, $lhs, $rhs"),
308 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000309 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000310 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000311 }
Evan Chengf49810c2009-06-23 17:48:47 +0000312}
313}
314
Evan Cheng62674222009-06-25 23:34:10 +0000315/// T2I_rsc_is - Same as T2I_adde_sube_irs except the order of operands are
Evan Cheng1e249e32009-06-25 20:59:23 +0000316/// reversed. It doesn't define the 'rr' form since it's handled by its
Evan Cheng62674222009-06-25 23:34:10 +0000317/// T2I_adde_sube_irs counterpart.
Evan Cheng1e249e32009-06-25 20:59:23 +0000318let Defs = [CPSR], Uses = [CPSR] in {
Evan Cheng62674222009-06-25 23:34:10 +0000319multiclass T2I_rsc_is<string opc, PatFrag opnode> {
Evan Cheng1e249e32009-06-25 20:59:23 +0000320 // shifted imm
Evan Cheng62674222009-06-25 23:34:10 +0000321 def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
322 opc, " $dst, $rhs, $lhs",
323 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000324 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000325 // shifted register
Evan Cheng62674222009-06-25 23:34:10 +0000326 def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
327 opc, " $dst, $rhs, $lhs",
328 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000329 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng62674222009-06-25 23:34:10 +0000330 // shifted imm
331 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
Evan Cheng1e249e32009-06-25 20:59:23 +0000332 !strconcat(opc, "s $dst, $rhs, $lhs"),
Evan Cheng62674222009-06-25 23:34:10 +0000333 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000334 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000335 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000336 }
Evan Cheng62674222009-06-25 23:34:10 +0000337 // shifted register
338 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
339 !strconcat(opc, "s $dst, $rhs, $lhs"),
340 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000341 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000342 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000343 }
Evan Cheng1e249e32009-06-25 20:59:23 +0000344}
345}
346
347/// T2I_rbin_s_is - Same as T2I_bin_s_irs except the order of operands are
348/// reversed. It doesn't define the 'rr' form since it's handled by its
349/// T2I_bin_s_irs counterpart.
350let Defs = [CPSR] in {
351multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
Evan Chengf49810c2009-06-23 17:48:47 +0000352 // shifted imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000353 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
354 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
355 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000356 // shifted register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000357 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
358 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
359 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000360}
361}
362
Evan Chenga67efd12009-06-23 19:39:13 +0000363/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
364// rotate operation that produces a value.
365multiclass T2I_sh_ir<string opc, PatFrag opnode> {
366 // 5-bit imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000367 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
368 opc, " $dst, $lhs, $rhs",
369 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000370 // register
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000371 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
372 opc, " $dst, $lhs, $rhs",
373 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000374}
Evan Chengf49810c2009-06-23 17:48:47 +0000375
Evan Chenga67efd12009-06-23 19:39:13 +0000376/// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
377/// patterns. Similar to T2I_bin_irs except the instruction does not produce
Evan Chengf49810c2009-06-23 17:48:47 +0000378/// a explicit result, only implicitly set CPSR.
379let Uses = [CPSR] in {
380multiclass T2I_cmp_is<string opc, PatFrag opnode> {
381 // shifted imm
382 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000383 opc, " $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000384 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000385 // register
386 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000387 opc, " $lhs, $rhs",
Evan Chenga67efd12009-06-23 19:39:13 +0000388 [(opnode GPR:$lhs, GPR:$rhs)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000389 // shifted register
390 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000391 opc, " $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000392 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000393}
394}
395
Evan Chengf3c21b82009-06-30 02:15:48 +0000396/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
397multiclass T2I_ld<string opc, PatFrag opnode> {
398 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr),
399 opc, " $dst, $addr",
400 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
401 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr),
402 opc, " $dst, $addr",
403 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
404 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr),
405 opc, " $dst, $addr",
406 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
407 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr),
408 opc, " $dst, $addr",
409 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>;
410}
411
David Goodwin73b8f162009-06-30 22:11:34 +0000412/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
413multiclass T2I_st<string opc, PatFrag opnode> {
414 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr),
415 opc, " $src, $addr",
416 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
417 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr),
418 opc, " $src, $addr",
419 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
420 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr),
421 opc, " $src, $addr",
422 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
423}
424
David Goodwind1fa1202009-07-01 00:01:13 +0000425/// T2I_picld - Defines the PIC load pattern.
426class T2I_picld<string opc, PatFrag opnode> :
427 T2I<(outs GPR:$dst), (ins addrmodepc:$addr),
428 !strconcat("${addr:label}:\n\t", opc), " $dst, $addr",
429 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
430
431/// T2I_picst - Defines the PIC store pattern.
432class T2I_picst<string opc, PatFrag opnode> :
433 T2I<(outs), (ins GPR:$src, addrmodepc:$addr),
434 !strconcat("${addr:label}:\n\t", opc), " $src, $addr",
435 [(opnode GPR:$src, addrmodepc:$addr)]>;
436
Anton Korobeynikov52237112009-06-17 18:13:58 +0000437//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000438// Instructions
439//===----------------------------------------------------------------------===//
440
441//===----------------------------------------------------------------------===//
Evan Chenga09b9ca2009-06-24 23:47:58 +0000442// Miscellaneous Instructions.
443//
444
445let isNotDuplicable = 1 in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000446def t2PICADD : T2XI<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp),
447 "$cp:\n\tadd $dst, pc",
448 [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))]>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000449
450
451// LEApcrel - Load a pc-relative address into a register without offending the
452// assembler.
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000453def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p),
Evan Chenga09b9ca2009-06-24 23:47:58 +0000454 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
455 "${:private}PCRELL${:uid}+8))\n"),
456 !strconcat("${:private}PCRELL${:uid}:\n\t",
457 "add$p $dst, pc, #PCRELV${:uid}")),
458 []>;
459
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000460def t2LEApcrelJT : T2XI<(outs GPR:$dst),
Evan Chenga09b9ca2009-06-24 23:47:58 +0000461 (ins i32imm:$label, i32imm:$id, pred:$p),
462 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
463 "${:private}PCRELL${:uid}+8))\n"),
464 !strconcat("${:private}PCRELL${:uid}:\n\t",
465 "add$p $dst, pc, #PCRELV${:uid}")),
466 []>;
467
Evan Chengb6c29d52009-06-25 01:21:30 +0000468// ADD rd, sp, #so_imm
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000469def t2ADDrSPi : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
470 "add $dst, $sp, $imm",
471 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000472
473// ADD rd, sp, #imm12
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000474def t2ADDrSPi12 : T2XI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$imm),
475 "addw $dst, $sp, $imm",
476 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000477
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000478def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
479 "addw $dst, $sp, $rhs",
480 []>;
Evan Chengb6c29d52009-06-25 01:21:30 +0000481
482
Evan Chenga09b9ca2009-06-24 23:47:58 +0000483//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000484// Load / store Instructions.
485//
486
Evan Cheng055b0312009-06-29 07:51:04 +0000487// Load
Evan Chengf3c21b82009-06-30 02:15:48 +0000488let canFoldAsLoad = 1 in
489defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000490
Evan Chengf3c21b82009-06-30 02:15:48 +0000491// Loads with zero extension
492defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
493defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000494
Evan Chengf3c21b82009-06-30 02:15:48 +0000495// Loads with sign extension
496defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
497defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000498
Evan Chengf3c21b82009-06-30 02:15:48 +0000499let mayLoad = 1 in {
500// Load doubleword
David Goodwin6647cea2009-06-30 22:50:01 +0000501def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr),
Evan Chengf3c21b82009-06-30 02:15:48 +0000502 "ldrd", " $dst, $addr", []>;
503def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr),
504 "ldrd", " $dst, $addr", []>;
505}
506
507// zextload i1 -> zextload i8
508def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
509 (t2LDRBi12 t2addrmode_imm12:$addr)>;
510def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
511 (t2LDRBi8 t2addrmode_imm8:$addr)>;
512def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
513 (t2LDRBs t2addrmode_so_reg:$addr)>;
514def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
515 (t2LDRBpci tconstpool:$addr)>;
516
517// extload -> zextload
518// FIXME: Reduce the number of patterns by legalizing extload to zextload
519// earlier?
520def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
521 (t2LDRBi12 t2addrmode_imm12:$addr)>;
522def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
523 (t2LDRBi8 t2addrmode_imm8:$addr)>;
524def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
525 (t2LDRBs t2addrmode_so_reg:$addr)>;
526def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
527 (t2LDRBpci tconstpool:$addr)>;
528
529def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
530 (t2LDRBi12 t2addrmode_imm12:$addr)>;
531def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
532 (t2LDRBi8 t2addrmode_imm8:$addr)>;
533def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
534 (t2LDRBs t2addrmode_so_reg:$addr)>;
535def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
536 (t2LDRBpci tconstpool:$addr)>;
537
538def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
539 (t2LDRHi12 t2addrmode_imm12:$addr)>;
540def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
541 (t2LDRHi8 t2addrmode_imm8:$addr)>;
542def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
543 (t2LDRHs t2addrmode_so_reg:$addr)>;
544def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
545 (t2LDRHpci tconstpool:$addr)>;
Evan Cheng055b0312009-06-29 07:51:04 +0000546
Evan Chenge88d5ce2009-07-02 07:28:31 +0000547// Indexed loads
548def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
549 (ins t2addrmode_imm8:$addr),
550 AddrModeT2_i8, IndexModePre,
551 "ldr", " $dst, $addr!", "$addr.base = $base_wb",
552 []>;
553
554def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
555 (ins GPR:$base, t2am_imm8_offset:$offset),
556 AddrModeT2_i8, IndexModePost,
557 "ldr", " $dst, [$base], $offset", "$base = $base_wb",
558 []>;
559
560def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
561 (ins t2addrmode_imm8:$addr),
562 AddrModeT2_i8, IndexModePre,
563 "ldrb", " $dst, $addr!", "$addr.base = $base_wb",
564 []>;
565def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
566 (ins GPR:$base, t2am_imm8_offset:$offset),
567 AddrModeT2_i8, IndexModePost,
568 "ldrb", " $dst, [$base], $offset", "$base = $base_wb",
569 []>;
570
571def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
572 (ins t2addrmode_imm8:$addr),
573 AddrModeT2_i8, IndexModePre,
574 "ldrh", " $dst, $addr!", "$addr.base = $base_wb",
575 []>;
576def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
577 (ins GPR:$base, t2am_imm8_offset:$offset),
578 AddrModeT2_i8, IndexModePost,
579 "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
580 []>;
581
Evan Cheng4fbb9962009-07-02 23:16:11 +0000582def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
583 (ins t2addrmode_imm8:$addr),
584 AddrModeT2_i8, IndexModePre,
585 "ldrsb", " $dst, $addr!", "$addr.base = $base_wb",
586 []>;
587def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
588 (ins GPR:$base, t2am_imm8_offset:$offset),
589 AddrModeT2_i8, IndexModePost,
590 "ldrsb", " $dst, [$base], $offset", "$base = $base_wb",
591 []>;
592
593def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
594 (ins t2addrmode_imm8:$addr),
595 AddrModeT2_i8, IndexModePre,
596 "ldrsh", " $dst, $addr!", "$addr.base = $base_wb",
597 []>;
598def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
599 (ins GPR:$base, t2am_imm8_offset:$offset),
600 AddrModeT2_i8, IndexModePost,
601 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
602 []>;
603
David Goodwin73b8f162009-06-30 22:11:34 +0000604// Store
Evan Chenge88d5ce2009-07-02 07:28:31 +0000605defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
606defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
607defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
David Goodwin73b8f162009-06-30 22:11:34 +0000608
David Goodwin6647cea2009-06-30 22:50:01 +0000609// Store doubleword
610let mayLoad = 1 in
611def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
612 "strd", " $src, $addr", []>;
613
David Goodwind1fa1202009-07-01 00:01:13 +0000614
615// Address computation and loads and stores in PIC mode.
616let isNotDuplicable = 1, AddedComplexity = 10 in {
617let canFoldAsLoad = 1 in
618def t2PICLDR : T2I_picld<"ldr", UnOpFrag<(load node:$Src)>>;
619
620def t2PICLDRH : T2I_picld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
621def t2PICLDRB : T2I_picld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
622def t2PICLDRSH : T2I_picld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
623def t2PICLDRSB : T2I_picld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
624
625def t2PICSTR : T2I_picst<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
626def t2PICSTRH : T2I_picst<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
627def t2PICSTRB : T2I_picst<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
628} // isNotDuplicable = 1, AddedComplexity = 10
629
Evan Cheng9cb9e672009-06-27 02:26:13 +0000630//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000631// Move Instructions.
632//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000633
Evan Chengf49810c2009-06-23 17:48:47 +0000634let neverHasSideEffects = 1 in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000635def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src),
636 "mov", " $dst, $src", []>;
Evan Chengf49810c2009-06-23 17:48:47 +0000637
Evan Chenga67efd12009-06-23 19:39:13 +0000638let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin83b35932009-06-26 16:10:07 +0000639def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
640 "mov", " $dst, $src",
641 [(set GPR:$dst, t2_so_imm:$src)]>;
642
643let isReMaterializable = 1, isAsCheapAsAMove = 1 in
644def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src),
645 "movw", " $dst, $src",
646 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000647
Evan Chengf49810c2009-06-23 17:48:47 +0000648// FIXME: Also available in ARM mode.
Evan Cheng3850a6a2009-06-23 05:23:49 +0000649let Constraints = "$src = $dst" in
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000650def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
651 "movt", " $dst, $imm",
652 [(set GPR:$dst,
653 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000654
655//===----------------------------------------------------------------------===//
656// Arithmetic Instructions.
657//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000658
Evan Cheng8de898a2009-06-26 00:19:44 +0000659defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chenga67efd12009-06-23 19:39:13 +0000660defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000661
Evan Chengf49810c2009-06-23 17:48:47 +0000662// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Cheng8de898a2009-06-26 00:19:44 +0000663defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000664defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000665
Evan Cheng8de898a2009-06-26 00:19:44 +0000666defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
667defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000668
669// RSB, RSC
Evan Cheng1e249e32009-06-25 20:59:23 +0000670defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
671defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng62674222009-06-25 23:34:10 +0000672defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000673
674// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Cheng9cb9e672009-06-27 02:26:13 +0000675def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
676 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
677def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
678 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000679
680
Evan Chengf49810c2009-06-23 17:48:47 +0000681//===----------------------------------------------------------------------===//
Evan Chenga67efd12009-06-23 19:39:13 +0000682// Shift and rotate Instructions.
683//
684
685defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
686defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
687defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
688defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
689
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000690def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src),
691 "mov", " $dst, $src, rrx",
692 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000693
694//===----------------------------------------------------------------------===//
Evan Chengf49810c2009-06-23 17:48:47 +0000695// Bitwise Instructions.
696//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000697
Evan Cheng8de898a2009-06-26 00:19:44 +0000698defm t2AND : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
699defm t2ORR : T2I_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
700defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000701
Evan Chenga67efd12009-06-23 19:39:13 +0000702defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000703
Evan Cheng9cb9e672009-06-27 02:26:13 +0000704def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
705 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000706
Evan Chenga67efd12009-06-23 19:39:13 +0000707defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000708
Evan Cheng9cb9e672009-06-27 02:26:13 +0000709def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
710 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000711
David Goodwindcdaebc2009-06-26 23:13:13 +0000712// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
713let AddedComplexity = 1 in
Evan Chenga67efd12009-06-23 19:39:13 +0000714defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
Evan Chengf49810c2009-06-23 17:48:47 +0000715
Evan Cheng9cb9e672009-06-27 02:26:13 +0000716def : T2Pat<(t2_so_imm_not:$src),
717 (t2MVNi t2_so_imm_not:$src)>;
David Goodwin0919a912009-06-25 23:11:21 +0000718
Evan Chengf49810c2009-06-23 17:48:47 +0000719// A8.6.17 BFC - Bitfield clear
720// FIXME: Also available in ARM mode.
721let Constraints = "$src = $dst" in
722def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000723 "bfc", " $dst, $imm",
Evan Chengf49810c2009-06-23 17:48:47 +0000724 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
725
726// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
727
728//===----------------------------------------------------------------------===//
729// Multiply Instructions.
730//
Evan Cheng8de898a2009-06-26 00:19:44 +0000731let isCommutable = 1 in
Evan Chengf49810c2009-06-23 17:48:47 +0000732def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000733 "mul", " $dst, $a, $b",
Evan Chengf49810c2009-06-23 17:48:47 +0000734 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
735
736def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000737 "mla", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000738 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
739
740def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000741 "mls", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000742 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
743
744// FIXME: SMULL, etc.
745
746//===----------------------------------------------------------------------===//
747// Misc. Arithmetic Instructions.
748//
749
Evan Chengf49810c2009-06-23 17:48:47 +0000750def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000751 "clz", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000752 [(set GPR:$dst, (ctlz GPR:$src))]>;
753
754def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000755 "rev", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000756 [(set GPR:$dst, (bswap GPR:$src))]>;
757
758def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000759 "rev16", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000760 [(set GPR:$dst,
761 (or (and (srl GPR:$src, (i32 8)), 0xFF),
762 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
763 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
764 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
765
766/////
767/// A8.6.137 REVSH
768/////
769def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000770 "revsh", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000771 [(set GPR:$dst,
772 (sext_inreg
773 (or (srl (and GPR:$src, 0xFFFF), (i32 8)),
774 (shl GPR:$src, (i32 8))), i16))]>;
775
776// FIXME: PKHxx etc.
777
778//===----------------------------------------------------------------------===//
779// Comparison Instructions...
780//
781
782defm t2CMP : T2I_cmp_is<"cmp",
783 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000784defm t2CMPz : T2I_cmp_is<"cmp",
785 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000786
787defm t2CMN : T2I_cmp_is<"cmn",
788 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000789defm t2CMNz : T2I_cmp_is<"cmn",
790 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000791
Evan Cheng9cb9e672009-06-27 02:26:13 +0000792def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
793 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000794
David Goodwinc0309b42009-06-29 15:33:01 +0000795def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng9cb9e672009-06-27 02:26:13 +0000796 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000797
David Goodwinbaeb9112009-06-29 22:49:42 +0000798defm t2TST : T2I_cmp_is<"tst",
799 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
800defm t2TEQ : T2I_cmp_is<"teq",
801 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000802
803// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
804// Short range conditional branch. Looks awesome for loops. Need to figure
805// out how to use this one.
806
807// FIXME: Conditional moves
808
David Goodwin5e47a9a2009-06-30 18:04:13 +0000809//===----------------------------------------------------------------------===//
810// Control-Flow Instructions
811//
812
813let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
814let isPredicable = 1 in
815def t2B : T2XI<(outs), (ins brtarget:$target),
816 "b $target",
817 [(br bb:$target)]>;
818
David Goodwinc9a59b52009-06-30 19:50:22 +0000819let isNotDuplicable = 1, isIndirectBranch = 1 in {
820def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
821 "mov pc, $target \n$jt",
822 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
823
824def t2BR_JTm :
825 T2JTI<(outs),
826 (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
827 "ldr pc, $target \n$jt",
828 [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
829 imm:$id)]>;
830
831def t2BR_JTadd :
832 T2JTI<(outs),
833 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
834 "add pc, $target, $idx \n$jt",
835 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
836} // isNotDuplicate, isIndirectBranch
837} // isBranch, isTerminator, isBarrier
David Goodwin5e47a9a2009-06-30 18:04:13 +0000838
839// FIXME: should be able to write a pattern for ARMBrcond, but can't use
840// a two-value operand where a dag node expects two operands. :(
841let isBranch = 1, isTerminator = 1 in
842def t2Bcc : T2I<(outs), (ins brtarget:$target),
843 "b", " $target",
844 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000845
846//===----------------------------------------------------------------------===//
847// Non-Instruction Patterns
848//
849
Evan Chenga09b9ca2009-06-24 23:47:58 +0000850// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng9cb9e672009-06-27 02:26:13 +0000851def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
852def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
853def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
854 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000855
Evan Chengf49810c2009-06-23 17:48:47 +0000856// Large immediate handling.
857
Evan Cheng9cb9e672009-06-27 02:26:13 +0000858def : T2Pat<(i32 imm:$src),
859 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;