blob: 31b8488afeab001b3ba18c87a302b0a9773f8e24 [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 Andersonac9de032009-08-10 22:56:29 +000040 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), EVT::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 Andersonac9de032009-08-10 22:56:29 +000045 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), EVT::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
52// into t2_so_imm instructions: the 8-bit immediate is the least significant bits
53// [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
54def 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
Evan Chengf7f986d2009-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 Cheng36173712009-06-23 17:48:47 +000077/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
Evan Cheng815c23a2009-08-07 00:34:42 +000078def imm0_4095 : Operand<i32>,
79 PatLeaf<(i32 imm), [{
Evan Cheng36173712009-06-23 17:48:47 +000080 return (uint32_t)N->getZExtValue() < 4096;
81}]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000082
83def imm0_4095_neg : PatLeaf<(i32 imm), [{
Evan Cheng36173712009-06-23 17:48:47 +000084 return (uint32_t)(-N->getZExtValue()) < 4096;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000085}], imm_neg_XFORM>;
86
Evan Cheng809fadb2009-08-04 01:41:15 +000087def imm0_255_neg : PatLeaf<(i32 imm), [{
88 return (uint32_t)(-N->getZExtValue()) < 255;
89}], imm_neg_XFORM>;
90
Evan Cheng36173712009-06-23 17:48:47 +000091/// imm0_65535 predicate - True if the 32-bit immediate is in the range
92/// [0.65535].
93def imm0_65535 : PatLeaf<(i32 imm), [{
94 return (uint32_t)N->getZExtValue() < 65536;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +000095}]>;
96
Evan Cheng36173712009-06-23 17:48:47 +000097/// Split a 32-bit immediate into two 16 bit parts.
98def t2_lo16 : SDNodeXForm<imm, [{
99 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
Owen Andersonac9de032009-08-10 22:56:29 +0000100 EVT::i32);
Evan Cheng36173712009-06-23 17:48:47 +0000101}]>;
102
103def t2_hi16 : SDNodeXForm<imm, [{
Owen Andersonac9de032009-08-10 22:56:29 +0000104 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, EVT::i32);
Evan Cheng36173712009-06-23 17:48:47 +0000105}]>;
106
107def t2_lo16AllZero : PatLeaf<(i32 imm), [{
108 // Returns true if all low 16-bits are 0.
109 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
110 }], t2_hi16>;
111
Evan Cheng19bb7c72009-06-27 02:26:13 +0000112
Evan Cheng532cdc52009-06-29 07:51:04 +0000113// Define Thumb2 specific addressing modes.
114
115// t2addrmode_imm12 := reg + imm12
116def t2addrmode_imm12 : Operand<i32>,
117 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
118 let PrintMethod = "printT2AddrModeImm12Operand";
119 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
120}
121
David Goodwin7938afc2009-07-24 00:16:18 +0000122// t2addrmode_imm8 := reg - imm8
Evan Cheng532cdc52009-06-29 07:51:04 +0000123def t2addrmode_imm8 : Operand<i32>,
124 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
125 let PrintMethod = "printT2AddrModeImm8Operand";
126 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
127}
128
Evan Cheng24f87d82009-07-03 00:06:39 +0000129def t2am_imm8_offset : Operand<i32>,
130 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
Evan Chenga90942e2009-07-02 07:28:31 +0000131 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
132}
133
Evan Cheng6bc67202009-07-09 22:21:59 +0000134// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
David Goodwin2af7ed82009-06-30 22:50:01 +0000135def t2addrmode_imm8s4 : Operand<i32>,
136 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
Evan Cheng6bc67202009-07-09 22:21:59 +0000137 let PrintMethod = "printT2AddrModeImm8s4Operand";
David Goodwin2af7ed82009-06-30 22:50:01 +0000138 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
139}
140
Evan Cheng4df2ea72009-07-09 20:40:44 +0000141// t2addrmode_so_reg := reg + (reg << imm2)
Evan Cheng532cdc52009-06-29 07:51:04 +0000142def t2addrmode_so_reg : Operand<i32>,
143 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
144 let PrintMethod = "printT2AddrModeSoRegOperand";
145 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
146}
147
148
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000149//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000150// Multiclass helpers...
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000151//
152
Evan Chengf7f986d2009-06-23 19:39:13 +0000153/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000154/// unary operation that produces a value. These are predicable and can be
155/// changed to modify CPSR.
Evan Chengf7f986d2009-06-23 19:39:13 +0000156multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
157 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000158 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000159 opc, " $dst, $src",
Evan Chengf7f986d2009-06-23 19:39:13 +0000160 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
161 let isAsCheapAsAMove = Cheap;
162 let isReMaterializable = ReMat;
163 }
164 // register
David Goodwincfd67652009-08-06 16:52:47 +0000165 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000166 opc, ".w $dst, $src",
Evan Chengf7f986d2009-06-23 19:39:13 +0000167 [(set GPR:$dst, (opnode GPR:$src))]>;
168 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000169 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000170 opc, ".w $dst, $src",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000171 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000172}
173
174/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000175// binary operation that produces a value. These are predicable and can be
176/// changed to modify CPSR.
David Goodwin87affb92009-07-27 23:34:12 +0000177multiclass T2I_bin_irs<string opc, PatFrag opnode,
178 bit Commutable = 0, string wide =""> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000179 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000180 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000181 opc, " $dst, $lhs, $rhs",
182 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000183 // register
David Goodwincfd67652009-08-06 16:52:47 +0000184 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin87affb92009-07-27 23:34:12 +0000185 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
Evan Chengbdd679a2009-06-26 00:19:44 +0000186 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
187 let isCommutable = Commutable;
188 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000189 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000190 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin87affb92009-07-27 23:34:12 +0000191 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000192 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000193}
194
David Goodwin87affb92009-07-27 23:34:12 +0000195/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
196// the ".w" prefix to indicate that they are wide.
197multiclass T2I_bin_w_irs<string opc, PatFrag opnode, bit Commutable = 0> :
198 T2I_bin_irs<opc, opnode, Commutable, ".w">;
199
Evan Chengd4e2f052009-06-25 20:59:23 +0000200/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
201/// reversed. It doesn't define the 'rr' form since it's handled by its
202/// T2I_bin_irs counterpart.
203multiclass T2I_rbin_is<string opc, PatFrag opnode> {
Evan Cheng36173712009-06-23 17:48:47 +0000204 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000205 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000206 opc, ".w $dst, $rhs, $lhs",
Evan Cheng36173712009-06-23 17:48:47 +0000207 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
208 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000209 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000210 opc, " $dst, $rhs, $lhs",
Evan Cheng36173712009-06-23 17:48:47 +0000211 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
212}
213
Evan Chengf7f986d2009-06-23 19:39:13 +0000214/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000215/// instruction modifies the CPSR register.
216let Defs = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000217multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000218 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000219 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000220 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000221 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000222 // register
David Goodwincfd67652009-08-06 16:52:47 +0000223 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000224 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Chengbdd679a2009-06-26 00:19:44 +0000225 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
226 let isCommutable = Commutable;
227 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000228 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000229 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000230 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000231 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000232}
233}
234
Evan Chengf7f986d2009-06-23 19:39:13 +0000235/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
236/// patterns for a binary operation that produces a value.
Evan Chengbdd679a2009-06-26 00:19:44 +0000237multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
Evan Cheng36173712009-06-23 17:48:47 +0000238 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000239 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000240 opc, ".w $dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000241 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000242 // 12-bit imm
Evan Cheng815c23a2009-08-07 00:34:42 +0000243 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000244 !strconcat(opc, "w"), " $dst, $lhs, $rhs",
245 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000246 // register
David Goodwincfd67652009-08-06 16:52:47 +0000247 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000248 opc, ".w $dst, $lhs, $rhs",
Evan Chengbdd679a2009-06-26 00:19:44 +0000249 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
250 let isCommutable = Commutable;
251 }
Evan Cheng36173712009-06-23 17:48:47 +0000252 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000253 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000254 opc, ".w $dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000255 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000256}
257
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000258/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Chengd4e2f052009-06-25 20:59:23 +0000259/// binary operation that produces a value and use and define the carry bit.
260/// It's not predicable.
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000261let Uses = [CPSR] in {
Evan Chengbdd679a2009-06-26 00:19:44 +0000262multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000263 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000264 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwin3536d172009-06-26 20:45:56 +0000265 opc, " $dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000266 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000267 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000268 // register
David Goodwincfd67652009-08-06 16:52:47 +0000269 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000270 opc, ".w $dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000271 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000272 Requires<[IsThumb2, CarryDefIsUnused]> {
Evan Chengbdd679a2009-06-26 00:19:44 +0000273 let isCommutable = Commutable;
274 }
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000275 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000276 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000277 opc, ".w $dst, $lhs, $rhs",
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000278 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000279 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000280 // Carry setting variants
281 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000282 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000283 !strconcat(opc, "s $dst, $lhs, $rhs"),
284 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000285 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000286 let Defs = [CPSR];
287 }
288 // register
David Goodwincfd67652009-08-06 16:52:47 +0000289 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000290 !strconcat(opc, "s.w $dst, $lhs, $rhs"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000291 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000292 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000293 let Defs = [CPSR];
Evan Chengbdd679a2009-06-26 00:19:44 +0000294 let isCommutable = Commutable;
295 }
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000296 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000297 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000298 !strconcat(opc, "s.w $dst, $lhs, $rhs"),
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000299 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengb1b2abc2009-07-02 06:38:40 +0000300 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng9b4d26f2009-06-25 23:34:10 +0000301 let Defs = [CPSR];
Evan Chengbdd679a2009-06-26 00:19:44 +0000302 }
Evan Cheng36173712009-06-23 17:48:47 +0000303}
304}
305
David Goodwin2f6f1132009-07-27 16:31:55 +0000306/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
Evan Chengd4e2f052009-06-25 20:59:23 +0000307let Defs = [CPSR] in {
308multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
Evan Cheng36173712009-06-23 17:48:47 +0000309 // shifted imm
Evan Cheng6dadbee2009-08-10 02:37:24 +0000310 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
311 IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000312 !strconcat(opc, "${s}.w $dst, $rhs, $lhs"),
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000313 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000314 // shifted register
Evan Cheng6dadbee2009-08-10 02:37:24 +0000315 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
316 IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000317 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
318 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
Evan Cheng36173712009-06-23 17:48:47 +0000319}
320}
321
Evan Chengf7f986d2009-06-23 19:39:13 +0000322/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
323// rotate operation that produces a value.
324multiclass T2I_sh_ir<string opc, PatFrag opnode> {
325 // 5-bit imm
David Goodwincfd67652009-08-06 16:52:47 +0000326 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000327 opc, ".w $dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000328 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000329 // register
David Goodwincfd67652009-08-06 16:52:47 +0000330 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000331 opc, ".w $dst, $lhs, $rhs",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000332 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000333}
Evan Cheng36173712009-06-23 17:48:47 +0000334
Evan Chengf7f986d2009-06-23 19:39:13 +0000335/// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
336/// patterns. Similar to T2I_bin_irs except the instruction does not produce
Evan Cheng36173712009-06-23 17:48:47 +0000337/// a explicit result, only implicitly set CPSR.
David Goodwin97eb10c2009-07-20 22:13:31 +0000338let Defs = [CPSR] in {
Evan Cheng36173712009-06-23 17:48:47 +0000339multiclass T2I_cmp_is<string opc, PatFrag opnode> {
340 // shifted imm
David Goodwincfd67652009-08-06 16:52:47 +0000341 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000342 opc, ".w $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000343 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000344 // register
David Goodwincfd67652009-08-06 16:52:47 +0000345 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000346 opc, ".w $lhs, $rhs",
Evan Chengf7f986d2009-06-23 19:39:13 +0000347 [(opnode GPR:$lhs, GPR:$rhs)]>;
Evan Cheng36173712009-06-23 17:48:47 +0000348 // shifted register
David Goodwincfd67652009-08-06 16:52:47 +0000349 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000350 opc, ".w $lhs, $rhs",
Evan Cheng36173712009-06-23 17:48:47 +0000351 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000352}
353}
354
Evan Cheng503be112009-06-30 02:15:48 +0000355/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
356multiclass T2I_ld<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000357 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoad,
David Goodwin2f6f1132009-07-27 16:31:55 +0000358 opc, ".w $dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000359 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000360 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoad,
Evan Cheng503be112009-06-30 02:15:48 +0000361 opc, " $dst, $addr",
362 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000363 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoad,
David Goodwin2f6f1132009-07-27 16:31:55 +0000364 opc, ".w $dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000365 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000366 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
David Goodwin2f6f1132009-07-27 16:31:55 +0000367 opc, ".w $dst, $addr",
Evan Cheng503be112009-06-30 02:15:48 +0000368 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>;
369}
370
David Goodwinbab5da12009-06-30 22:11:34 +0000371/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
372multiclass T2I_st<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000373 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStore,
David Goodwin2f6f1132009-07-27 16:31:55 +0000374 opc, ".w $src, $addr",
David Goodwinbab5da12009-06-30 22:11:34 +0000375 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
David Goodwincfd67652009-08-06 16:52:47 +0000376 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStore,
David Goodwinbab5da12009-06-30 22:11:34 +0000377 opc, " $src, $addr",
378 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
David Goodwincfd67652009-08-06 16:52:47 +0000379 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStore,
David Goodwin2f6f1132009-07-27 16:31:55 +0000380 opc, ".w $src, $addr",
David Goodwinbab5da12009-06-30 22:11:34 +0000381 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
382}
383
David Goodwin5811e5c2009-07-01 00:01:13 +0000384/// T2I_picld - Defines the PIC load pattern.
385class T2I_picld<string opc, PatFrag opnode> :
David Goodwincfd67652009-08-06 16:52:47 +0000386 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoad,
David Goodwin5811e5c2009-07-01 00:01:13 +0000387 !strconcat("${addr:label}:\n\t", opc), " $dst, $addr",
388 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
389
390/// T2I_picst - Defines the PIC store pattern.
391class T2I_picst<string opc, PatFrag opnode> :
David Goodwincfd67652009-08-06 16:52:47 +0000392 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStore,
David Goodwin5811e5c2009-07-01 00:01:13 +0000393 !strconcat("${addr:label}:\n\t", opc), " $src, $addr",
394 [(opnode GPR:$src, addrmodepc:$addr)]>;
395
Evan Cheng0f994ed2009-07-03 01:43:10 +0000396
397/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
398/// register and one whose operand is a register rotated by 8/16/24.
399multiclass T2I_unary_rrot<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000400 def r : T2I<(outs GPR:$dst), (ins GPR:$Src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000401 opc, ".w $dst, $Src",
Evan Cheng0f994ed2009-07-03 01:43:10 +0000402 [(set GPR:$dst, (opnode GPR:$Src))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000403 def r_rot : T2I<(outs GPR:$dst), (ins GPR:$Src, i32imm:$rot), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000404 opc, ".w $dst, $Src, ror $rot",
Evan Cheng0f994ed2009-07-03 01:43:10 +0000405 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>;
406}
407
408/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
409/// register and one whose operand is a register rotated by 8/16/24.
410multiclass T2I_bin_rrot<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000411 def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALU,
Evan Cheng0f994ed2009-07-03 01:43:10 +0000412 opc, " $dst, $LHS, $RHS",
413 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>;
414 def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
David Goodwincfd67652009-08-06 16:52:47 +0000415 IIC_iALU, opc, " $dst, $LHS, $RHS, ror $rot",
Evan Cheng0f994ed2009-07-03 01:43:10 +0000416 [(set GPR:$dst, (opnode GPR:$LHS,
417 (rotr GPR:$RHS, rot_imm:$rot)))]>;
418}
419
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000420//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000421// Instructions
422//===----------------------------------------------------------------------===//
423
424//===----------------------------------------------------------------------===//
Evan Cheng41799702009-06-24 23:47:58 +0000425// Miscellaneous Instructions.
426//
427
Evan Cheng41799702009-06-24 23:47:58 +0000428// LEApcrel - Load a pc-relative address into a register without offending the
429// assembler.
David Goodwincfd67652009-08-06 16:52:47 +0000430def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000431 "adr$p.w $dst, #$label", []>;
Evan Cheng41799702009-06-24 23:47:58 +0000432
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000433def t2LEApcrelJT : T2XI<(outs GPR:$dst),
Anton Korobeynikove2be3382009-08-08 23:10:41 +0000434 (ins i32imm:$label, lane_cst:$id, pred:$p), IIC_iALU,
435 "adr$p.w $dst, #${label}_${id}", []>;
Evan Cheng41799702009-06-24 23:47:58 +0000436
Evan Cheng815c23a2009-08-07 00:34:42 +0000437
438// ADD r, sp, {so_imm|i12}
439def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), IIC_iALU,
440 "add", ".w $dst, $sp, $imm", []>;
441def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), IIC_iALU,
442 "addw", " $dst, $sp, $imm", []>;
443
444// ADD r, sp, so_reg
445def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), IIC_iALU,
446 "add", ".w $dst, $sp, $rhs", []>;
447
448// SUB r, sp, {so_imm|i12}
449def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), IIC_iALU,
450 "sub", ".w $dst, $sp, $imm", []>;
451def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), IIC_iALU,
452 "subw", " $dst, $sp, $imm", []>;
453
454// SUB r, sp, so_reg
455def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), IIC_iALU,
456 "sub", " $dst, $sp, $rhs", []>;
457
458
459// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
460let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
461def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
462 NoItinerary, "@ sub.w $dst, $sp, $imm", []>;
463def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
464 NoItinerary, "@ subw $dst, $sp, $imm", []>;
465def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
466 NoItinerary, "@ sub $dst, $sp, $rhs", []>;
467} // usesCustomDAGSchedInserter
468
469
Evan Cheng41799702009-06-24 23:47:58 +0000470//===----------------------------------------------------------------------===//
Evan Cheng19bb7c72009-06-27 02:26:13 +0000471// Load / store Instructions.
472//
473
Evan Cheng532cdc52009-06-29 07:51:04 +0000474// Load
Evan Cheng503be112009-06-30 02:15:48 +0000475let canFoldAsLoad = 1 in
476defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000477
Evan Cheng503be112009-06-30 02:15:48 +0000478// Loads with zero extension
479defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
480defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000481
Evan Cheng503be112009-06-30 02:15:48 +0000482// Loads with sign extension
483defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
484defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000485
Evan Cheng503be112009-06-30 02:15:48 +0000486let mayLoad = 1 in {
487// Load doubleword
David Goodwin2af7ed82009-06-30 22:50:01 +0000488def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000489 IIC_iLoad, "ldrd", " $dst, $addr", []>;
490def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
Evan Cheng503be112009-06-30 02:15:48 +0000491 "ldrd", " $dst, $addr", []>;
492}
493
494// zextload i1 -> zextload i8
495def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
496 (t2LDRBi12 t2addrmode_imm12:$addr)>;
497def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
498 (t2LDRBi8 t2addrmode_imm8:$addr)>;
499def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
500 (t2LDRBs t2addrmode_so_reg:$addr)>;
501def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)),
502 (t2LDRBpci tconstpool:$addr)>;
503
504// extload -> zextload
505// FIXME: Reduce the number of patterns by legalizing extload to zextload
506// earlier?
507def : T2Pat<(extloadi1 t2addrmode_imm12:$addr),
508 (t2LDRBi12 t2addrmode_imm12:$addr)>;
509def : T2Pat<(extloadi1 t2addrmode_imm8:$addr),
510 (t2LDRBi8 t2addrmode_imm8:$addr)>;
511def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr),
512 (t2LDRBs t2addrmode_so_reg:$addr)>;
513def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)),
514 (t2LDRBpci tconstpool:$addr)>;
515
516def : T2Pat<(extloadi8 t2addrmode_imm12:$addr),
517 (t2LDRBi12 t2addrmode_imm12:$addr)>;
518def : T2Pat<(extloadi8 t2addrmode_imm8:$addr),
519 (t2LDRBi8 t2addrmode_imm8:$addr)>;
520def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr),
521 (t2LDRBs t2addrmode_so_reg:$addr)>;
522def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)),
523 (t2LDRBpci tconstpool:$addr)>;
524
525def : T2Pat<(extloadi16 t2addrmode_imm12:$addr),
526 (t2LDRHi12 t2addrmode_imm12:$addr)>;
527def : T2Pat<(extloadi16 t2addrmode_imm8:$addr),
528 (t2LDRHi8 t2addrmode_imm8:$addr)>;
529def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
530 (t2LDRHs t2addrmode_so_reg:$addr)>;
531def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
532 (t2LDRHpci tconstpool:$addr)>;
Evan Cheng532cdc52009-06-29 07:51:04 +0000533
Evan Chenga90942e2009-07-02 07:28:31 +0000534// Indexed loads
Evan Chengd72edde2009-07-03 00:08:19 +0000535let mayLoad = 1 in {
Evan Chenga90942e2009-07-02 07:28:31 +0000536def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
537 (ins t2addrmode_imm8:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000538 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000539 "ldr", " $dst, $addr!", "$addr.base = $base_wb",
540 []>;
541
542def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
543 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000544 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000545 "ldr", " $dst, [$base], $offset", "$base = $base_wb",
546 []>;
547
548def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
549 (ins t2addrmode_imm8:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000550 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000551 "ldrb", " $dst, $addr!", "$addr.base = $base_wb",
552 []>;
553def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
554 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000555 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000556 "ldrb", " $dst, [$base], $offset", "$base = $base_wb",
557 []>;
558
559def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
560 (ins t2addrmode_imm8:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000561 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000562 "ldrh", " $dst, $addr!", "$addr.base = $base_wb",
563 []>;
564def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
565 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000566 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenga90942e2009-07-02 07:28:31 +0000567 "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
568 []>;
569
Evan Cheng40995c92009-07-02 23:16:11 +0000570def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
571 (ins t2addrmode_imm8:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000572 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Cheng40995c92009-07-02 23:16:11 +0000573 "ldrsb", " $dst, $addr!", "$addr.base = $base_wb",
574 []>;
575def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
576 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000577 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Cheng40995c92009-07-02 23:16:11 +0000578 "ldrsb", " $dst, [$base], $offset", "$base = $base_wb",
579 []>;
580
581def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
582 (ins t2addrmode_imm8:$addr),
David Goodwincfd67652009-08-06 16:52:47 +0000583 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Cheng40995c92009-07-02 23:16:11 +0000584 "ldrsh", " $dst, $addr!", "$addr.base = $base_wb",
585 []>;
586def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
587 (ins GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000588 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Cheng40995c92009-07-02 23:16:11 +0000589 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
590 []>;
Evan Chengd72edde2009-07-03 00:08:19 +0000591}
Evan Cheng40995c92009-07-02 23:16:11 +0000592
David Goodwinbab5da12009-06-30 22:11:34 +0000593// Store
Evan Chenga90942e2009-07-02 07:28:31 +0000594defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
595defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
596defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
David Goodwinbab5da12009-06-30 22:11:34 +0000597
David Goodwin2af7ed82009-06-30 22:50:01 +0000598// Store doubleword
599let mayLoad = 1 in
Evan Cheng64cfb7f2009-08-11 08:47:46 +0000600def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
601 IIC_iStore, "strd", " $src, $addr", []>;
David Goodwin2af7ed82009-06-30 22:50:01 +0000602
Evan Cheng24f87d82009-07-03 00:06:39 +0000603// Indexed stores
604def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb),
605 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000606 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000607 "str", " $src, [$base, $offset]!", "$base = $base_wb",
608 [(set GPR:$base_wb,
609 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
610
611def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
612 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000613 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000614 "str", " $src, [$base], $offset", "$base = $base_wb",
615 [(set GPR:$base_wb,
616 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
617
618def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb),
619 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000620 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000621 "strh", " $src, [$base, $offset]!", "$base = $base_wb",
622 [(set GPR:$base_wb,
623 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
624
625def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
626 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000627 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000628 "strh", " $src, [$base], $offset", "$base = $base_wb",
629 [(set GPR:$base_wb,
630 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
631
632def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb),
633 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000634 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000635 "strb", " $src, [$base, $offset]!", "$base = $base_wb",
636 [(set GPR:$base_wb,
637 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
638
639def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
640 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
David Goodwincfd67652009-08-06 16:52:47 +0000641 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng24f87d82009-07-03 00:06:39 +0000642 "strb", " $src, [$base], $offset", "$base = $base_wb",
643 [(set GPR:$base_wb,
644 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
645
David Goodwin5811e5c2009-07-01 00:01:13 +0000646
Evan Cheng6bc67202009-07-09 22:21:59 +0000647// FIXME: ldrd / strd pre / post variants
Evan Cheng2832edf2009-07-03 00:18:36 +0000648
649//===----------------------------------------------------------------------===//
650// Load / store multiple Instructions.
651//
652
653let mayLoad = 1 in
654def t2LDM : T2XI<(outs),
655 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng9b531042009-08-07 21:19:10 +0000656 IIC_iLoad, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1", []>;
Evan Cheng2832edf2009-07-03 00:18:36 +0000657
658let mayStore = 1 in
659def t2STM : T2XI<(outs),
660 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
Evan Cheng9b531042009-08-07 21:19:10 +0000661 IIC_iStore, "stm${addr:submode}${p}${addr:wide} $addr, $src1", []>;
Evan Cheng2832edf2009-07-03 00:18:36 +0000662
Evan Cheng19bb7c72009-06-27 02:26:13 +0000663//===----------------------------------------------------------------------===//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000664// Move Instructions.
665//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000666
Evan Cheng36173712009-06-23 17:48:47 +0000667let neverHasSideEffects = 1 in
David Goodwincfd67652009-08-06 16:52:47 +0000668def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000669 "mov", ".w $dst, $src", []>;
Evan Cheng36173712009-06-23 17:48:47 +0000670
Evan Chengf7f986d2009-06-23 19:39:13 +0000671let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwincfd67652009-08-06 16:52:47 +0000672def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000673 "mov", ".w $dst, $src",
David Goodwin2dbffd42009-06-26 16:10:07 +0000674 [(set GPR:$dst, t2_so_imm:$src)]>;
675
676let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwincfd67652009-08-06 16:52:47 +0000677def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iALU,
David Goodwin2dbffd42009-06-26 16:10:07 +0000678 "movw", " $dst, $src",
679 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Cheng36173712009-06-23 17:48:47 +0000680
Evan Cheng36173712009-06-23 17:48:47 +0000681// FIXME: Also available in ARM mode.
Evan Cheng42e6ce92009-06-23 05:23:49 +0000682let Constraints = "$src = $dst" in
David Goodwincfd67652009-08-06 16:52:47 +0000683def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000684 "movt", " $dst, $imm",
685 [(set GPR:$dst,
686 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000687
688//===----------------------------------------------------------------------===//
Evan Cheng0f994ed2009-07-03 01:43:10 +0000689// Extend Instructions.
690//
691
692// Sign extenders
693
694defm t2SXTB : T2I_unary_rrot<"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
695defm t2SXTH : T2I_unary_rrot<"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
696
697defm t2SXTAB : T2I_bin_rrot<"sxtab",
698 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
699defm t2SXTAH : T2I_bin_rrot<"sxtah",
700 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
701
702// TODO: SXT(A){B|H}16
703
704// Zero extenders
705
706let AddedComplexity = 16 in {
707defm t2UXTB : T2I_unary_rrot<"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
708defm t2UXTH : T2I_unary_rrot<"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
709defm t2UXTB16 : T2I_unary_rrot<"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
710
711def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
712 (t2UXTB16r_rot GPR:$Src, 24)>;
713def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
714 (t2UXTB16r_rot GPR:$Src, 8)>;
715
716defm t2UXTAB : T2I_bin_rrot<"uxtab",
717 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
718defm t2UXTAH : T2I_bin_rrot<"uxtah",
719 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
720}
721
722//===----------------------------------------------------------------------===//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000723// Arithmetic Instructions.
724//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000725
Evan Chengbdd679a2009-06-26 00:19:44 +0000726defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000727defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000728
Evan Cheng36173712009-06-23 17:48:47 +0000729// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Chengbdd679a2009-06-26 00:19:44 +0000730defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Chengd4e2f052009-06-25 20:59:23 +0000731defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000732
Evan Chengbdd679a2009-06-26 00:19:44 +0000733defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
734defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +0000735
David Goodwin3bc1afe2009-07-27 16:39:05 +0000736// RSB
Evan Chengd4e2f052009-06-25 20:59:23 +0000737defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
738defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +0000739
740// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Cheng809fadb2009-08-04 01:41:15 +0000741let AddedComplexity = 1 in
742def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
743 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
Evan Cheng19bb7c72009-06-27 02:26:13 +0000744def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
745 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
746def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
747 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000748
749
Evan Cheng36173712009-06-23 17:48:47 +0000750//===----------------------------------------------------------------------===//
Evan Chengf7f986d2009-06-23 19:39:13 +0000751// Shift and rotate Instructions.
752//
753
754defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
755defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
756defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
757defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
758
David Goodwincfd67652009-08-06 16:52:47 +0000759def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin1f697672009-07-30 21:38:40 +0000760 "rrx", ".w $dst, $src",
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000761 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
Evan Chengf7f986d2009-06-23 19:39:13 +0000762
David Goodwin7cdd24c2009-07-28 17:06:49 +0000763let Defs = [CPSR] in {
David Goodwincfd67652009-08-06 16:52:47 +0000764def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin7cdd24c2009-07-28 17:06:49 +0000765 "lsrs.w $dst, $src, #1",
766 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000767def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin7cdd24c2009-07-28 17:06:49 +0000768 "asrs.w $dst, $src, #1",
769 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
770}
771
Evan Chengf7f986d2009-06-23 19:39:13 +0000772//===----------------------------------------------------------------------===//
Evan Cheng36173712009-06-23 17:48:47 +0000773// Bitwise Instructions.
774//
Anton Korobeynikovac869fc2009-06-17 18:13:58 +0000775
David Goodwin87affb92009-07-27 23:34:12 +0000776defm t2AND : T2I_bin_w_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
777defm t2ORR : T2I_bin_w_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
778defm t2EOR : T2I_bin_w_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Evan Cheng36173712009-06-23 17:48:47 +0000779
David Goodwin87affb92009-07-27 23:34:12 +0000780defm t2BIC : T2I_bin_w_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Cheng36173712009-06-23 17:48:47 +0000781
Evan Cheng36173712009-06-23 17:48:47 +0000782let Constraints = "$src = $dst" in
David Goodwincfd67652009-08-06 16:52:47 +0000783def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000784 "bfc", " $dst, $imm",
Evan Cheng36173712009-06-23 17:48:47 +0000785 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
786
787// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
788
Evan Cheng04f40fa2009-08-01 06:13:52 +0000789/*
David Goodwin481216a2009-07-30 21:51:41 +0000790defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Cheng04f40fa2009-08-01 06:13:52 +0000791*/
792// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwincfd67652009-08-06 16:52:47 +0000793def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng04f40fa2009-08-01 06:13:52 +0000794 "orn", " $dst, $lhs, $rhs",
795 [(set GPR:$dst, (or GPR:$lhs, (not t2_so_imm:$rhs)))]>,
796 Requires<[IsThumb2, IsNotDarwin]>;
797
David Goodwincfd67652009-08-06 16:52:47 +0000798def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
Evan Cheng04f40fa2009-08-01 06:13:52 +0000799 "orn", " $dst, $lhs, $rhs",
800 [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>;
David Goodwincfd67652009-08-06 16:52:47 +0000801def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
Evan Cheng04f40fa2009-08-01 06:13:52 +0000802 "orn", " $dst, $lhs, $rhs",
803 [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;
Evan Cheng299ee652009-07-06 22:23:46 +0000804
805// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
806let AddedComplexity = 1 in
807defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
808
809
810def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
811 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
812
Evan Cheng04f40fa2009-08-01 06:13:52 +0000813// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwin481216a2009-07-30 21:51:41 +0000814def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
Evan Cheng04f40fa2009-08-01 06:13:52 +0000815 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
816 Requires<[IsThumb2, IsNotDarwin]>;
Evan Cheng299ee652009-07-06 22:23:46 +0000817
818def : T2Pat<(t2_so_imm_not:$src),
819 (t2MVNi t2_so_imm_not:$src)>;
820
Evan Cheng36173712009-06-23 17:48:47 +0000821//===----------------------------------------------------------------------===//
822// Multiply Instructions.
823//
Evan Chengbdd679a2009-06-26 00:19:44 +0000824let isCommutable = 1 in
David Goodwincfd67652009-08-06 16:52:47 +0000825def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000826 "mul", " $dst, $a, $b",
Evan Cheng36173712009-06-23 17:48:47 +0000827 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
828
David Goodwincfd67652009-08-06 16:52:47 +0000829def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000830 "mla", " $dst, $a, $b, $c",
Evan Cheng36173712009-06-23 17:48:47 +0000831 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
832
David Goodwincfd67652009-08-06 16:52:47 +0000833def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000834 "mls", " $dst, $a, $b, $c",
Evan Cheng36173712009-06-23 17:48:47 +0000835 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
836
Evan Chenga5626262009-07-07 01:17:28 +0000837// Extra precision multiplies with low / high results
838let neverHasSideEffects = 1 in {
839let isCommutable = 1 in {
David Goodwincfd67652009-08-06 16:52:47 +0000840def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000841 "smull", " $ldst, $hdst, $a, $b", []>;
842
David Goodwincfd67652009-08-06 16:52:47 +0000843def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000844 "umull", " $ldst, $hdst, $a, $b", []>;
845}
846
847// Multiply + accumulate
David Goodwincfd67652009-08-06 16:52:47 +0000848def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000849 "smlal", " $ldst, $hdst, $a, $b", []>;
850
David Goodwincfd67652009-08-06 16:52:47 +0000851def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000852 "umlal", " $ldst, $hdst, $a, $b", []>;
853
David Goodwincfd67652009-08-06 16:52:47 +0000854def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000855 "umaal", " $ldst, $hdst, $a, $b", []>;
856} // neverHasSideEffects
857
858// Most significant word multiply
David Goodwincfd67652009-08-06 16:52:47 +0000859def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000860 "smmul", " $dst, $a, $b",
861 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
862
David Goodwincfd67652009-08-06 16:52:47 +0000863def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000864 "smmla", " $dst, $a, $b, $c",
865 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>;
866
867
David Goodwincfd67652009-08-06 16:52:47 +0000868def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000869 "smmls", " $dst, $a, $b, $c",
870 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>;
871
872multiclass T2I_smul<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000873 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000874 !strconcat(opc, "bb"), " $dst, $a, $b",
875 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
876 (sext_inreg GPR:$b, i16)))]>;
877
David Goodwincfd67652009-08-06 16:52:47 +0000878 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000879 !strconcat(opc, "bt"), " $dst, $a, $b",
880 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
881 (sra GPR:$b, (i32 16))))]>;
882
David Goodwincfd67652009-08-06 16:52:47 +0000883 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000884 !strconcat(opc, "tb"), " $dst, $a, $b",
885 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
886 (sext_inreg GPR:$b, i16)))]>;
887
David Goodwincfd67652009-08-06 16:52:47 +0000888 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000889 !strconcat(opc, "tt"), " $dst, $a, $b",
890 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
891 (sra GPR:$b, (i32 16))))]>;
892
David Goodwincfd67652009-08-06 16:52:47 +0000893 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000894 !strconcat(opc, "wb"), " $dst, $a, $b",
895 [(set GPR:$dst, (sra (opnode GPR:$a,
896 (sext_inreg GPR:$b, i16)), (i32 16)))]>;
897
David Goodwincfd67652009-08-06 16:52:47 +0000898 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000899 !strconcat(opc, "wt"), " $dst, $a, $b",
900 [(set GPR:$dst, (sra (opnode GPR:$a,
901 (sra GPR:$b, (i32 16))), (i32 16)))]>;
902}
903
904
905multiclass T2I_smla<string opc, PatFrag opnode> {
David Goodwincfd67652009-08-06 16:52:47 +0000906 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000907 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
908 [(set GPR:$dst, (add GPR:$acc,
909 (opnode (sext_inreg GPR:$a, i16),
910 (sext_inreg GPR:$b, i16))))]>;
911
David Goodwincfd67652009-08-06 16:52:47 +0000912 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000913 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
914 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
915 (sra GPR:$b, (i32 16)))))]>;
916
David Goodwincfd67652009-08-06 16:52:47 +0000917 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000918 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
919 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
920 (sext_inreg GPR:$b, i16))))]>;
921
David Goodwincfd67652009-08-06 16:52:47 +0000922 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000923 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
924 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
925 (sra GPR:$b, (i32 16)))))]>;
926
David Goodwincfd67652009-08-06 16:52:47 +0000927 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000928 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
929 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
930 (sext_inreg GPR:$b, i16)), (i32 16))))]>;
931
David Goodwincfd67652009-08-06 16:52:47 +0000932 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Chenga5626262009-07-07 01:17:28 +0000933 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
934 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
935 (sra GPR:$b, (i32 16))), (i32 16))))]>;
936}
937
938defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
939defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
940
941// TODO: Halfword multiple accumulate long: SMLAL<x><y>
942// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
943
Evan Cheng36173712009-06-23 17:48:47 +0000944
945//===----------------------------------------------------------------------===//
946// Misc. Arithmetic Instructions.
947//
948
David Goodwincfd67652009-08-06 16:52:47 +0000949def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
Evan Cheng3d92dfd2009-06-25 02:08:06 +0000950 "clz", " $dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000951 [(set GPR:$dst, (ctlz GPR:$src))]>;
952
David Goodwincfd67652009-08-06 16:52:47 +0000953def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000954 "rev", ".w $dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000955 [(set GPR:$dst, (bswap GPR:$src))]>;
956
David Goodwincfd67652009-08-06 16:52:47 +0000957def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000958 "rev16", ".w $dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000959 [(set GPR:$dst,
960 (or (and (srl GPR:$src, (i32 8)), 0xFF),
961 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
962 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
963 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
964
David Goodwincfd67652009-08-06 16:52:47 +0000965def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin2f6f1132009-07-27 16:31:55 +0000966 "revsh", ".w $dst, $src",
Evan Cheng36173712009-06-23 17:48:47 +0000967 [(set GPR:$dst,
968 (sext_inreg
969 (or (srl (and GPR:$src, 0xFFFF), (i32 8)),
970 (shl GPR:$src, (i32 8))), i16))]>;
971
Evan Chengcd0ae282009-07-07 05:35:52 +0000972def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
David Goodwincfd67652009-08-06 16:52:47 +0000973 IIC_iALU, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Chengcd0ae282009-07-07 05:35:52 +0000974 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
975 (and (shl GPR:$src2, (i32 imm:$shamt)),
976 0xFFFF0000)))]>;
977
978// Alternate cases for PKHBT where identities eliminate some nodes.
979def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
980 (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
981def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
982 (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
983
984def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
David Goodwincfd67652009-08-06 16:52:47 +0000985 IIC_iALU, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Chengcd0ae282009-07-07 05:35:52 +0000986 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
987 (and (sra GPR:$src2, imm16_31:$shamt),
988 0xFFFF)))]>;
989
990// Alternate cases for PKHTB where identities eliminate some nodes. Note that
991// a shift amount of 0 is *not legal* here, it is PKHBT instead.
992def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
993 (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
994def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
995 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
996 (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Evan Cheng36173712009-06-23 17:48:47 +0000997
998//===----------------------------------------------------------------------===//
999// Comparison Instructions...
1000//
1001
Evan Cheng6dadbee2009-08-10 02:37:24 +00001002defm t2CMP : T2I_cmp_is<"cmp",
1003 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwin8bdcbb32009-06-29 15:33:01 +00001004defm t2CMPz : T2I_cmp_is<"cmp",
1005 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Cheng36173712009-06-23 17:48:47 +00001006
Evan Cheng6dadbee2009-08-10 02:37:24 +00001007defm t2CMN : T2I_cmp_is<"cmn",
1008 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwin8bdcbb32009-06-29 15:33:01 +00001009defm t2CMNz : T2I_cmp_is<"cmn",
1010 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Cheng36173712009-06-23 17:48:47 +00001011
Evan Cheng19bb7c72009-06-27 02:26:13 +00001012def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
1013 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Cheng36173712009-06-23 17:48:47 +00001014
David Goodwin8bdcbb32009-06-29 15:33:01 +00001015def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng19bb7c72009-06-27 02:26:13 +00001016 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Cheng36173712009-06-23 17:48:47 +00001017
David Goodwinec52c892009-06-29 22:49:42 +00001018defm t2TST : T2I_cmp_is<"tst",
1019 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1020defm t2TEQ : T2I_cmp_is<"teq",
1021 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Cheng36173712009-06-23 17:48:47 +00001022
1023// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
1024// Short range conditional branch. Looks awesome for loops. Need to figure
1025// out how to use this one.
1026
Evan Cheng03137672009-07-07 20:39:03 +00001027
1028// Conditional moves
1029// FIXME: should be able to write a pattern for ARMcmov, but can't use
1030// a two-value operand where a dag node expects two operands. :(
David Goodwincfd67652009-08-06 16:52:47 +00001031def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iALU,
Evan Chengdec08242009-07-31 22:21:55 +00001032 "mov", ".w $dst, $true",
Evan Cheng03137672009-07-07 20:39:03 +00001033 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1034 RegConstraint<"$false = $dst">;
1035
David Goodwincfd67652009-08-06 16:52:47 +00001036def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), IIC_iALU,
Evan Chengdec08242009-07-31 22:21:55 +00001037 "mov", ".w $dst, $true",
Evan Cheng03137672009-07-07 20:39:03 +00001038[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1039 RegConstraint<"$false = $dst">;
Evan Cheng36173712009-06-23 17:48:47 +00001040
Evan Cheng7c002f32009-08-01 01:43:45 +00001041def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwincfd67652009-08-06 16:52:47 +00001042 IIC_iALU, "lsl", ".w $dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001043 RegConstraint<"$false = $dst">;
1044def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwincfd67652009-08-06 16:52:47 +00001045 IIC_iALU, "lsr", ".w $dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001046 RegConstraint<"$false = $dst">;
1047def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwincfd67652009-08-06 16:52:47 +00001048 IIC_iALU, "asr", ".w $dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001049 RegConstraint<"$false = $dst">;
1050def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwincfd67652009-08-06 16:52:47 +00001051 IIC_iALU, "ror", ".w $dst, $true, $rhs", []>,
Evan Cheng7c002f32009-08-01 01:43:45 +00001052 RegConstraint<"$false = $dst">;
1053
David Goodwinf6154702009-06-30 18:04:13 +00001054//===----------------------------------------------------------------------===//
David Goodwin41afec22009-07-08 16:09:28 +00001055// TLS Instructions
1056//
1057
1058// __aeabi_read_tp preserves the registers r1-r3.
1059let isCall = 1,
1060 Defs = [R0, R12, LR, CPSR] in {
David Goodwincfd67652009-08-06 16:52:47 +00001061 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
David Goodwin41afec22009-07-08 16:09:28 +00001062 "bl __aeabi_read_tp",
1063 [(set R0, ARMthread_pointer)]>;
1064}
1065
1066//===----------------------------------------------------------------------===//
Jim Grosbachcc6e66a2009-08-11 19:42:21 +00001067// SJLJ Exception handling intrinsics
1068// eh_sjlj_setjmp() is a three instruction sequence to store the return
1069// address and save #0 in R0 for the non-longjmp case.
1070// Since by its nature we may be coming from some other function to get
1071// here, and we're using the stack frame for the containing function to
1072// save/restore registers, we can't keep anything live in regs across
1073// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1074// when we get here from a longjmp(). We force everthing out of registers
1075// except for our own input by listing the relevant registers in Defs. By
1076// doing so, we also cause the prologue/epilogue code to actively preserve
1077// all of the callee-saved resgisters, which is exactly what we want.
1078let Defs =
1079 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1080 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1081 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1082 D31 ] in {
1083 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src),
1084 AddrModeNone, SizeSpecial, NoItinerary,
1085 "str.w sp, [$src, #+8] @ eh_setjmp begin\n"
1086 "\tadr ip, 0f\n"
1087 "\torr ip, #1\n"
1088 "\tstr.w ip, [$src, #+4]\n"
1089 "\tmovs r0, #0\n"
1090 "\tb 1f\n"
1091 "0:\tmovs r0, #1 @ eh_setjmp end\n"
1092 "1:\n", "",
1093 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1094}
1095
1096
1097
1098//===----------------------------------------------------------------------===//
David Goodwinf6154702009-06-30 18:04:13 +00001099// Control-Flow Instructions
1100//
1101
Evan Chengad877c82009-07-09 22:58:39 +00001102// FIXME: remove when we have a way to marking a MI with these properties.
1103// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
1104// operand list.
1105// FIXME: Should pc be an implicit operand like PICADD, etc?
1106let isReturn = 1, isTerminator = 1, mayLoad = 1 in
1107 def t2LDM_RET : T2XI<(outs),
1108 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng9b531042009-08-07 21:19:10 +00001109 IIC_iLoad, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1",
Evan Chengad877c82009-07-09 22:58:39 +00001110 []>;
1111
David Goodwinf6154702009-06-30 18:04:13 +00001112let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1113let isPredicable = 1 in
David Goodwincfd67652009-08-06 16:52:47 +00001114def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
David Goodwin2f6f1132009-07-27 16:31:55 +00001115 "b.w $target",
David Goodwinf6154702009-06-30 18:04:13 +00001116 [(br bb:$target)]>;
1117
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001118let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng6e2ebc92009-07-25 00:33:29 +00001119def t2BR_JT :
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001120 T2JTI<(outs),
1121 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwincfd67652009-08-06 16:52:47 +00001122 IIC_Br, "mov pc, $target\n$jt",
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001123 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
1124
Evan Cheng04f40fa2009-08-01 06:13:52 +00001125// FIXME: Add a non-pc based case that can be predicated.
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001126def t2TBB :
Evan Cheng04f40fa2009-08-01 06:13:52 +00001127 T2JTI<(outs),
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001128 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwincfd67652009-08-06 16:52:47 +00001129 IIC_Br, "tbb $index\n$jt", []>;
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001130
1131def t2TBH :
Evan Cheng04f40fa2009-08-01 06:13:52 +00001132 T2JTI<(outs),
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001133 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwincfd67652009-08-06 16:52:47 +00001134 IIC_Br, "tbh $index\n$jt", []>;
Evan Cheng1b2b3e22009-07-29 02:18:14 +00001135} // isNotDuplicable, isIndirectBranch
1136
David Goodwin13d2f4e2009-06-30 19:50:22 +00001137} // isBranch, isTerminator, isBarrier
David Goodwinf6154702009-06-30 18:04:13 +00001138
1139// FIXME: should be able to write a pattern for ARMBrcond, but can't use
1140// a two-value operand where a dag node expects two operands. :(
1141let isBranch = 1, isTerminator = 1 in
David Goodwincfd67652009-08-06 16:52:47 +00001142def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
David Goodwin2f6f1132009-07-27 16:31:55 +00001143 "b", ".w $target",
David Goodwinf6154702009-06-30 18:04:13 +00001144 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Cheng36173712009-06-23 17:48:47 +00001145
Evan Chengd5b67fa2009-07-10 01:54:42 +00001146
1147// IT block
1148def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
David Goodwincfd67652009-08-06 16:52:47 +00001149 AddrModeNone, Size2Bytes, IIC_iALU,
Evan Chengd5b67fa2009-07-10 01:54:42 +00001150 "it$mask $cc", "", []>;
1151
Evan Cheng36173712009-06-23 17:48:47 +00001152//===----------------------------------------------------------------------===//
1153// Non-Instruction Patterns
1154//
1155
Evan Cheng41799702009-06-24 23:47:58 +00001156// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng19bb7c72009-06-27 02:26:13 +00001157def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
1158def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
1159def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1160 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Cheng41799702009-06-24 23:47:58 +00001161
Evan Cheng36173712009-06-23 17:48:47 +00001162// Large immediate handling.
1163
Evan Cheng19bb7c72009-06-27 02:26:13 +00001164def : T2Pat<(i32 imm:$src),
1165 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;