blob: ab64b1b82feced12720e73005de1ef793d5531bb [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
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000789/*
David Goodwin8f652532009-07-30 21:51:41 +0000790defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000791*/
792// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000793def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
Evan Cheng25f7cfc2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000798def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000799 "orn", " $dst, $lhs, $rhs",
800 [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>;
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000801def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000802 "orn", " $dst, $lhs, $rhs",
803 [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;
Evan Cheng36a0aeb2009-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 Cheng25f7cfc2009-08-01 06:13:52 +0000813// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
David Goodwin8f652532009-07-30 21:51:41 +0000814def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000815 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
816 Requires<[IsThumb2, IsNotDarwin]>;
Evan Cheng36a0aeb2009-07-06 22:23:46 +0000817
818def : T2Pat<(t2_so_imm_not:$src),
819 (t2MVNi t2_so_imm_not:$src)>;
820
Evan Chengf49810c2009-06-23 17:48:47 +0000821//===----------------------------------------------------------------------===//
822// Multiply Instructions.
823//
Evan Cheng8de898a2009-06-26 00:19:44 +0000824let isCommutable = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000825def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000826 "mul", " $dst, $a, $b",
Evan Chengf49810c2009-06-23 17:48:47 +0000827 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
828
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000829def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000830 "mla", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000831 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
832
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000833def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000834 "mls", " $dst, $a, $b, $c",
Evan Chengf49810c2009-06-23 17:48:47 +0000835 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
836
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000837// Extra precision multiplies with low / high results
838let neverHasSideEffects = 1 in {
839let isCommutable = 1 in {
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000840def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000841 "smull", " $ldst, $hdst, $a, $b", []>;
842
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000843def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000844 "umull", " $ldst, $hdst, $a, $b", []>;
845}
846
847// Multiply + accumulate
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000848def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000849 "smlal", " $ldst, $hdst, $a, $b", []>;
850
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000851def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000852 "umlal", " $ldst, $hdst, $a, $b", []>;
853
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000854def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000855 "umaal", " $ldst, $hdst, $a, $b", []>;
856} // neverHasSideEffects
857
858// Most significant word multiply
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000859def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-07-07 01:17:28 +0000860 "smmul", " $dst, $a, $b",
861 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
862
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000863def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000868def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000873 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000878 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000883 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000888 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000893 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000898 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000906 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000912 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000917 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000922 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000927 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000932 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
Evan Cheng5b9fcd12009-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 Chengf49810c2009-06-23 17:48:47 +0000944
945//===----------------------------------------------------------------------===//
946// Misc. Arithmetic Instructions.
947//
948
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000949def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
Evan Cheng0aa1d8c2009-06-25 02:08:06 +0000950 "clz", " $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000951 [(set GPR:$dst, (ctlz GPR:$src))]>;
952
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000953def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000954 "rev", ".w $dst, $src",
Evan Chengf49810c2009-06-23 17:48:47 +0000955 [(set GPR:$dst, (bswap GPR:$src))]>;
956
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000957def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000958 "rev16", ".w $dst, $src",
Evan Chengf49810c2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000965def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
David Goodwinaf0d08d2009-07-27 16:31:55 +0000966 "revsh", ".w $dst, $src",
Evan Chengf49810c2009-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 Cheng40289b02009-07-07 05:35:52 +0000972def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
David Goodwin8b7d7ad2009-08-06 16:52:47 +0000973 IIC_iALU, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
Evan Cheng40289b02009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +0000985 IIC_iALU, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
Evan Cheng40289b02009-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 Chengf49810c2009-06-23 17:48:47 +0000997
998//===----------------------------------------------------------------------===//
999// Comparison Instructions...
1000//
1001
Evan Chenge8af1f92009-08-10 02:37:24 +00001002defm t2CMP : T2I_cmp_is<"cmp",
1003 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
David Goodwinc0309b42009-06-29 15:33:01 +00001004defm t2CMPz : T2I_cmp_is<"cmp",
1005 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Chengf49810c2009-06-23 17:48:47 +00001006
Evan Chenge8af1f92009-08-10 02:37:24 +00001007defm t2CMN : T2I_cmp_is<"cmn",
1008 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
David Goodwinc0309b42009-06-29 15:33:01 +00001009defm t2CMNz : T2I_cmp_is<"cmn",
1010 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
Evan Chengf49810c2009-06-23 17:48:47 +00001011
Evan Cheng9cb9e672009-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 Chengf49810c2009-06-23 17:48:47 +00001014
David Goodwinc0309b42009-06-29 15:33:01 +00001015def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
Evan Cheng9cb9e672009-06-27 02:26:13 +00001016 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Chengf49810c2009-06-23 17:48:47 +00001017
David Goodwinbaeb9112009-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 Chengf49810c2009-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 Chenge253c952009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +00001031def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iALU,
Evan Cheng11197762009-07-31 22:21:55 +00001032 "mov", ".w $dst, $true",
Evan Chenge253c952009-07-07 20:39:03 +00001033 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1034 RegConstraint<"$false = $dst">;
1035
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001036def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), IIC_iALU,
Evan Cheng11197762009-07-31 22:21:55 +00001037 "mov", ".w $dst, $true",
Evan Chenge253c952009-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 Chengf49810c2009-06-23 17:48:47 +00001040
Evan Cheng13f8b362009-08-01 01:43:45 +00001041def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001042 IIC_iALU, "lsl", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001043 RegConstraint<"$false = $dst">;
1044def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001045 IIC_iALU, "lsr", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001046 RegConstraint<"$false = $dst">;
1047def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001048 IIC_iALU, "asr", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001049 RegConstraint<"$false = $dst">;
1050def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001051 IIC_iALU, "ror", ".w $dst, $true, $rhs", []>,
Evan Cheng13f8b362009-08-01 01:43:45 +00001052 RegConstraint<"$false = $dst">;
1053
David Goodwin5e47a9a2009-06-30 18:04:13 +00001054//===----------------------------------------------------------------------===//
David Goodwin334c2642009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +00001061 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
David Goodwin334c2642009-07-08 16:09:28 +00001062 "bl __aeabi_read_tp",
1063 [(set R0, ARMthread_pointer)]>;
1064}
1065
1066//===----------------------------------------------------------------------===//
Jim Grosbach5aa16842009-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 Goodwin5e47a9a2009-06-30 18:04:13 +00001099// Control-Flow Instructions
1100//
1101
Evan Chengc50a1cb2009-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 Chengd77c7ab2009-08-07 21:19:10 +00001109 IIC_iLoad, "ldm${addr:submode}${p}${addr:wide} $addr, $dst1",
Evan Chengc50a1cb2009-07-09 22:58:39 +00001110 []>;
1111
David Goodwin5e47a9a2009-06-30 18:04:13 +00001112let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1113let isPredicable = 1 in
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001114def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
David Goodwinaf0d08d2009-07-27 16:31:55 +00001115 "b.w $target",
David Goodwin5e47a9a2009-06-30 18:04:13 +00001116 [(br bb:$target)]>;
1117
Evan Cheng5657c012009-07-29 02:18:14 +00001118let isNotDuplicable = 1, isIndirectBranch = 1 in {
Evan Cheng66ac5312009-07-25 00:33:29 +00001119def t2BR_JT :
Evan Cheng5657c012009-07-29 02:18:14 +00001120 T2JTI<(outs),
1121 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001122 IIC_Br, "mov pc, $target\n$jt",
Evan Cheng5657c012009-07-29 02:18:14 +00001123 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
1124
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001125// FIXME: Add a non-pc based case that can be predicated.
Evan Cheng5657c012009-07-29 02:18:14 +00001126def t2TBB :
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001127 T2JTI<(outs),
Evan Cheng5657c012009-07-29 02:18:14 +00001128 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001129 IIC_Br, "tbb $index\n$jt", []>;
Evan Cheng5657c012009-07-29 02:18:14 +00001130
1131def t2TBH :
Evan Cheng25f7cfc2009-08-01 06:13:52 +00001132 T2JTI<(outs),
Evan Cheng5657c012009-07-29 02:18:14 +00001133 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001134 IIC_Br, "tbh $index\n$jt", []>;
Evan Cheng5657c012009-07-29 02:18:14 +00001135} // isNotDuplicable, isIndirectBranch
1136
David Goodwinc9a59b52009-06-30 19:50:22 +00001137} // isBranch, isTerminator, isBarrier
David Goodwin5e47a9a2009-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 Goodwin8b7d7ad2009-08-06 16:52:47 +00001142def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
David Goodwinaf0d08d2009-07-27 16:31:55 +00001143 "b", ".w $target",
David Goodwin5e47a9a2009-06-30 18:04:13 +00001144 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Chengf49810c2009-06-23 17:48:47 +00001145
Evan Cheng06e16582009-07-10 01:54:42 +00001146
1147// IT block
1148def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
David Goodwin8b7d7ad2009-08-06 16:52:47 +00001149 AddrModeNone, Size2Bytes, IIC_iALU,
Evan Cheng06e16582009-07-10 01:54:42 +00001150 "it$mask $cc", "", []>;
1151
Evan Chengf49810c2009-06-23 17:48:47 +00001152//===----------------------------------------------------------------------===//
1153// Non-Instruction Patterns
1154//
1155
Evan Chenga09b9ca2009-06-24 23:47:58 +00001156// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng9cb9e672009-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 Chenga09b9ca2009-06-24 23:47:58 +00001161
Evan Chengf49810c2009-06-23 17:48:47 +00001162// Large immediate handling.
1163
Evan Cheng9cb9e672009-06-27 02:26:13 +00001164def : T2Pat<(i32 imm:$src),
1165 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;