blob: a2aa1c03e937afb09b893d9b2505ce2f41e4a780 [file] [log] [blame]
Anton Korobeynikovf2e14752009-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 Korobeynikovac869fc2009-06-17 18:13:58 +000013
Evan Chengd5b67fa2009-07-10 01:54:42 +000014// IT block predicate field
15def it_pred : Operand<i32> {
16 let PrintMethod = "printPredicateOperand";
17}
18
19// IT block condition mask
20def it_mask : Operand<i32> {
21 let PrintMethod = "printThumbITMask";
22}
23
Evan Cheng1b2b3e22009-07-29 02:18:14 +000024// Table branch address
25def tb_addrmode : Operand<i32> {
26 let PrintMethod = "printTBAddrMode";
27}
28
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000029// Shifted operands. No register controlled shifts for Thumb2.
30// Note: We do not support rrx shifted operands yet.
31def t2_so_reg : Operand<i32>, // reg imm
Evan Cheng19bb7c72009-06-27 02:26:13 +000032 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000033 [shl,srl,sra,rotr]> {
Evan Cheng19bb7c72009-06-27 02:26:13 +000034 let PrintMethod = "printT2SOOperand";
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000035 let MIOperandInfo = (ops GPR, i32imm);
36}
37
Evan Cheng36173712009-06-23 17:48:47 +000038// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
39def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
Owen Anderson36e3a6e2009-08-11 20:47:22 +000040 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000041}]>;
42
Evan Cheng36173712009-06-23 17:48:47 +000043// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
44def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
Owen Anderson36e3a6e2009-08-11 20:47:22 +000045 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
Evan Cheng36173712009-06-23 17:48:47 +000046}]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000047
Evan Cheng36173712009-06-23 17:48:47 +000048// t2_so_imm - Match a 32-bit immediate operand, which is an
49// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
50// immediate splatted into multiple bytes of the word. t2_so_imm values are
51// represented in the imm field in the same 12-bit form that they are encoded
Jim Grosbach71465ac2009-11-24 00:20:27 +000052// into t2_so_imm instructions: the 8-bit immediate is the least significant
53// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
Evan Cheng36173712009-06-23 17:48:47 +000054def t2_so_imm : Operand<i32>,
55 PatLeaf<(imm), [{
Evan Cheng8be2a5b2009-07-08 21:03:57 +000056 return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
57}]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000058
Evan Cheng36173712009-06-23 17:48:47 +000059// t2_so_imm_not - Match an immediate that is a complement
60// of a t2_so_imm.
61def t2_so_imm_not : Operand<i32>,
62 PatLeaf<(imm), [{
Evan Cheng8be2a5b2009-07-08 21:03:57 +000063 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64}], t2_so_imm_not_XFORM>;
Evan Cheng36173712009-06-23 17:48:47 +000065
66// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
67def t2_so_imm_neg : Operand<i32>,
68 PatLeaf<(imm), [{
Evan Cheng8be2a5b2009-07-08 21:03:57 +000069 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
70}], t2_so_imm_neg_XFORM>;
Evan Cheng36173712009-06-23 17:48:47 +000071
Jim Grosbach1afc8e22009-10-21 20:44:34 +000072// Break t2_so_imm's up into two pieces. This handles immediates with up to 16
73// bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12]
74// to get the first/second pieces.
75def t2_so_imm2part : Operand<i32>,
76 PatLeaf<(imm), [{
77 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
78 }]> {
79}
80
81def t2_so_imm2part_1 : SDNodeXForm<imm, [{
82 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
83 return CurDAG->getTargetConstant(V, MVT::i32);
84}]>;
85
86def t2_so_imm2part_2 : SDNodeXForm<imm, [{
87 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
88 return CurDAG->getTargetConstant(V, MVT::i32);
89}]>;
90
Jim Grosbach66e70cd2009-11-23 20:35:53 +000091def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
92 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
93 }]> {
94}
95
96def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
97 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
98 return CurDAG->getTargetConstant(V, MVT::i32);
99}]>;
100
101def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
102 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
103 return CurDAG->getTargetConstant(V, MVT::i32);
104}]>;
105
Evan Chengf7f986d2009-06-23 19:39:13 +0000106/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
107def imm1_31 : PatLeaf<(i32 imm), [{
108 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
109}]>;
110
Evan Cheng36173712009-06-23 17:48:47 +0000111/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
Evan Cheng815c23a2009-08-07 00:34:42 +0000112def imm0_4095 : Operand<i32>,
113 PatLeaf<(i32 imm), [{
Evan Cheng36173712009-06-23 17:48:47 +0000114 return (uint32_t)N->getZExtValue() < 4096;
115}]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000116
117def imm0_4095_neg : PatLeaf<(i32 imm), [{
Evan Cheng36173712009-06-23 17:48:47 +0000118 return (uint32_t)(-N->getZExtValue()) < 4096;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000119}], imm_neg_XFORM>;
120
Evan Cheng809fadb2009-08-04 01:41:15 +0000121def imm0_255_neg : PatLeaf<(i32 imm), [{
122 return (uint32_t)(-N->getZExtValue()) < 255;
123}], imm_neg_XFORM>;
124
Evan Cheng532cdc52009-06-29 07:51:04 +0000125// Define Thumb2 specific addressing modes.
126
127// t2addrmode_imm12 := reg + imm12
128def t2addrmode_imm12 : Operand<i32>,
129 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
130 let PrintMethod = "printT2AddrModeImm12Operand";
131 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
132}
133
David Goodwin7938afc2009-07-24 00:16:18 +0000134// t2addrmode_imm8 := reg - imm8
Evan Cheng532cdc52009-06-29 07:51:04 +0000135def t2addrmode_imm8 : Operand<i32>,
136 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
137 let PrintMethod = "printT2AddrModeImm8Operand";
138 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
139}
140
Evan Cheng24f87d82009-07-03 00:06:39 +0000141def t2am_imm8_offset : Operand<i32>,
142 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
Evan Chenga90942e2009-07-02 07:28:31 +0000143 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
144}
145
Evan Cheng6bc67202009-07-09 22:21:59 +0000146// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
David Goodwin2af7ed82009-06-30 22:50:01 +0000147def t2addrmode_imm8s4 : Operand<i32>,
148 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
Evan Cheng6bc67202009-07-09 22:21:59 +0000149 let PrintMethod = "printT2AddrModeImm8s4Operand";
David Goodwin2af7ed82009-06-30 22:50:01 +0000150 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
151}
152
Evan Cheng4df2ea72009-07-09 20:40:44 +0000153// t2addrmode_so_reg := reg + (reg << imm2)
Evan Cheng532cdc52009-06-29 07:51:04 +0000154def t2addrmode_so_reg : Operand<i32>,
155 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
156 let PrintMethod = "printT2AddrModeSoRegOperand";
157 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
158}
159
160
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000161//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000162// Multiclass helpers...
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000163//
164
Evan Chengf7f986d2009-06-23 19:39:13 +0000165/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000166/// unary operation that produces a value. These are predicable and can be
167/// changed to modify CPSR.
Evan Chengf7f986d2009-06-23 19:39:13 +0000168multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
169 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000170 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
Evan Cheng08540a92009-10-27 00:08:59 +0000171 opc, "\t$dst, $src",
Evan Chengf7f986d2009-06-23 19:39:13 +0000172 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
173 let isAsCheapAsAMove = Cheap;
174 let isReMaterializable = ReMat;
175 }
176 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000177 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
Evan Cheng08540a92009-10-27 00:08:59 +0000178 opc, ".w\t$dst, $src",
Evan Chengf7f986d2009-06-23 19:39:13 +0000179 [(set GPR:$dst, (opnode GPR:$src))]>;
180 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000181 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000182 opc, ".w\t$dst, $src",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000183 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000184}
185
186/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000187// binary operation that produces a value. These are predicable and can be
188/// changed to modify CPSR.
David Goodwin87affb92009-07-27 23:34:12 +0000189multiclass T2I_bin_irs<string opc, PatFrag opnode,
190 bit Commutable = 0, string wide =""> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000191 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000192 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000193 opc, "\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000194 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000195 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000196 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000197 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
Evan Chengbdd679a2009-06-26 00:19:44 +0000198 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
199 let isCommutable = Commutable;
200 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000201 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000202 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000203 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000204 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000205}
206
David Goodwin87affb92009-07-27 23:34:12 +0000207/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
208// the ".w" prefix to indicate that they are wide.
209multiclass T2I_bin_w_irs<string opc, PatFrag opnode, bit Commutable = 0> :
210 T2I_bin_irs<opc, opnode, Commutable, ".w">;
211
Evan Chengd4e2f052009-06-25 20:59:23 +0000212/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
213/// reversed. It doesn't define the 'rr' form since it's handled by its
214/// T2I_bin_irs counterpart.
215multiclass T2I_rbin_is<string opc, PatFrag opnode> {
Evan Cheng36173712009-06-23 17:48:47 +0000216 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000217 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000218 opc, ".w\t$dst, $rhs, $lhs",
Evan Cheng36173712009-06-23 17:48:47 +0000219 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
220 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000221 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000222 opc, "\t$dst, $rhs, $lhs",
Evan Cheng36173712009-06-23 17:48:47 +0000223 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
224}
225
Evan Chengf7f986d2009-06-23 19:39:13 +0000226/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000227/// instruction modifies the CPSR register.
228let Defs = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000229multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000230 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000231 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000232 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000233 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000234 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000235 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000236 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
Evan Chengbdd679a2009-06-26 00:19:44 +0000237 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
238 let isCommutable = Commutable;
239 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000240 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000241 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000242 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000243 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000244}
245}
246
Evan Chengf7f986d2009-06-23 19:39:13 +0000247/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
248/// patterns for a binary operation that produces a value.
Evan Chengbdd679a2009-06-26 00:19:44 +0000249multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
Evan Cheng36173712009-06-23 17:48:47 +0000250 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000251 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000252 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000253 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000254 // 12-bit imm
David Goodwin236ccb52009-08-19 18:00:44 +0000255 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000256 !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000257 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000258 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000259 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000260 opc, ".w\t$dst, $lhs, $rhs",
Evan Chengbdd679a2009-06-26 00:19:44 +0000261 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
262 let isCommutable = Commutable;
263 }
Evan Cheng36173712009-06-23 17:48:47 +0000264 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000265 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000266 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000267 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000268}
269
Jim Grosbach71465ac2009-11-24 00:20:27 +0000270/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
271/// for a binary operation that produces a value and use and define the carry
272/// bit. It's not predicable.
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000273let Uses = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000274multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000275 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000276 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000277 opc, "\t$dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000278 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000279 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000280 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000281 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000282 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000283 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000284 Requires<[IsThumb2, CarryDefIsUnused]> {
Evan Chengbdd679a2009-06-26 00:19:44 +0000285 let isCommutable = Commutable;
286 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000287 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000288 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000289 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000290 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000291 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000292 // Carry setting variants
293 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000294 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000295 !strconcat(opc, "s\t$dst, $lhs, $rhs"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000296 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000297 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000298 let Defs = [CPSR];
299 }
300 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000301 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000302 !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000303 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000304 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000305 let Defs = [CPSR];
Evan Chengbdd679a2009-06-26 00:19:44 +0000306 let isCommutable = Commutable;
307 }
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000308 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000309 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000310 !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000311 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000312 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000313 let Defs = [CPSR];
Evan Chengbdd679a2009-06-26 00:19:44 +0000314 }
Evan Cheng36173712009-06-23 17:48:47 +0000315}
316}
317
David Goodwin2f6f1132009-07-27 16:31:55 +0000318/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
Evan Chengd4e2f052009-06-25 20:59:23 +0000319let Defs = [CPSR] in {
320multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
Evan Cheng36173712009-06-23 17:48:47 +0000321 // shifted imm
Evan Cheng6dadbee2009-08-10 02:37:24 +0000322 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
David Goodwin236ccb52009-08-19 18:00:44 +0000323 IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000324 !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"),
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000325 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000326 // shifted register
Evan Cheng6dadbee2009-08-10 02:37:24 +0000327 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
David Goodwin236ccb52009-08-19 18:00:44 +0000328 IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000329 !strconcat(opc, "${s}\t$dst, $rhs, $lhs"),
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000330 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000331}
332}
333
Evan Chengf7f986d2009-06-23 19:39:13 +0000334/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
335// rotate operation that produces a value.
336multiclass T2I_sh_ir<string opc, PatFrag opnode> {
337 // 5-bit imm
David Goodwin236ccb52009-08-19 18:00:44 +0000338 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000339 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000340 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000341 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000342 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr,
Evan Cheng08540a92009-10-27 00:08:59 +0000343 opc, ".w\t$dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000344 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000345}
Evan Cheng36173712009-06-23 17:48:47 +0000346
David Goodwin236ccb52009-08-19 18:00:44 +0000347/// T2I_cmp_is - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
Evan Chengf7f986d2009-06-23 19:39:13 +0000348/// patterns. Similar to T2I_bin_irs except the instruction does not produce
Evan Cheng36173712009-06-23 17:48:47 +0000349/// a explicit result, only implicitly set CPSR.
David Goodwin97eb10c2009-07-20 22:13:31 +0000350let Defs = [CPSR] in {
Evan Cheng36173712009-06-23 17:48:47 +0000351multiclass T2I_cmp_is<string opc, PatFrag opnode> {
352 // shifted imm
David Goodwin236ccb52009-08-19 18:00:44 +0000353 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
Evan Cheng08540a92009-10-27 00:08:59 +0000354 opc, ".w\t$lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000355 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000356 // register
David Goodwin236ccb52009-08-19 18:00:44 +0000357 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
Evan Cheng08540a92009-10-27 00:08:59 +0000358 opc, ".w\t$lhs, $rhs",
Evan Chengf7f986d2009-06-23 19:39:13 +0000359 [(opnode GPR:$lhs, GPR:$rhs)]>;
Evan Cheng36173712009-06-23 17:48:47 +0000360 // shifted register
David Goodwin236ccb52009-08-19 18:00:44 +0000361 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000362 opc, ".w\t$lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000363 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000364}
365}
366
Evan Cheng503be112009-06-30 02:15:48 +0000367/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
368multiclass T2I_ld<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000369 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
Evan Cheng08540a92009-10-27 00:08:59 +0000370 opc, ".w\t$dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000371 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000372 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
Evan Cheng08540a92009-10-27 00:08:59 +0000373 opc, "\t$dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000374 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000375 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
Evan Cheng08540a92009-10-27 00:08:59 +0000376 opc, ".w\t$dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000377 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000378 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
Evan Cheng08540a92009-10-27 00:08:59 +0000379 opc, ".w\t$dst, $addr",
Evan Cheng326d7242009-10-31 03:39:36 +0000380 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
381 let isReMaterializable = 1;
382 }
Evan Cheng503be112009-06-30 02:15:48 +0000383}
384
David Goodwinbab5da12009-06-30 22:11:34 +0000385/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
386multiclass T2I_st<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000387 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
Evan Cheng08540a92009-10-27 00:08:59 +0000388 opc, ".w\t$src, $addr",
David Goodwinbab5da12009-06-30 22:11:34 +0000389 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000390 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
Evan Cheng08540a92009-10-27 00:08:59 +0000391 opc, "\t$src, $addr",
David Goodwinbab5da12009-06-30 22:11:34 +0000392 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000393 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
Evan Cheng08540a92009-10-27 00:08:59 +0000394 opc, ".w\t$src, $addr",
David Goodwinbab5da12009-06-30 22:11:34 +0000395 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
396}
397
David Goodwin5811e5c2009-07-01 00:01:13 +0000398/// T2I_picld - Defines the PIC load pattern.
399class T2I_picld<string opc, PatFrag opnode> :
David Goodwin236ccb52009-08-19 18:00:44 +0000400 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi,
Evan Cheng08540a92009-10-27 00:08:59 +0000401 !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr",
David Goodwin5811e5c2009-07-01 00:01:13 +0000402 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
403
404/// T2I_picst - Defines the PIC store pattern.
405class T2I_picst<string opc, PatFrag opnode> :
David Goodwin236ccb52009-08-19 18:00:44 +0000406 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer,
Evan Cheng08540a92009-10-27 00:08:59 +0000407 !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr",
David Goodwin5811e5c2009-07-01 00:01:13 +0000408 [(opnode GPR:$src, addrmodepc:$addr)]>;
409
Evan Cheng0f994ed2009-07-03 01:43:10 +0000410
411/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
412/// register and one whose operand is a register rotated by 8/16/24.
413multiclass T2I_unary_rrot<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000414 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng08540a92009-10-27 00:08:59 +0000415 opc, ".w\t$dst, $src",
David Goodwin236ccb52009-08-19 18:00:44 +0000416 [(set GPR:$dst, (opnode GPR:$src))]>;
417 def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000418 opc, ".w\t$dst, $src, ror $rot",
David Goodwin236ccb52009-08-19 18:00:44 +0000419 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>;
Evan Cheng0f994ed2009-07-03 01:43:10 +0000420}
421
422/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
423/// register and one whose operand is a register rotated by 8/16/24.
424multiclass T2I_bin_rrot<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000425 def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
Evan Cheng08540a92009-10-27 00:08:59 +0000426 opc, "\t$dst, $LHS, $RHS",
Evan Cheng0f994ed2009-07-03 01:43:10 +0000427 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>;
428 def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
Evan Cheng08540a92009-10-27 00:08:59 +0000429 IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
Evan Cheng0f994ed2009-07-03 01:43:10 +0000430 [(set GPR:$dst, (opnode GPR:$LHS,
431 (rotr GPR:$RHS, rot_imm:$rot)))]>;
432}
433
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000434//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000435// Instructions
436//===----------------------------------------------------------------------===//
437
438//===----------------------------------------------------------------------===//
Evan Cheng41799702009-06-24 23:47:58 +0000439// Miscellaneous Instructions.
440//
441
Evan Cheng41799702009-06-24 23:47:58 +0000442// LEApcrel - Load a pc-relative address into a register without offending the
443// assembler.
David Goodwin236ccb52009-08-19 18:00:44 +0000444def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000445 "adr$p.w\t$dst, #$label", []>;
Evan Cheng41799702009-06-24 23:47:58 +0000446
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000447def t2LEApcrelJT : T2XI<(outs GPR:$dst),
Bob Wilson30ff4492009-08-21 21:58:55 +0000448 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
Evan Cheng08540a92009-10-27 00:08:59 +0000449 "adr$p.w\t$dst, #${label}_${id}", []>;
Evan Cheng41799702009-06-24 23:47:58 +0000450
Evan Cheng815c23a2009-08-07 00:34:42 +0000451// ADD r, sp, {so_imm|i12}
David Goodwin236ccb52009-08-19 18:00:44 +0000452def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000453 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []>;
David Goodwin236ccb52009-08-19 18:00:44 +0000454def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000455 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000456
457// ADD r, sp, so_reg
David Goodwin236ccb52009-08-19 18:00:44 +0000458def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +0000459 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000460
461// SUB r, sp, {so_imm|i12}
David Goodwin236ccb52009-08-19 18:00:44 +0000462def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000463 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []>;
David Goodwin236ccb52009-08-19 18:00:44 +0000464def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000465 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000466
467// SUB r, sp, so_reg
David Goodwin236ccb52009-08-19 18:00:44 +0000468def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
469 IIC_iALUsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000470 "sub", "\t$dst, $sp, $rhs", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000471
472
473// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
Dan Gohman30afe012009-10-29 18:10:34 +0000474let usesCustomInserter = 1 in { // Expanded after instruction selection.
Evan Cheng815c23a2009-08-07 00:34:42 +0000475def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000476 NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000477def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
Evan Cheng08540a92009-10-27 00:08:59 +0000478 NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
Evan Cheng815c23a2009-08-07 00:34:42 +0000479def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +0000480 NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
Dan Gohman30afe012009-10-29 18:10:34 +0000481} // usesCustomInserter
Evan Cheng815c23a2009-08-07 00:34:42 +0000482
483
Evan Cheng41799702009-06-24 23:47:58 +0000484//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000485// Load / store Instructions.
486//
487
Evan Cheng532cdc52009-06-29 07:51:04 +0000488// Load
Evan Cheng2f6bfd42009-11-20 19:57:15 +0000489let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
Evan Cheng503be112009-06-30 02:15:48 +0000490defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000491
Evan Cheng503be112009-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 Cheng532cdc52009-06-29 07:51:04 +0000495
Evan Cheng503be112009-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 Cheng532cdc52009-06-29 07:51:04 +0000499
Evan Cheng7c8d5ea2009-10-01 08:22:27 +0000500let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
Evan Cheng503be112009-06-30 02:15:48 +0000501// Load doubleword
Evan Cheng340684f2009-09-27 09:46:04 +0000502def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2),
503 (ins t2addrmode_imm8s4:$addr),
Evan Cheng08540a92009-10-27 00:08:59 +0000504 IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
Evan Cheng340684f2009-09-27 09:46:04 +0000505def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2),
506 (ins i32imm:$addr), IIC_iLoadi,
Evan Cheng08540a92009-10-27 00:08:59 +0000507 "ldrd", "\t$dst1, $addr", []>;
Evan Cheng503be112009-06-30 02:15:48 +0000508}
509
510// zextload i1 -> zextload i8
511def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
512 (t2LDRBi12 t2addrmode_imm12:$addr)>;
513def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
514 (t2LDRBi8 t2addrmode_imm8:$addr)>;
515def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
516 (t2LDRBs t2addrmode_so_reg:$addr)>;
517def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
518 (t2LDRBpci tconstpool:$addr)>;
519
520// extload -> zextload
521// FIXME: Reduce the number of patterns by legalizing extload to zextload
522// earlier?
523def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
524 (t2LDRBi12 t2addrmode_imm12:$addr)>;
525def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
526 (t2LDRBi8 t2addrmode_imm8:$addr)>;
527def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
528 (t2LDRBs t2addrmode_so_reg:$addr)>;
529def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
530 (t2LDRBpci tconstpool:$addr)>;
531
532def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
533 (t2LDRBi12 t2addrmode_imm12:$addr)>;
534def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
535 (t2LDRBi8 t2addrmode_imm8:$addr)>;
536def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
537 (t2LDRBs t2addrmode_so_reg:$addr)>;
538def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
539 (t2LDRBpci tconstpool:$addr)>;
540
541def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
542 (t2LDRHi12 t2addrmode_imm12:$addr)>;
543def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
544 (t2LDRHi8 t2addrmode_imm8:$addr)>;
545def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
546 (t2LDRHs t2addrmode_so_reg:$addr)>;
547def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
548 (t2LDRHpci tconstpool:$addr)>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000549
Evan Chenga90942e2009-07-02 07:28:31 +0000550// Indexed loads
Evan Chengd72edde2009-07-03 00:08:19 +0000551let mayLoad = 1 in {
Evan Chenga90942e2009-07-02 07:28:31 +0000552def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
553 (ins t2addrmode_imm8:$addr),
David Goodwin236ccb52009-08-19 18:00:44 +0000554 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000555 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000556 []>;
557
558def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
559 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000560 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000561 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000562 []>;
563
564def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
565 (ins t2addrmode_imm8:$addr),
David Goodwin236ccb52009-08-19 18:00:44 +0000566 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000567 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000568 []>;
569def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
570 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000571 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000572 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000573 []>;
574
575def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
576 (ins t2addrmode_imm8:$addr),
David Goodwin236ccb52009-08-19 18:00:44 +0000577 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000578 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000579 []>;
580def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
581 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000582 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000583 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
Evan Chenga90942e2009-07-02 07:28:31 +0000584 []>;
585
Evan Cheng40995c92009-07-02 23:16:11 +0000586def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
587 (ins t2addrmode_imm8:$addr),
David Goodwin236ccb52009-08-19 18:00:44 +0000588 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000589 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
Evan Cheng40995c92009-07-02 23:16:11 +0000590 []>;
591def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
592 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000593 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000594 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
Evan Cheng40995c92009-07-02 23:16:11 +0000595 []>;
596
597def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
598 (ins t2addrmode_imm8:$addr),
David Goodwin236ccb52009-08-19 18:00:44 +0000599 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000600 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
Evan Cheng40995c92009-07-02 23:16:11 +0000601 []>;
602def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
603 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000604 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000605 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
Evan Cheng40995c92009-07-02 23:16:11 +0000606 []>;
Evan Chengd72edde2009-07-03 00:08:19 +0000607}
Evan Cheng40995c92009-07-02 23:16:11 +0000608
David Goodwinbab5da12009-06-30 22:11:34 +0000609// Store
Evan Chenga90942e2009-07-02 07:28:31 +0000610defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
611defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
612defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
David Goodwinbab5da12009-06-30 22:11:34 +0000613
David Goodwin2af7ed82009-06-30 22:50:01 +0000614// Store doubleword
Evan Cheng7c8d5ea2009-10-01 08:22:27 +0000615let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
Evan Cheng340684f2009-09-27 09:46:04 +0000616def t2STRDi8 : T2Ii8s4<(outs),
617 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
Evan Cheng08540a92009-10-27 00:08:59 +0000618 IIC_iStorer, "strd", "\t$src1, $addr", []>;
David Goodwin2af7ed82009-06-30 22:50:01 +0000619
Evan Cheng24f87d82009-07-03 00:06:39 +0000620// Indexed stores
621def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb),
622 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000623 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000624 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000625 [(set GPR:$base_wb,
626 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
627
628def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
629 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000630 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000631 "str", "\t$src, [$base], $offset", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000632 [(set GPR:$base_wb,
Jim Grosbach71465ac2009-11-24 00:20:27 +0000633 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
Evan Cheng24f87d82009-07-03 00:06:39 +0000634
635def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb),
636 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000637 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000638 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000639 [(set GPR:$base_wb,
640 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
641
642def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
643 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000644 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000645 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000646 [(set GPR:$base_wb,
647 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
648
649def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb),
650 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000651 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000652 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000653 [(set GPR:$base_wb,
654 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
655
656def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
657 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwin236ccb52009-08-19 18:00:44 +0000658 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
Evan Cheng08540a92009-10-27 00:08:59 +0000659 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
Evan Cheng24f87d82009-07-03 00:06:39 +0000660 [(set GPR:$base_wb,
661 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
662
David Goodwin5811e5c2009-07-01 00:01:13 +0000663
Evan Cheng6bc67202009-07-09 22:21:59 +0000664// FIXME: ldrd / strd pre / post variants
Evan Cheng2832edf2009-07-03 00:18:36 +0000665
666//===----------------------------------------------------------------------===//
667// Load / store multiple Instructions.
668//
669
Evan Cheng7c8d5ea2009-10-01 08:22:27 +0000670let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
Evan Cheng2832edf2009-07-03 00:18:36 +0000671def t2LDM : T2XI<(outs),
Evan Chengb43a20e2009-10-01 01:33:39 +0000672 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
Evan Cheng08540a92009-10-27 00:08:59 +0000673 IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>;
Evan Cheng2832edf2009-07-03 00:18:36 +0000674
Evan Cheng7c8d5ea2009-10-01 08:22:27 +0000675let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
Evan Cheng2832edf2009-07-03 00:18:36 +0000676def t2STM : T2XI<(outs),
Evan Chengb43a20e2009-10-01 01:33:39 +0000677 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
Evan Cheng08540a92009-10-27 00:08:59 +0000678 IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>;
Evan Cheng2832edf2009-07-03 00:18:36 +0000679
Evan Cheng19bb7c72009-06-27 02:26:13 +0000680//===----------------------------------------------------------------------===//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000681// Move Instructions.
682//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000683
Evan Cheng36173712009-06-23 17:48:47 +0000684let neverHasSideEffects = 1 in
David Goodwin236ccb52009-08-19 18:00:44 +0000685def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
Evan Cheng08540a92009-10-27 00:08:59 +0000686 "mov", ".w\t$dst, $src", []>;
Evan Cheng36173712009-06-23 17:48:47 +0000687
Evan Cheng16c012d2009-09-28 09:14:39 +0000688// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
689let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
David Goodwin236ccb52009-08-19 18:00:44 +0000690def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
Evan Cheng08540a92009-10-27 00:08:59 +0000691 "mov", ".w\t$dst, $src",
David Goodwin2dbffd42009-06-26 16:10:07 +0000692 [(set GPR:$dst, t2_so_imm:$src)]>;
693
694let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin236ccb52009-08-19 18:00:44 +0000695def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
Evan Cheng08540a92009-10-27 00:08:59 +0000696 "movw", "\t$dst, $src",
David Goodwin2dbffd42009-06-26 16:10:07 +0000697 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Cheng36173712009-06-23 17:48:47 +0000698
Evan Cheng42e6ce92009-06-23 05:23:49 +0000699let Constraints = "$src = $dst" in
Evan Cheng16c012d2009-09-28 09:14:39 +0000700def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
Evan Cheng08540a92009-10-27 00:08:59 +0000701 "movt", "\t$dst, $imm",
Evan Cheng16c012d2009-09-28 09:14:39 +0000702 [(set GPR:$dst,
703 (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000704
Evan Cheng89ef2852009-10-21 08:15:52 +0000705def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
706
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000707//===----------------------------------------------------------------------===//
Evan Cheng0f994ed2009-07-03 01:43:10 +0000708// Extend Instructions.
709//
710
711// Sign extenders
712
713defm t2SXTB : T2I_unary_rrot<"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
714defm t2SXTH : T2I_unary_rrot<"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
715
716defm t2SXTAB : T2I_bin_rrot<"sxtab",
717 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
718defm t2SXTAH : T2I_bin_rrot<"sxtah",
719 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
720
721// TODO: SXT(A){B|H}16
722
723// Zero extenders
724
725let AddedComplexity = 16 in {
726defm t2UXTB : T2I_unary_rrot<"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
727defm t2UXTH : T2I_unary_rrot<"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
728defm t2UXTB16 : T2I_unary_rrot<"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
729
730def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
731 (t2UXTB16r_rot GPR:$Src, 24)>;
732def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
733 (t2UXTB16r_rot GPR:$Src, 8)>;
734
735defm t2UXTAB : T2I_bin_rrot<"uxtab",
Jim Grosbach71465ac2009-11-24 00:20:27 +0000736 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
Evan Cheng0f994ed2009-07-03 01:43:10 +0000737defm t2UXTAH : T2I_bin_rrot<"uxtah",
Jim Grosbach71465ac2009-11-24 00:20:27 +0000738 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
Evan Cheng0f994ed2009-07-03 01:43:10 +0000739}
740
741//===----------------------------------------------------------------------===//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000742// Arithmetic Instructions.
743//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000744
Evan Chengbdd679a2009-06-26 00:19:44 +0000745defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000746defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000747
Evan Cheng36173712009-06-23 17:48:47 +0000748// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Chengbdd679a2009-06-26 00:19:44 +0000749defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Chengd4e2f052009-06-25 20:59:23 +0000750defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000751
Evan Chengbdd679a2009-06-26 00:19:44 +0000752defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
753defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +0000754
David Goodwin3bc1afe2009-07-27 16:39:05 +0000755// RSB
Evan Chengd4e2f052009-06-25 20:59:23 +0000756defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
757defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +0000758
759// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Cheng809fadb2009-08-04 01:41:15 +0000760let AddedComplexity = 1 in
761def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
762 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
Evan Cheng19bb7c72009-06-27 02:26:13 +0000763def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
764 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
765def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
766 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000767
768
Evan Cheng36173712009-06-23 17:48:47 +0000769//===----------------------------------------------------------------------===//
Evan Chengf7f986d2009-06-23 19:39:13 +0000770// Shift and rotate Instructions.
771//
772
773defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
774defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
775defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
776defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
777
David Goodwin02b0e352009-09-01 18:32:09 +0000778let Uses = [CPSR] in {
David Goodwin236ccb52009-08-19 18:00:44 +0000779def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000780 "rrx", "\t$dst, $src",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000781 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
David Goodwin02b0e352009-09-01 18:32:09 +0000782}
Evan Chengf7f986d2009-06-23 19:39:13 +0000783
David Goodwin7cdd24c2009-07-28 17:06:49 +0000784let Defs = [CPSR] in {
David Goodwin236ccb52009-08-19 18:00:44 +0000785def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000786 "lsrs.w\t$dst, $src, #1",
David Goodwin7cdd24c2009-07-28 17:06:49 +0000787 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
David Goodwin236ccb52009-08-19 18:00:44 +0000788def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
Evan Cheng08540a92009-10-27 00:08:59 +0000789 "asrs.w\t$dst, $src, #1",
David Goodwin7cdd24c2009-07-28 17:06:49 +0000790 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
791}
792
Evan Chengf7f986d2009-06-23 19:39:13 +0000793//===----------------------------------------------------------------------===//
Evan Cheng36173712009-06-23 17:48:47 +0000794// Bitwise Instructions.
795//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000796
David Goodwin87affb92009-07-27 23:34:12 +0000797defm t2AND : T2I_bin_w_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
798defm t2ORR : T2I_bin_w_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
799defm t2EOR : T2I_bin_w_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Evan Cheng36173712009-06-23 17:48:47 +0000800
David Goodwin87affb92009-07-27 23:34:12 +0000801defm t2BIC : T2I_bin_w_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Cheng36173712009-06-23 17:48:47 +0000802
Evan Cheng36173712009-06-23 17:48:47 +0000803let Constraints = "$src = $dst" in
David Goodwin236ccb52009-08-19 18:00:44 +0000804def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
David Goodwin9a8ec822009-11-02 17:28:36 +0000805 IIC_iUNAsi, "bfc", "\t$dst, $imm",
Evan Cheng36173712009-06-23 17:48:47 +0000806 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
807
Sandeep Patelbb4648a2009-10-13 18:59:48 +0000808def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
Evan Cheng08540a92009-10-27 00:08:59 +0000809 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []>;
Sandeep Patelbb4648a2009-10-13 18:59:48 +0000810
811def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
Evan Cheng08540a92009-10-27 00:08:59 +0000812 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []>;
Sandeep Patelbb4648a2009-10-13 18:59:48 +0000813
Evan Cheng36173712009-06-23 17:48:47 +0000814// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
815
David Goodwin481216a2009-07-30 21:51:41 +0000816defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Cheng299ee652009-07-06 22:23:46 +0000817
818// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
819let AddedComplexity = 1 in
820defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
821
822
823def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
824 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
825
Evan Cheng04f40fa2009-08-01 06:13:52 +0000826// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwin481216a2009-07-30 21:51:41 +0000827def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
Evan Cheng04f40fa2009-08-01 06:13:52 +0000828 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
Evan Chengf9e5b5e2009-08-12 01:56:42 +0000829 Requires<[IsThumb2]>;
Evan Cheng299ee652009-07-06 22:23:46 +0000830
831def : T2Pat<(t2_so_imm_not:$src),
832 (t2MVNi t2_so_imm_not:$src)>;
833
Evan Cheng36173712009-06-23 17:48:47 +0000834//===----------------------------------------------------------------------===//
835// Multiply Instructions.
836//
Evan Chengbdd679a2009-06-26 00:19:44 +0000837let isCommutable = 1 in
David Goodwin236ccb52009-08-19 18:00:44 +0000838def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000839 "mul", "\t$dst, $a, $b",
Evan Cheng36173712009-06-23 17:48:47 +0000840 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
841
David Goodwin236ccb52009-08-19 18:00:44 +0000842def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
Evan Cheng08540a92009-10-27 00:08:59 +0000843 "mla", "\t$dst, $a, $b, $c",
Evan Cheng36173712009-06-23 17:48:47 +0000844 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
845
David Goodwin236ccb52009-08-19 18:00:44 +0000846def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
Evan Cheng08540a92009-10-27 00:08:59 +0000847 "mls", "\t$dst, $a, $b, $c",
Evan Cheng36173712009-06-23 17:48:47 +0000848 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
849
Evan Chenga5626262009-07-07 01:17:28 +0000850// Extra precision multiplies with low / high results
851let neverHasSideEffects = 1 in {
852let isCommutable = 1 in {
David Goodwin236ccb52009-08-19 18:00:44 +0000853def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
Evan Cheng08540a92009-10-27 00:08:59 +0000854 "smull", "\t$ldst, $hdst, $a, $b", []>;
Evan Chenga5626262009-07-07 01:17:28 +0000855
David Goodwin236ccb52009-08-19 18:00:44 +0000856def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
Evan Cheng08540a92009-10-27 00:08:59 +0000857 "umull", "\t$ldst, $hdst, $a, $b", []>;
Evan Chenga5626262009-07-07 01:17:28 +0000858}
859
860// Multiply + accumulate
David Goodwin236ccb52009-08-19 18:00:44 +0000861def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng08540a92009-10-27 00:08:59 +0000862 "smlal", "\t$ldst, $hdst, $a, $b", []>;
Evan Chenga5626262009-07-07 01:17:28 +0000863
David Goodwin236ccb52009-08-19 18:00:44 +0000864def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng08540a92009-10-27 00:08:59 +0000865 "umlal", "\t$ldst, $hdst, $a, $b", []>;
Evan Chenga5626262009-07-07 01:17:28 +0000866
David Goodwin236ccb52009-08-19 18:00:44 +0000867def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng08540a92009-10-27 00:08:59 +0000868 "umaal", "\t$ldst, $hdst, $a, $b", []>;
Evan Chenga5626262009-07-07 01:17:28 +0000869} // neverHasSideEffects
870
871// Most significant word multiply
David Goodwin236ccb52009-08-19 18:00:44 +0000872def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000873 "smmul", "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000874 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
875
David Goodwin236ccb52009-08-19 18:00:44 +0000876def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
Evan Cheng08540a92009-10-27 00:08:59 +0000877 "smmla", "\t$dst, $a, $b, $c",
Evan Chenga5626262009-07-07 01:17:28 +0000878 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>;
879
880
David Goodwin236ccb52009-08-19 18:00:44 +0000881def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
Evan Cheng08540a92009-10-27 00:08:59 +0000882 "smmls", "\t$dst, $a, $b, $c",
Evan Chenga5626262009-07-07 01:17:28 +0000883 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>;
884
885multiclass T2I_smul<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000886 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000887 !strconcat(opc, "bb"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000888 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
889 (sext_inreg GPR:$b, i16)))]>;
890
David Goodwin236ccb52009-08-19 18:00:44 +0000891 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000892 !strconcat(opc, "bt"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000893 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
894 (sra GPR:$b, (i32 16))))]>;
895
David Goodwin236ccb52009-08-19 18:00:44 +0000896 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000897 !strconcat(opc, "tb"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000898 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
899 (sext_inreg GPR:$b, i16)))]>;
900
David Goodwin236ccb52009-08-19 18:00:44 +0000901 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
Evan Cheng08540a92009-10-27 00:08:59 +0000902 !strconcat(opc, "tt"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000903 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
904 (sra GPR:$b, (i32 16))))]>;
905
David Goodwin236ccb52009-08-19 18:00:44 +0000906 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
Evan Cheng08540a92009-10-27 00:08:59 +0000907 !strconcat(opc, "wb"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000908 [(set GPR:$dst, (sra (opnode GPR:$a,
909 (sext_inreg GPR:$b, i16)), (i32 16)))]>;
910
David Goodwin236ccb52009-08-19 18:00:44 +0000911 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
Evan Cheng08540a92009-10-27 00:08:59 +0000912 !strconcat(opc, "wt"), "\t$dst, $a, $b",
Evan Chenga5626262009-07-07 01:17:28 +0000913 [(set GPR:$dst, (sra (opnode GPR:$a,
914 (sra GPR:$b, (i32 16))), (i32 16)))]>;
915}
916
917
918multiclass T2I_smla<string opc, PatFrag opnode> {
David Goodwin236ccb52009-08-19 18:00:44 +0000919 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000920 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000921 [(set GPR:$dst, (add GPR:$acc,
922 (opnode (sext_inreg GPR:$a, i16),
923 (sext_inreg GPR:$b, i16))))]>;
924
David Goodwin236ccb52009-08-19 18:00:44 +0000925 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000926 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000927 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
928 (sra GPR:$b, (i32 16)))))]>;
929
David Goodwin236ccb52009-08-19 18:00:44 +0000930 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000931 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000932 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
933 (sext_inreg GPR:$b, i16))))]>;
934
David Goodwin236ccb52009-08-19 18:00:44 +0000935 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000936 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000937 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
938 (sra GPR:$b, (i32 16)))))]>;
939
David Goodwin236ccb52009-08-19 18:00:44 +0000940 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000941 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000942 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
943 (sext_inreg GPR:$b, i16)), (i32 16))))]>;
944
David Goodwin236ccb52009-08-19 18:00:44 +0000945 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
Evan Cheng08540a92009-10-27 00:08:59 +0000946 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
Evan Chenga5626262009-07-07 01:17:28 +0000947 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
948 (sra GPR:$b, (i32 16))), (i32 16))))]>;
949}
950
951defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
952defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
953
954// TODO: Halfword multiple accumulate long: SMLAL<x><y>
955// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
956
Evan Cheng36173712009-06-23 17:48:47 +0000957
958//===----------------------------------------------------------------------===//
959// Misc. Arithmetic Instructions.
960//
961
David Goodwin236ccb52009-08-19 18:00:44 +0000962def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng08540a92009-10-27 00:08:59 +0000963 "clz", "\t$dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000964 [(set GPR:$dst, (ctlz GPR:$src))]>;
965
David Goodwin236ccb52009-08-19 18:00:44 +0000966def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng08540a92009-10-27 00:08:59 +0000967 "rev", ".w\t$dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000968 [(set GPR:$dst, (bswap GPR:$src))]>;
969
David Goodwin236ccb52009-08-19 18:00:44 +0000970def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng08540a92009-10-27 00:08:59 +0000971 "rev16", ".w\t$dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000972 [(set GPR:$dst,
973 (or (and (srl GPR:$src, (i32 8)), 0xFF),
974 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
975 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
976 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
977
David Goodwin236ccb52009-08-19 18:00:44 +0000978def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng08540a92009-10-27 00:08:59 +0000979 "revsh", ".w\t$dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000980 [(set GPR:$dst,
981 (sext_inreg
Evan Chengb4c98a32009-08-18 05:43:23 +0000982 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
Evan Cheng36173712009-06-23 17:48:47 +0000983 (shl GPR:$src, (i32 8))), i16))]>;
984
Evan Chengcd0ae282009-07-07 05:35:52 +0000985def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
Evan Cheng08540a92009-10-27 00:08:59 +0000986 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
Evan Chengcd0ae282009-07-07 05:35:52 +0000987 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
988 (and (shl GPR:$src2, (i32 imm:$shamt)),
989 0xFFFF0000)))]>;
990
991// Alternate cases for PKHBT where identities eliminate some nodes.
992def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
993 (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
994def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
995 (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
996
997def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
Evan Cheng08540a92009-10-27 00:08:59 +0000998 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
Evan Chengcd0ae282009-07-07 05:35:52 +0000999 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1000 (and (sra GPR:$src2, imm16_31:$shamt),
1001 0xFFFF)))]>;
1002
1003// Alternate cases for PKHTB where identities eliminate some nodes. Note that
1004// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1005def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1006 (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
1007def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
1008 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1009 (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Evan Cheng36173712009-06-23 17:48:47 +00001010
1011//===----------------------------------------------------------------------===//
1012// Comparison Instructions...
1013//
1014
Evan Cheng6dadbee2009-08-10 02:37:24 +00001015defm t2CMP : T2I_cmp_is<"cmp",
1016 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwin8bdcbb32009-06-29 15:33:01 +00001017defm t2CMPz : T2I_cmp_is<"cmp",
1018 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +00001019
Evan Cheng6dadbee2009-08-10 02:37:24 +00001020defm t2CMN : T2I_cmp_is<"cmn",
1021 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwin8bdcbb32009-06-29 15:33:01 +00001022defm t2CMNz : T2I_cmp_is<"cmn",
1023 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Cheng36173712009-06-23 17:48:47 +00001024
Evan Cheng19bb7c72009-06-27 02:26:13 +00001025def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
1026 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Cheng36173712009-06-23 17:48:47 +00001027
David Goodwin8bdcbb32009-06-29 15:33:01 +00001028def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng19bb7c72009-06-27 02:26:13 +00001029 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Cheng36173712009-06-23 17:48:47 +00001030
David Goodwinec52c892009-06-29 22:49:42 +00001031defm t2TST : T2I_cmp_is<"tst",
1032 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1033defm t2TEQ : T2I_cmp_is<"teq",
1034 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Cheng36173712009-06-23 17:48:47 +00001035
1036// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
1037// Short range conditional branch. Looks awesome for loops. Need to figure
1038// out how to use this one.
1039
Evan Cheng03137672009-07-07 20:39:03 +00001040
1041// Conditional moves
1042// FIXME: should be able to write a pattern for ARMcmov, but can't use
1043// a two-value operand where a dag node expects two operands. :(
David Goodwin236ccb52009-08-19 18:00:44 +00001044def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
Evan Cheng08540a92009-10-27 00:08:59 +00001045 "mov", ".w\t$dst, $true",
Evan Cheng03137672009-07-07 20:39:03 +00001046 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1047 RegConstraint<"$false = $dst">;
1048
David Goodwin236ccb52009-08-19 18:00:44 +00001049def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
Evan Cheng08540a92009-10-27 00:08:59 +00001050 IIC_iCMOVi, "mov", ".w\t$dst, $true",
Evan Cheng03137672009-07-07 20:39:03 +00001051[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1052 RegConstraint<"$false = $dst">;
Evan Cheng36173712009-06-23 17:48:47 +00001053
Evan Cheng7c002f32009-08-01 01:43:45 +00001054def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +00001055 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001056 RegConstraint<"$false = $dst">;
1057def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +00001058 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001059 RegConstraint<"$false = $dst">;
1060def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +00001061 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001062 RegConstraint<"$false = $dst">;
1063def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
Evan Cheng08540a92009-10-27 00:08:59 +00001064 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001065 RegConstraint<"$false = $dst">;
1066
David Goodwinf6154702009-06-30 18:04:13 +00001067//===----------------------------------------------------------------------===//
Jim Grosbachefbc1f02009-12-14 18:56:47 +00001068// Atomic operations intrinsics
1069//
1070
1071// memory barriers protect the atomic sequences
1072let hasSideEffects = 1 in {
1073def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
1074 Pseudo, NoItinerary,
1075 "dmb", "",
Jim Grosbach2d6e2492009-12-14 19:24:11 +00001076 [(ARMMemBarrier)]>,
1077 Requires<[IsThumb2]> {
Jim Grosbachefbc1f02009-12-14 18:56:47 +00001078 // FIXME: add support for options other than a full system DMB
1079}
1080
1081def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
1082 Pseudo, NoItinerary,
1083 "dsb", "",
Jim Grosbach2d6e2492009-12-14 19:24:11 +00001084 [(ARMSyncBarrier)]>,
1085 Requires<[IsThumb2]> {
Jim Grosbachefbc1f02009-12-14 18:56:47 +00001086 // FIXME: add support for options other than a full system DSB
1087}
1088}
1089
1090let mayLoad = 1 in {
1091def t2LDREXB : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1092 Size4Bytes, NoItinerary,
1093 "ldrexb", "\t$dest, [$ptr]", "",
1094 []>;
1095def t2LDREXH : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1096 Size4Bytes, NoItinerary,
1097 "ldrexh", "\t$dest, [$ptr]", "",
1098 []>;
1099def t2LDREX : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1100 Size4Bytes, NoItinerary,
1101 "ldrex", "\t$dest, [$ptr]", "",
1102 []>;
1103def t2LDREXD : Thumb2I<(outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1104 AddrModeNone, Size4Bytes, NoItinerary,
1105 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
1106 []>;
1107}
1108
1109let mayStore = 1 in {
1110def t2STREXB : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1111 AddrModeNone, Size4Bytes, NoItinerary,
1112 "strexb", "\t$success, $src, [$ptr]", "",
1113 []>;
1114def t2STREXH : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1115 AddrModeNone, Size4Bytes, NoItinerary,
1116 "strexh", "\t$success, $src, [$ptr]", "",
1117 []>;
1118def t2STREX : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1119 AddrModeNone, Size4Bytes, NoItinerary,
1120 "strex", "\t$success, $src, [$ptr]", "",
1121 []>;
1122def t2STREXD : Thumb2I<(outs GPR:$success),
1123 (ins GPR:$src, GPR:$src2, GPR:$ptr),
1124 AddrModeNone, Size4Bytes, NoItinerary,
1125 "strexd", "\t$success, $src, $src2, [$ptr]", "",
1126 []>;
1127}
1128
1129//===----------------------------------------------------------------------===//
David Goodwin41afec22009-07-08 16:09:28 +00001130// TLS Instructions
1131//
1132
1133// __aeabi_read_tp preserves the registers r1-r3.
1134let isCall = 1,
1135 Defs = [R0, R12, LR, CPSR] in {
David Goodwincfd67652009-08-06 16:52:47 +00001136 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
Evan Cheng08540a92009-10-27 00:08:59 +00001137 "bl\t__aeabi_read_tp",
David Goodwin41afec22009-07-08 16:09:28 +00001138 [(set R0, ARMthread_pointer)]>;
1139}
1140
1141//===----------------------------------------------------------------------===//
Jim Grosbachcc6e66a2009-08-11 19:42:21 +00001142// SJLJ Exception handling intrinsics
Jim Grosbach207a4ba2009-08-13 15:11:43 +00001143// eh_sjlj_setjmp() is an instruction sequence to store the return
Jim Grosbachcc6e66a2009-08-11 19:42:21 +00001144// address and save #0 in R0 for the non-longjmp case.
1145// Since by its nature we may be coming from some other function to get
1146// here, and we're using the stack frame for the containing function to
1147// save/restore registers, we can't keep anything live in regs across
1148// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1149// when we get here from a longjmp(). We force everthing out of registers
1150// except for our own input by listing the relevant registers in Defs. By
1151// doing so, we also cause the prologue/epilogue code to actively preserve
1152// all of the callee-saved resgisters, which is exactly what we want.
1153let Defs =
Jim Grosbach3990e392009-08-13 16:59:44 +00001154 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
1155 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
Jim Grosbachcc6e66a2009-08-11 19:42:21 +00001156 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1157 D31 ] in {
1158 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src),
1159 AddrModeNone, SizeSpecial, NoItinerary,
Evan Cheng08540a92009-10-27 00:08:59 +00001160 "str.w\tsp, [$src, #+8] @ eh_setjmp begin\n"
1161 "\tadr\tr12, 0f\n"
Evan Cheng276f8162009-11-03 23:13:34 +00001162 "\torr.w\tr12, r12, #1\n"
Evan Cheng08540a92009-10-27 00:08:59 +00001163 "\tstr.w\tr12, [$src, #+4]\n"
1164 "\tmovs\tr0, #0\n"
1165 "\tb\t1f\n"
1166 "0:\tmovs\tr0, #1 @ eh_setjmp end\n"
Jim Grosbachdd4f75b2009-08-13 15:12:16 +00001167 "1:", "",
Jim Grosbachcc6e66a2009-08-11 19:42:21 +00001168 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1169}
1170
1171
1172
1173//===----------------------------------------------------------------------===//
David Goodwinf6154702009-06-30 18:04:13 +00001174// Control-Flow Instructions
1175//
1176
Evan Chengad877c82009-07-09 22:58:39 +00001177// FIXME: remove when we have a way to marking a MI with these properties.
1178// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
1179// operand list.
1180// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Cheng7c8d5ea2009-10-01 08:22:27 +00001181let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1182 hasExtraDefRegAllocReq = 1 in
Evan Chengad877c82009-07-09 22:58:39 +00001183 def t2LDM_RET : T2XI<(outs),
Evan Chengb43a20e2009-10-01 01:33:39 +00001184 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
Evan Cheng08540a92009-10-27 00:08:59 +00001185 IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
Evan Chengad877c82009-07-09 22:58:39 +00001186 []>;
1187
David Goodwinf6154702009-06-30 18:04:13 +00001188let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1189let isPredicable = 1 in
David Goodwincfd67652009-08-06 16:52:47 +00001190def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng08540a92009-10-27 00:08:59 +00001191 "b.w\t$target",
David Goodwinf6154702009-06-30 18:04:13 +00001192 [(br bb:$target)]>;
1193
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001194let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng6e2ebc92009-07-25 00:33:29 +00001195def t2BR_JT :
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001196 T2JTI<(outs),
1197 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
Evan Cheng08540a92009-10-27 00:08:59 +00001198 IIC_Br, "mov\tpc, $target\n$jt",
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001199 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
1200
Evan Cheng04f40fa2009-08-01 06:13:52 +00001201// FIXME: Add a non-pc based case that can be predicated.
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001202def t2TBB :
Evan Cheng04f40fa2009-08-01 06:13:52 +00001203 T2JTI<(outs),
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001204 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
Evan Cheng08540a92009-10-27 00:08:59 +00001205 IIC_Br, "tbb\t$index\n$jt", []>;
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001206
1207def t2TBH :
Evan Cheng04f40fa2009-08-01 06:13:52 +00001208 T2JTI<(outs),
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001209 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
Evan Cheng08540a92009-10-27 00:08:59 +00001210 IIC_Br, "tbh\t$index\n$jt", []>;
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001211} // isNotDuplicable, isIndirectBranch
1212
David Goodwin13d2f4e2009-06-30 19:50:22 +00001213} // isBranch, isTerminator, isBarrier
David Goodwinf6154702009-06-30 18:04:13 +00001214
1215// FIXME: should be able to write a pattern for ARMBrcond, but can't use
1216// a two-value operand where a dag node expects two operands. :(
1217let isBranch = 1, isTerminator = 1 in
David Goodwincfd67652009-08-06 16:52:47 +00001218def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng08540a92009-10-27 00:08:59 +00001219 "b", ".w\t$target",
David Goodwinf6154702009-06-30 18:04:13 +00001220 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Cheng36173712009-06-23 17:48:47 +00001221
Evan Chengd5b67fa2009-07-10 01:54:42 +00001222
1223// IT block
1224def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
David Goodwin236ccb52009-08-19 18:00:44 +00001225 AddrModeNone, Size2Bytes, IIC_iALUx,
Evan Cheng08540a92009-10-27 00:08:59 +00001226 "it$mask\t$cc", "", []>;
Evan Chengd5b67fa2009-07-10 01:54:42 +00001227
Evan Cheng36173712009-06-23 17:48:47 +00001228//===----------------------------------------------------------------------===//
1229// Non-Instruction Patterns
1230//
1231
Jim Grosbach1afc8e22009-10-21 20:44:34 +00001232// Two piece so_imms.
1233def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
1234 (t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1235 (t2_so_imm2part_2 imm:$RHS))>;
1236def : T2Pat<(xor GPR:$LHS, t2_so_imm2part:$RHS),
1237 (t2EORri (t2EORri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1238 (t2_so_imm2part_2 imm:$RHS))>;
1239def : T2Pat<(add GPR:$LHS, t2_so_imm2part:$RHS),
1240 (t2ADDri (t2ADDri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
1241 (t2_so_imm2part_2 imm:$RHS))>;
Jim Grosbach66e70cd2009-11-23 20:35:53 +00001242def : T2Pat<(add GPR:$LHS, t2_so_neg_imm2part:$RHS),
1243 (t2SUBri (t2SUBri GPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
1244 (t2_so_neg_imm2part_2 imm:$RHS))>;
Jim Grosbach1afc8e22009-10-21 20:44:34 +00001245
Evan Cheng16c012d2009-09-28 09:14:39 +00001246// 32-bit immediate using movw + movt.
1247// This is a single pseudo instruction to make it re-materializable. Remove
1248// when we can do generalized remat.
1249let isReMaterializable = 1 in
1250def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
Evan Cheng08540a92009-10-27 00:08:59 +00001251 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}",
Evan Cheng16c012d2009-09-28 09:14:39 +00001252 [(set GPR:$dst, (i32 imm:$src))]>;
Evan Cheng7921e582009-11-06 23:52:48 +00001253
Anton Korobeynikova414f362009-11-24 00:44:37 +00001254// ConstantPool, GlobalAddress, and JumpTable
1255def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
1256 Requires<[IsThumb2, DontUseMovt]>;
1257def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
1258def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
1259 Requires<[IsThumb2, UseMovt]>;
1260
1261def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1262 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
1263
Evan Cheng7921e582009-11-06 23:52:48 +00001264// Pseudo instruction that combines ldr from constpool and add pc. This should
1265// be expanded into two instructions late to allow if-conversion and
1266// scheduling.
Evan Cheng2f6bfd42009-11-20 19:57:15 +00001267let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
Evan Cheng7921e582009-11-06 23:52:48 +00001268def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
1269 NoItinerary, "@ ldr.w\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
1270 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
1271 imm:$cp))]>,
1272 Requires<[IsThumb2]>;