blob: 5800a4304775d13a89d56d39e500ab2073c09fd5 [file] [log] [blame]
Anton Korobeynikovd4022c32009-05-29 23:41:08 +00001//===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the Thumb2 instruction set.
11//
12//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +000013
Evan Cheng06e16582009-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 Cheng5657c012009-07-29 02:18:14 +000024// Table branch address
25def tb_addrmode : Operand<i32> {
26 let PrintMethod = "printTBAddrMode";
27}
28
Anton Korobeynikov52237112009-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 Cheng9cb9e672009-06-27 02:26:13 +000032 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
Anton Korobeynikov52237112009-06-17 18:13:58 +000033 [shl,srl,sra,rotr]> {
Evan Cheng9cb9e672009-06-27 02:26:13 +000034 let PrintMethod = "printT2SOOperand";
Anton Korobeynikov52237112009-06-17 18:13:58 +000035 let MIOperandInfo = (ops GPR, i32imm);
36}
37
Evan Chengf49810c2009-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 Anderson825b72b2009-08-11 20:47:22 +000040 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
Anton Korobeynikov52237112009-06-17 18:13:58 +000041}]>;
42
Evan Chengf49810c2009-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 Anderson825b72b2009-08-11 20:47:22 +000045 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
Evan Chengf49810c2009-06-23 17:48:47 +000046}]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +000047
Evan Chengf49810c2009-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 Chenge7cbe412009-07-08 21:03:57 +000056 return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
57}]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +000058
Evan Chengf49810c2009-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 Chenge7cbe412009-07-08 21:03:57 +000063 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
64}], t2_so_imm_not_XFORM>;
Evan Chengf49810c2009-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 Chenge7cbe412009-07-08 21:03:57 +000069 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
70}], t2_so_imm_neg_XFORM>;
Evan Chengf49810c2009-06-23 17:48:47 +000071
Evan Chenga67efd12009-06-23 19:39:13 +000072/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
73def imm1_31 : PatLeaf<(i32 imm), [{
74 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
75}]>;
76
Evan Chengf49810c2009-06-23 17:48:47 +000077/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
Evan Cheng86198642009-08-07 00:34:42 +000078def imm0_4095 : Operand<i32>,
79 PatLeaf<(i32 imm), [{
Evan Chengf49810c2009-06-23 17:48:47 +000080 return (uint32_t)N->getZExtValue() < 4096;
81}]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +000082
83def imm0_4095_neg : PatLeaf<(i32 imm), [{
Evan Chengf49810c2009-06-23 17:48:47 +000084 return (uint32_t)(-N->getZExtValue()) < 4096;
Anton Korobeynikov52237112009-06-17 18:13:58 +000085}], imm_neg_XFORM>;
86
Evan Chengfa2ea1a2009-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 Chengf49810c2009-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 Korobeynikov52237112009-06-17 18:13:58 +000095}]>;
96
Evan Chengf49810c2009-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 Anderson825b72b2009-08-11 20:47:22 +0000100 MVT::i32);
Evan Chengf49810c2009-06-23 17:48:47 +0000101}]>;
102
103def t2_hi16 : SDNodeXForm<imm, [{
Owen Anderson825b72b2009-08-11 20:47:22 +0000104 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32);
Evan Chengf49810c2009-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 Cheng9cb9e672009-06-27 02:26:13 +0000112
Evan Cheng055b0312009-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 Goodwin5ff58b52009-07-24 00:16:18 +0000122// t2addrmode_imm8 := reg - imm8
Evan Cheng055b0312009-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 Cheng6d94f112009-07-03 00:06:39 +0000129def t2am_imm8_offset : Operand<i32>,
130 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
Evan Chenge88d5ce2009-07-02 07:28:31 +0000131 let PrintMethod = "printT2AddrModeImm8OffsetOperand";
132}
133
Evan Cheng5c874172009-07-09 22:21:59 +0000134// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
David Goodwin6647cea2009-06-30 22:50:01 +0000135def t2addrmode_imm8s4 : Operand<i32>,
136 ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
Evan Cheng5c874172009-07-09 22:21:59 +0000137 let PrintMethod = "printT2AddrModeImm8s4Operand";
David Goodwin6647cea2009-06-30 22:50:01 +0000138 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
139}
140
Evan Chengcba962d2009-07-09 20:40:44 +0000141// t2addrmode_so_reg := reg + (reg << imm2)
Evan Cheng055b0312009-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 Korobeynikov52237112009-06-17 18:13:58 +0000149//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000150// Multiclass helpers...
Anton Korobeynikov52237112009-06-17 18:13:58 +0000151//
152
Evan Chenga67efd12009-06-23 19:39:13 +0000153/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000154/// unary operation that produces a value. These are predicable and can be
155/// changed to modify CPSR.
Evan Chenga67efd12009-06-23 19:39:13 +0000156multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
157 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000158 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000159 opc, " $dst, $src",
Evan Chenga67efd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000165 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000166 opc, ".w $dst, $src",
Evan Chenga67efd12009-06-23 19:39:13 +0000167 [(set GPR:$dst, (opnode GPR:$src))]>;
168 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000169 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000170 opc, ".w $dst, $src",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000171 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
Evan Chenga67efd12009-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 Cheng0aa1d8c2009-06-25 02:08:06 +0000175// binary operation that produces a value. These are predicable and can be
176/// changed to modify CPSR.
David Goodwin1f096272009-07-27 23:34:12 +0000177multiclass T2I_bin_irs<string opc, PatFrag opnode,
178 bit Commutable = 0, string wide =""> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000179 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000180 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000181 opc, " $dst, $lhs, $rhs",
182 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000183 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000184 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin1f096272009-07-27 23:34:12 +0000185 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
Evan Cheng8de898a2009-06-26 00:19:44 +0000186 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
187 let isCommutable = Commutable;
188 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000189 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000190 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin1f096272009-07-27 23:34:12 +0000191 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000192 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000193}
194
David Goodwin1f096272009-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 Cheng1e249e32009-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 Chengf49810c2009-06-23 17:48:47 +0000204 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000205 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000206 opc, ".w $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000207 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
208 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000209 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000210 opc, " $dst, $rhs, $lhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000211 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
212}
213
Evan Chenga67efd12009-06-23 19:39:13 +0000214/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
Anton Korobeynikov52237112009-06-17 18:13:58 +0000215/// instruction modifies the CPSR register.
216let Defs = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000217multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000218 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000219 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000220 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000221 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000222 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000223 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000224 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000225 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
226 let isCommutable = Commutable;
227 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000228 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000229 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000230 !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000231 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000232}
233}
234
Evan Chenga67efd12009-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 Cheng8de898a2009-06-26 00:19:44 +0000237multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
Evan Chengf49810c2009-06-23 17:48:47 +0000238 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000239 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000240 opc, ".w $dst, $lhs, $rhs",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000241 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000242 // 12-bit imm
Evan Cheng86198642009-08-07 00:34:42 +0000243 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000244 !strconcat(opc, "w"), " $dst, $lhs, $rhs",
245 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000246 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000247 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000248 opc, ".w $dst, $lhs, $rhs",
Evan Cheng8de898a2009-06-26 00:19:44 +0000249 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
250 let isCommutable = Commutable;
251 }
Evan Chengf49810c2009-06-23 17:48:47 +0000252 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000253 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000254 opc, ".w $dst, $lhs, $rhs",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000255 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000256}
257
Evan Cheng62674222009-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 Cheng1e249e32009-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 Cheng62674222009-06-25 23:34:10 +0000261let Uses = [CPSR] in {
Evan Cheng8de898a2009-06-26 00:19:44 +0000262multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
Anton Korobeynikov52237112009-06-17 18:13:58 +0000263 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000264 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwin7ce720b2009-06-26 20:45:56 +0000265 opc, " $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000266 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000267 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000268 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000269 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000270 opc, ".w $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000271 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000272 Requires<[IsThumb2, CarryDefIsUnused]> {
Evan Cheng8de898a2009-06-26 00:19:44 +0000273 let isCommutable = Commutable;
274 }
Anton Korobeynikov52237112009-06-17 18:13:58 +0000275 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000276 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000277 opc, ".w $dst, $lhs, $rhs",
Evan Cheng62674222009-06-25 23:34:10 +0000278 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000279 Requires<[IsThumb2, CarryDefIsUnused]>;
Evan Cheng62674222009-06-25 23:34:10 +0000280 // Carry setting variants
281 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000282 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng62674222009-06-25 23:34:10 +0000283 !strconcat(opc, "s $dst, $lhs, $rhs"),
284 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000285 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000286 let Defs = [CPSR];
287 }
288 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000289 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000290 !strconcat(opc, "s.w $dst, $lhs, $rhs"),
Evan Cheng62674222009-06-25 23:34:10 +0000291 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000292 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000293 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000294 let isCommutable = Commutable;
295 }
Evan Cheng62674222009-06-25 23:34:10 +0000296 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000297 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000298 !strconcat(opc, "s.w $dst, $lhs, $rhs"),
Evan Cheng62674222009-06-25 23:34:10 +0000299 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
Evan Chengd770d9e2009-07-02 06:38:40 +0000300 Requires<[IsThumb2, CarryDefIsUsed]> {
Evan Cheng62674222009-06-25 23:34:10 +0000301 let Defs = [CPSR];
Evan Cheng8de898a2009-06-26 00:19:44 +0000302 }
Evan Chengf49810c2009-06-23 17:48:47 +0000303}
304}
305
David Goodwinaf0d08d2009-07-27 16:31:55 +0000306/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
Evan Cheng1e249e32009-06-25 20:59:23 +0000307let Defs = [CPSR] in {
308multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
Evan Chengf49810c2009-06-23 17:48:47 +0000309 // shifted imm
Evan Chenge8af1f92009-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 Goodwinaf0d08d2009-07-27 16:31:55 +0000312 !strconcat(opc, "${s}.w $dst, $rhs, $lhs"),
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000313 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000314 // shifted register
Evan Chenge8af1f92009-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 Cheng0aa1d8c2009-06-25 02:08:06 +0000317 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
318 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000319}
320}
321
Evan Chenga67efd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000326 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000327 opc, ".w $dst, $lhs, $rhs",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000328 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000329 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000330 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000331 opc, ".w $dst, $lhs, $rhs",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000332 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000333}
Evan Chengf49810c2009-06-23 17:48:47 +0000334
Evan Chenga67efd12009-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 Chengf49810c2009-06-23 17:48:47 +0000337/// a explicit result, only implicitly set CPSR.
David Goodwinc27a4542009-07-20 22:13:31 +0000338let Defs = [CPSR] in {
Evan Chengf49810c2009-06-23 17:48:47 +0000339multiclass T2I_cmp_is<string opc, PatFrag opnode> {
340 // shifted imm
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000341 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000342 opc, ".w $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000343 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000344 // register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000345 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000346 opc, ".w $lhs, $rhs",
Evan Chenga67efd12009-06-23 19:39:13 +0000347 [(opnode GPR:$lhs, GPR:$rhs)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000348 // shifted register
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000349 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000350 opc, ".w $lhs, $rhs",
Evan Chengf49810c2009-06-23 17:48:47 +0000351 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000352}
353}
354
Evan Chengf3c21b82009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000357 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoad,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000358 opc, ".w $dst, $addr",
Evan Chengf3c21b82009-06-30 02:15:48 +0000359 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000360 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoad,
Evan Chengf3c21b82009-06-30 02:15:48 +0000361 opc, " $dst, $addr",
362 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000363 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoad,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000364 opc, ".w $dst, $addr",
Evan Chengf3c21b82009-06-30 02:15:48 +0000365 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000366 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000367 opc, ".w $dst, $addr",
Evan Chengf3c21b82009-06-30 02:15:48 +0000368 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>;
369}
370
David Goodwin73b8f162009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000373 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStore,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000374 opc, ".w $src, $addr",
David Goodwin73b8f162009-06-30 22:11:34 +0000375 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000376 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStore,
David Goodwin73b8f162009-06-30 22:11:34 +0000377 opc, " $src, $addr",
378 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000379 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStore,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000380 opc, ".w $src, $addr",
David Goodwin73b8f162009-06-30 22:11:34 +0000381 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
382}
383
David Goodwind1fa1202009-07-01 00:01:13 +0000384/// T2I_picld - Defines the PIC load pattern.
385class T2I_picld<string opc, PatFrag opnode> :
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000386 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoad,
David Goodwind1fa1202009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000392 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStore,
David Goodwind1fa1202009-07-01 00:01:13 +0000393 !strconcat("${addr:label}:\n\t", opc), " $src, $addr",
394 [(opnode GPR:$src, addrmodepc:$addr)]>;
395
Evan Chengd27c9fc2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000400 def r : T2I<(outs GPR:$dst), (ins GPR:$Src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000401 opc, ".w $dst, $Src",
Evan Chengd27c9fc2009-07-03 01:43:10 +0000402 [(set GPR:$dst, (opnode GPR:$Src))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000403 def r_rot : T2I<(outs GPR:$dst), (ins GPR:$Src, i32imm:$rot), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000404 opc, ".w $dst, $Src, ror $rot",
Evan Chengd27c9fc2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000411 def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALU,
Evan Chengd27c9fc2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000415 IIC_iALU, opc, " $dst, $LHS, $RHS, ror $rot",
Evan Chengd27c9fc2009-07-03 01:43:10 +0000416 [(set GPR:$dst, (opnode GPR:$LHS,
417 (rotr GPR:$RHS, rot_imm:$rot)))]>;
418}
419
Anton Korobeynikov52237112009-06-17 18:13:58 +0000420//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000421// Instructions
422//===----------------------------------------------------------------------===//
423
424//===----------------------------------------------------------------------===//
Evan Chenga09b9ca2009-06-24 23:47:58 +0000425// Miscellaneous Instructions.
426//
427
Evan Chenga09b9ca2009-06-24 23:47:58 +0000428// LEApcrel - Load a pc-relative address into a register without offending the
429// assembler.
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000430def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000431 "adr$p.w $dst, #$label", []>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000432
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000433def t2LEApcrelJT : T2XI<(outs GPR:$dst),
Anton Korobeynikov8e9ece72009-08-08 23:10:41 +0000434 (ins i32imm:$label, lane_cst:$id, pred:$p), IIC_iALU,
435 "adr$p.w $dst, #${label}_${id}", []>;
Evan Chenga09b9ca2009-06-24 23:47:58 +0000436
Evan Cheng86198642009-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 Chenga09b9ca2009-06-24 23:47:58 +0000470//===----------------------------------------------------------------------===//
Evan Cheng9cb9e672009-06-27 02:26:13 +0000471// Load / store Instructions.
472//
473
Evan Cheng055b0312009-06-29 07:51:04 +0000474// Load
Evan Chengf3c21b82009-06-30 02:15:48 +0000475let canFoldAsLoad = 1 in
476defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
Evan Cheng055b0312009-06-29 07:51:04 +0000477
Evan Chengf3c21b82009-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 Cheng055b0312009-06-29 07:51:04 +0000481
Evan Chengf3c21b82009-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 Cheng055b0312009-06-29 07:51:04 +0000485
Evan Chengf3c21b82009-06-30 02:15:48 +0000486let mayLoad = 1 in {
487// Load doubleword
David Goodwin6647cea2009-06-30 22:50:01 +0000488def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000489 IIC_iLoad, "ldrd", " $dst, $addr", []>;
490def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
Evan Chengf3c21b82009-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 Cheng055b0312009-06-29 07:51:04 +0000533
Evan Chenge88d5ce2009-07-02 07:28:31 +0000534// Indexed loads
Evan Cheng78236f82009-07-03 00:08:19 +0000535let mayLoad = 1 in {
Evan Chenge88d5ce2009-07-02 07:28:31 +0000536def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
537 (ins t2addrmode_imm8:$addr),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000538 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenge88d5ce2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000544 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenge88d5ce2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000550 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenge88d5ce2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000555 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenge88d5ce2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000561 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Chenge88d5ce2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000566 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Chenge88d5ce2009-07-02 07:28:31 +0000567 "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
568 []>;
569
Evan Cheng4fbb9962009-07-02 23:16:11 +0000570def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
571 (ins t2addrmode_imm8:$addr),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000572 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Cheng4fbb9962009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000577 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Cheng4fbb9962009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000583 AddrModeT2_i8, IndexModePre, IIC_iLoad,
Evan Cheng4fbb9962009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000588 AddrModeT2_i8, IndexModePost, IIC_iLoad,
Evan Cheng4fbb9962009-07-02 23:16:11 +0000589 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
590 []>;
Evan Cheng78236f82009-07-03 00:08:19 +0000591}
Evan Cheng4fbb9962009-07-02 23:16:11 +0000592
David Goodwin73b8f162009-06-30 22:11:34 +0000593// Store
Evan Chenge88d5ce2009-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 Goodwin73b8f162009-06-30 22:11:34 +0000597
David Goodwin6647cea2009-06-30 22:50:01 +0000598// Store doubleword
599let mayLoad = 1 in
Evan Cheng1cf57832009-08-11 08:47:46 +0000600def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
601 IIC_iStore, "strd", " $src, $addr", []>;
David Goodwin6647cea2009-06-30 22:50:01 +0000602
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000606 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000613 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000620 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000627 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000634 AddrModeT2_i8, IndexModePre, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000641 AddrModeT2_i8, IndexModePost, IIC_iStore,
Evan Cheng6d94f112009-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 Goodwind1fa1202009-07-01 00:01:13 +0000646
Evan Cheng5c874172009-07-09 22:21:59 +0000647// FIXME: ldrd / strd pre / post variants
Evan Cheng2889cce2009-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 Chengd77c7ab2009-08-07 21:19:10 +0000656 IIC_iLoad, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1", []>;
Evan Cheng2889cce2009-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 Chengd77c7ab2009-08-07 21:19:10 +0000661 IIC_iStore, "stm${addr:submode}${p}${addr:wide} $addr, $src1", []>;
Evan Cheng2889cce2009-07-03 00:18:36 +0000662
Evan Cheng9cb9e672009-06-27 02:26:13 +0000663//===----------------------------------------------------------------------===//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000664// Move Instructions.
665//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000666
Evan Chengf49810c2009-06-23 17:48:47 +0000667let neverHasSideEffects = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000668def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000669 "mov", ".w $dst, $src", []>;
Evan Chengf49810c2009-06-23 17:48:47 +0000670
Evan Chenga67efd12009-06-23 19:39:13 +0000671let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000672def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000673 "mov", ".w $dst, $src",
David Goodwin83b35932009-06-26 16:10:07 +0000674 [(set GPR:$dst, t2_so_imm:$src)]>;
675
676let isReMaterializable = 1, isAsCheapAsAMove = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000677def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iALU,
David Goodwin83b35932009-06-26 16:10:07 +0000678 "movw", " $dst, $src",
679 [(set GPR:$dst, imm0_65535:$src)]>;
Evan Chengf49810c2009-06-23 17:48:47 +0000680
Evan Chengf49810c2009-06-23 17:48:47 +0000681// FIXME: Also available in ARM mode.
Evan Cheng3850a6a2009-06-23 05:23:49 +0000682let Constraints = "$src = $dst" in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000683def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000684 "movt", " $dst, $imm",
685 [(set GPR:$dst,
686 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000687
688//===----------------------------------------------------------------------===//
Evan Chengd27c9fc2009-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 Korobeynikov52237112009-06-17 18:13:58 +0000723// Arithmetic Instructions.
724//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000725
Evan Cheng8de898a2009-06-26 00:19:44 +0000726defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Evan Chenga67efd12009-06-23 19:39:13 +0000727defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000728
Evan Chengf49810c2009-06-23 17:48:47 +0000729// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
Evan Cheng8de898a2009-06-26 00:19:44 +0000730defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
Evan Cheng1e249e32009-06-25 20:59:23 +0000731defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Anton Korobeynikov52237112009-06-17 18:13:58 +0000732
Evan Cheng8de898a2009-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 Chengf49810c2009-06-23 17:48:47 +0000735
David Goodwin752aa7d2009-07-27 16:39:05 +0000736// RSB
Evan Cheng1e249e32009-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 Chengf49810c2009-06-23 17:48:47 +0000739
740// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
Evan Chengfa2ea1a2009-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 Cheng9cb9e672009-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 Korobeynikov52237112009-06-17 18:13:58 +0000748
749
Evan Chengf49810c2009-06-23 17:48:47 +0000750//===----------------------------------------------------------------------===//
Evan Chenga67efd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000759def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin7c92f3a2009-07-30 21:38:40 +0000760 "rrx", ".w $dst, $src",
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000761 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
Evan Chenga67efd12009-06-23 19:39:13 +0000762
David Goodwin3583df72009-07-28 17:06:49 +0000763let Defs = [CPSR] in {
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000764def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin3583df72009-07-28 17:06:49 +0000765 "lsrs.w $dst, $src, #1",
766 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000767def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwin3583df72009-07-28 17:06:49 +0000768 "asrs.w $dst, $src, #1",
769 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
770}
771
Evan Chenga67efd12009-06-23 19:39:13 +0000772//===----------------------------------------------------------------------===//
Evan Chengf49810c2009-06-23 17:48:47 +0000773// Bitwise Instructions.
774//
Anton Korobeynikov52237112009-06-17 18:13:58 +0000775
David Goodwin1f096272009-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 Chengf49810c2009-06-23 17:48:47 +0000779
David Goodwin1f096272009-07-27 23:34:12 +0000780defm t2BIC : T2I_bin_w_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000781
Evan Chengf49810c2009-06-23 17:48:47 +0000782let Constraints = "$src = $dst" in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000783def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000784 "bfc", " $dst, $imm",
Evan Chengf49810c2009-06-23 17:48:47 +0000785 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
786
787// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
788
David Goodwin8f652532009-07-30 21:51:41 +0000789defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Cheng36a0aeb2009-07-06 22:23:46 +0000790
791// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
792let AddedComplexity = 1 in
793defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
794
795
796def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
797 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
798
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000799// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwin8f652532009-07-30 21:51:41 +0000800def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000801 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
Evan Chengea253b92009-08-12 01:56:42 +0000802 Requires<[IsThumb2]>;
Evan Cheng36a0aeb2009-07-06 22:23:46 +0000803
804def : T2Pat<(t2_so_imm_not:$src),
805 (t2MVNi t2_so_imm_not:$src)>;
806
Evan Chengf49810c2009-06-23 17:48:47 +0000807//===----------------------------------------------------------------------===//
808// Multiply Instructions.
809//
Evan Cheng8de898a2009-06-26 00:19:44 +0000810let isCommutable = 1 in
David Goodwin1a8f36e2009-08-12 18:31:53 +0000811def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000812 "mul", " $dst, $a, $b",
Evan Chengf49810c2009-06-23 17:48:47 +0000813 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
814
David Goodwin1a8f36e2009-08-12 18:31:53 +0000815def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMPY,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000816 "mla", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000817 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
818
David Goodwin1a8f36e2009-08-12 18:31:53 +0000819def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMPY,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000820 "mls", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000821 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
822
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000823// Extra precision multiplies with low / high results
824let neverHasSideEffects = 1 in {
825let isCommutable = 1 in {
David Goodwin1a8f36e2009-08-12 18:31:53 +0000826def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000827 "smull", " $ldst, $hdst, $a, $b", []>;
828
David Goodwin1a8f36e2009-08-12 18:31:53 +0000829def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000830 "umull", " $ldst, $hdst, $a, $b", []>;
831}
832
833// Multiply + accumulate
David Goodwin1a8f36e2009-08-12 18:31:53 +0000834def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000835 "smlal", " $ldst, $hdst, $a, $b", []>;
836
David Goodwin1a8f36e2009-08-12 18:31:53 +0000837def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000838 "umlal", " $ldst, $hdst, $a, $b", []>;
839
David Goodwin1a8f36e2009-08-12 18:31:53 +0000840def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000841 "umaal", " $ldst, $hdst, $a, $b", []>;
842} // neverHasSideEffects
843
844// Most significant word multiply
David Goodwin1a8f36e2009-08-12 18:31:53 +0000845def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000846 "smmul", " $dst, $a, $b",
847 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
848
David Goodwin1a8f36e2009-08-12 18:31:53 +0000849def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000850 "smmla", " $dst, $a, $b, $c",
851 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>;
852
853
David Goodwin1a8f36e2009-08-12 18:31:53 +0000854def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000855 "smmls", " $dst, $a, $b, $c",
856 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>;
857
858multiclass T2I_smul<string opc, PatFrag opnode> {
David Goodwin1a8f36e2009-08-12 18:31:53 +0000859 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000860 !strconcat(opc, "bb"), " $dst, $a, $b",
861 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
862 (sext_inreg GPR:$b, i16)))]>;
863
David Goodwin1a8f36e2009-08-12 18:31:53 +0000864 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000865 !strconcat(opc, "bt"), " $dst, $a, $b",
866 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
867 (sra GPR:$b, (i32 16))))]>;
868
David Goodwin1a8f36e2009-08-12 18:31:53 +0000869 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000870 !strconcat(opc, "tb"), " $dst, $a, $b",
871 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
872 (sext_inreg GPR:$b, i16)))]>;
873
David Goodwin1a8f36e2009-08-12 18:31:53 +0000874 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000875 !strconcat(opc, "tt"), " $dst, $a, $b",
876 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
877 (sra GPR:$b, (i32 16))))]>;
878
David Goodwin1a8f36e2009-08-12 18:31:53 +0000879 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000880 !strconcat(opc, "wb"), " $dst, $a, $b",
881 [(set GPR:$dst, (sra (opnode GPR:$a,
882 (sext_inreg GPR:$b, i16)), (i32 16)))]>;
883
David Goodwin1a8f36e2009-08-12 18:31:53 +0000884 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000885 !strconcat(opc, "wt"), " $dst, $a, $b",
886 [(set GPR:$dst, (sra (opnode GPR:$a,
887 (sra GPR:$b, (i32 16))), (i32 16)))]>;
888}
889
890
891multiclass T2I_smla<string opc, PatFrag opnode> {
David Goodwin1a8f36e2009-08-12 18:31:53 +0000892 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000893 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
894 [(set GPR:$dst, (add GPR:$acc,
895 (opnode (sext_inreg GPR:$a, i16),
896 (sext_inreg GPR:$b, i16))))]>;
897
David Goodwin1a8f36e2009-08-12 18:31:53 +0000898 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000899 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
900 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
901 (sra GPR:$b, (i32 16)))))]>;
902
David Goodwin1a8f36e2009-08-12 18:31:53 +0000903 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000904 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
905 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
906 (sext_inreg GPR:$b, i16))))]>;
907
David Goodwin1a8f36e2009-08-12 18:31:53 +0000908 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000909 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
910 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
911 (sra GPR:$b, (i32 16)))))]>;
912
David Goodwin1a8f36e2009-08-12 18:31:53 +0000913 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000914 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
915 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
916 (sext_inreg GPR:$b, i16)), (i32 16))))]>;
917
David Goodwin1a8f36e2009-08-12 18:31:53 +0000918 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMPY,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000919 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
920 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
921 (sra GPR:$b, (i32 16))), (i32 16))))]>;
922}
923
924defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
925defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
926
927// TODO: Halfword multiple accumulate long: SMLAL<x><y>
928// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
929
Evan Chengf49810c2009-06-23 17:48:47 +0000930
931//===----------------------------------------------------------------------===//
932// Misc. Arithmetic Instructions.
933//
934
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000935def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000936 "clz", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000937 [(set GPR:$dst, (ctlz GPR:$src))]>;
938
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000939def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000940 "rev", ".w $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000941 [(set GPR:$dst, (bswap GPR:$src))]>;
942
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000943def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000944 "rev16", ".w $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000945 [(set GPR:$dst,
946 (or (and (srl GPR:$src, (i32 8)), 0xFF),
947 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
948 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
949 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
950
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000951def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000952 "revsh", ".w $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000953 [(set GPR:$dst,
954 (sext_inreg
955 (or (srl (and GPR:$src, 0xFFFF), (i32 8)),
956 (shl GPR:$src, (i32 8))), i16))]>;
957
Evan Cheng40289b02009-07-07 05:35:52 +0000958def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000959 IIC_iALU, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Cheng40289b02009-07-07 05:35:52 +0000960 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
961 (and (shl GPR:$src2, (i32 imm:$shamt)),
962 0xFFFF0000)))]>;
963
964// Alternate cases for PKHBT where identities eliminate some nodes.
965def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
966 (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
967def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
968 (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
969
970def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000971 IIC_iALU, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Cheng40289b02009-07-07 05:35:52 +0000972 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
973 (and (sra GPR:$src2, imm16_31:$shamt),
974 0xFFFF)))]>;
975
976// Alternate cases for PKHTB where identities eliminate some nodes. Note that
977// a shift amount of 0 is *not legal* here, it is PKHBT instead.
978def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
979 (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
980def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
981 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
982 (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
Evan Chengf49810c2009-06-23 17:48:47 +0000983
984//===----------------------------------------------------------------------===//
985// Comparison Instructions...
986//
987
Evan Chenge8af1f92009-08-10 02:37:24 +0000988defm t2CMP : T2I_cmp_is<"cmp",
989 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000990defm t2CMPz : T2I_cmp_is<"cmp",
991 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000992
Evan Chenge8af1f92009-08-10 02:37:24 +0000993defm t2CMN : T2I_cmp_is<"cmn",
994 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwinc0309b42009-06-29 15:33:01 +0000995defm t2CMNz : T2I_cmp_is<"cmn",
996 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +0000997
Evan Cheng9cb9e672009-06-27 02:26:13 +0000998def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
999 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +00001000
David Goodwinc0309b42009-06-29 15:33:01 +00001001def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng9cb9e672009-06-27 02:26:13 +00001002 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +00001003
David Goodwinbaeb9112009-06-29 22:49:42 +00001004defm t2TST : T2I_cmp_is<"tst",
1005 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1006defm t2TEQ : T2I_cmp_is<"teq",
1007 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Chengf49810c2009-06-23 17:48:47 +00001008
1009// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
1010// Short range conditional branch. Looks awesome for loops. Need to figure
1011// out how to use this one.
1012
Evan Chenge253c952009-07-07 20:39:03 +00001013
1014// Conditional moves
1015// FIXME: should be able to write a pattern for ARMcmov, but can't use
1016// a two-value operand where a dag node expects two operands. :(
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001017def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iALU,
Evan Cheng11197762009-07-31 22:21:55 +00001018 "mov", ".w $dst, $true",
Evan Chenge253c952009-07-07 20:39:03 +00001019 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1020 RegConstraint<"$false = $dst">;
1021
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001022def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), IIC_iALU,
Evan Cheng11197762009-07-31 22:21:55 +00001023 "mov", ".w $dst, $true",
Evan Chenge253c952009-07-07 20:39:03 +00001024[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1025 RegConstraint<"$false = $dst">;
Evan Chengf49810c2009-06-23 17:48:47 +00001026
Evan Cheng13f8b362009-08-01 01:43:45 +00001027def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001028 IIC_iALU, "lsl", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001029 RegConstraint<"$false = $dst">;
1030def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001031 IIC_iALU, "lsr", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001032 RegConstraint<"$false = $dst">;
1033def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001034 IIC_iALU, "asr", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001035 RegConstraint<"$false = $dst">;
1036def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001037 IIC_iALU, "ror", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001038 RegConstraint<"$false = $dst">;
1039
David Goodwin5e47a9a2009-06-30 18:04:13 +00001040//===----------------------------------------------------------------------===//
David Goodwin334c2642009-07-08 16:09:28 +00001041// TLS Instructions
1042//
1043
1044// __aeabi_read_tp preserves the registers r1-r3.
1045let isCall = 1,
1046 Defs = [R0, R12, LR, CPSR] in {
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001047 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
David Goodwin334c2642009-07-08 16:09:28 +00001048 "bl __aeabi_read_tp",
1049 [(set R0, ARMthread_pointer)]>;
1050}
1051
1052//===----------------------------------------------------------------------===//
Jim Grosbach5aa16842009-08-11 19:42:21 +00001053// SJLJ Exception handling intrinsics
1054// eh_sjlj_setjmp() is a three instruction sequence to store the return
1055// address and save #0 in R0 for the non-longjmp case.
1056// Since by its nature we may be coming from some other function to get
1057// here, and we're using the stack frame for the containing function to
1058// save/restore registers, we can't keep anything live in regs across
1059// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1060// when we get here from a longjmp(). We force everthing out of registers
1061// except for our own input by listing the relevant registers in Defs. By
1062// doing so, we also cause the prologue/epilogue code to actively preserve
1063// all of the callee-saved resgisters, which is exactly what we want.
1064let Defs =
1065 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1066 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1067 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
1068 D31 ] in {
1069 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src),
1070 AddrModeNone, SizeSpecial, NoItinerary,
1071 "str.w sp, [$src, #+8] @ eh_setjmp begin\n"
Jim Grosbach378756c2009-08-12 15:21:13 +00001072 "\tadr r12, 0f\n"
1073 "\torr r12, #1\n"
1074 "\tstr.w r12, [$src, #+4]\n"
Jim Grosbach5aa16842009-08-11 19:42:21 +00001075 "\tmovs r0, #0\n"
1076 "\tb 1f\n"
1077 "0:\tmovs r0, #1 @ eh_setjmp end\n"
1078 "1:\n", "",
1079 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1080}
1081
1082
1083
1084//===----------------------------------------------------------------------===//
David Goodwin5e47a9a2009-06-30 18:04:13 +00001085// Control-Flow Instructions
1086//
1087
Evan Chengc50a1cb2009-07-09 22:58:39 +00001088// FIXME: remove when we have a way to marking a MI with these properties.
1089// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
1090// operand list.
1091// FIXME: Should pc be an implicit operand like PICADD, etc?
1092let isReturn = 1, isTerminator = 1, mayLoad = 1 in
1093 def t2LDM_RET : T2XI<(outs),
1094 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
Evan Cheng4b322e52009-08-11 21:11:32 +00001095 IIC_Br, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1",
Evan Chengc50a1cb2009-07-09 22:58:39 +00001096 []>;
1097
David Goodwin5e47a9a2009-06-30 18:04:13 +00001098let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1099let isPredicable = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001100def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
David Goodwinaf0d08d2009-07-27 16:31:55 +00001101 "b.w $target",
David Goodwin5e47a9a2009-06-30 18:04:13 +00001102 [(br bb:$target)]>;
1103
Evan Cheng5657c012009-07-29 02:18:14 +00001104let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng66ac5312009-07-25 00:33:29 +00001105def t2BR_JT :
Evan Cheng5657c012009-07-29 02:18:14 +00001106 T2JTI<(outs),
1107 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001108 IIC_Br, "mov pc, $target\n$jt",
Evan Cheng5657c012009-07-29 02:18:14 +00001109 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
1110
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001111// FIXME: Add a non-pc based case that can be predicated.
Evan Cheng5657c012009-07-29 02:18:14 +00001112def t2TBB :
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001113 T2JTI<(outs),
Evan Cheng5657c012009-07-29 02:18:14 +00001114 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001115 IIC_Br, "tbb $index\n$jt", []>;
Evan Cheng5657c012009-07-29 02:18:14 +00001116
1117def t2TBH :
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001118 T2JTI<(outs),
Evan Cheng5657c012009-07-29 02:18:14 +00001119 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001120 IIC_Br, "tbh $index\n$jt", []>;
Evan Cheng5657c012009-07-29 02:18:14 +00001121} // isNotDuplicable, isIndirectBranch
1122
David Goodwinc9a59b52009-06-30 19:50:22 +00001123} // isBranch, isTerminator, isBarrier
David Goodwin5e47a9a2009-06-30 18:04:13 +00001124
1125// FIXME: should be able to write a pattern for ARMBrcond, but can't use
1126// a two-value operand where a dag node expects two operands. :(
1127let isBranch = 1, isTerminator = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001128def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
David Goodwinaf0d08d2009-07-27 16:31:55 +00001129 "b", ".w $target",
David Goodwin5e47a9a2009-06-30 18:04:13 +00001130 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Chengf49810c2009-06-23 17:48:47 +00001131
Evan Cheng06e16582009-07-10 01:54:42 +00001132
1133// IT block
1134def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001135 AddrModeNone, Size2Bytes, IIC_iALU,
Evan Cheng06e16582009-07-10 01:54:42 +00001136 "it$mask $cc", "", []>;
1137
Evan Chengf49810c2009-06-23 17:48:47 +00001138//===----------------------------------------------------------------------===//
1139// Non-Instruction Patterns
1140//
1141
Evan Chenga09b9ca2009-06-24 23:47:58 +00001142// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng9cb9e672009-06-27 02:26:13 +00001143def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
1144def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
1145def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1146 (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Chenga09b9ca2009-06-24 23:47:58 +00001147
Evan Chengf49810c2009-06-23 17:48:47 +00001148// Large immediate handling.
1149
Evan Cheng9cb9e672009-06-27 02:26:13 +00001150def : T2Pat<(i32 imm:$src),
1151 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;