1 //==- HexagonInstrInfo.td - Target Description for Hexagon -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Hexagon instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 include "HexagonInstrFormats.td"
15 include "HexagonOperands.td"
17 //===----------------------------------------------------------------------===//
19 // Multi-class for logical operators.
20 multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
21 def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
22 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
23 [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b),
25 def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c),
26 !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")),
27 [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b,
31 // Multi-class for compare ops.
32 let isCompare = 1 in {
33 multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
34 def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c),
35 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
36 [(set (i1 PredRegs:$dst),
37 (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
40 multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
41 let CextOpcode = CextOp in {
42 let InputType = "reg" in
43 def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
44 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
45 [(set (i1 PredRegs:$dst),
46 (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
48 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1,
49 opExtentBits = 10, InputType = "imm" in
50 def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c),
51 !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
52 [(set (i1 PredRegs:$dst),
53 (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>;
57 multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
58 let CextOpcode = CextOp in {
59 let InputType = "reg" in
60 def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
61 !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
62 [(set (i1 PredRegs:$dst),
63 (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
65 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0,
66 opExtentBits = 9, InputType = "imm" in
67 def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c),
68 !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
69 [(set (i1 PredRegs:$dst),
70 (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>;
74 multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
75 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
76 def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
77 !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
78 [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
83 //===----------------------------------------------------------------------===//
84 // ALU32/ALU (Instructions with register-register form)
85 //===----------------------------------------------------------------------===//
86 def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
87 [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
89 def HexagonWrapperCombineII :
90 SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
92 def HexagonWrapperCombineRR :
93 SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
95 multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
97 let isPredicatedNew = isPredNew in
98 def NAME : ALU32_rr<(outs RC:$dst),
99 (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
100 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
101 ") $dst = ")#mnemonic#"($src2, $src3)",
105 multiclass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
106 let isPredicatedFalse = PredNot in {
107 defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>;
109 defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>;
113 let InputType = "reg" in
114 multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
115 let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in {
116 let isPredicable = 1 in
117 def NAME : ALU32_rr<(outs IntRegs:$dst),
118 (ins IntRegs:$src1, IntRegs:$src2),
119 "$dst = "#mnemonic#"($src1, $src2)",
120 [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
121 (i32 IntRegs:$src2)))]>;
123 let neverHasSideEffects = 1, isPredicated = 1 in {
124 defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>;
125 defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>;
130 let isCommutable = 1 in {
131 defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
132 defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel;
133 defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
134 defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
137 defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
139 // Combines the two integer registers SRC1 and SRC2 into a double register.
140 let isPredicable = 1 in
141 class T_Combine : ALU32_rr<(outs DoubleRegs:$dst),
142 (ins IntRegs:$src1, IntRegs:$src2),
143 "$dst = combine($src1, $src2)",
144 [(set (i64 DoubleRegs:$dst),
145 (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
146 (i32 IntRegs:$src2))))]>;
148 multiclass Combine_base {
149 let BaseOpcode = "combine" in {
150 def NAME : T_Combine;
151 let neverHasSideEffects = 1, isPredicated = 1 in {
152 defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>;
153 defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>;
158 defm COMBINE_rr : Combine_base, PredNewRel;
160 // Combines the two immediates SRC1 and SRC2 into a double register.
161 class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
162 ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
163 "$dst = combine(#$src1, #$src2)",
164 [(set (i64 DoubleRegs:$dst),
165 (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
167 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
168 def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
170 //===----------------------------------------------------------------------===//
171 // ALU32/ALU (ADD with register-immediate form)
172 //===----------------------------------------------------------------------===//
173 multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
174 let isPredicatedNew = isPredNew in
175 def NAME : ALU32_ri<(outs IntRegs:$dst),
176 (ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3),
177 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
178 ") $dst = ")#mnemonic#"($src2, #$src3)",
182 multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
183 let isPredicatedFalse = PredNot in {
184 defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
186 defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
190 let isExtendable = 1, InputType = "imm" in
191 multiclass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> {
192 let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in {
193 let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16,
195 def NAME : ALU32_ri<(outs IntRegs:$dst),
196 (ins IntRegs:$src1, s16Ext:$src2),
197 "$dst = "#mnemonic#"($src1, #$src2)",
198 [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
199 (s16ExtPred:$src2)))]>;
201 let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
202 neverHasSideEffects = 1, isPredicated = 1 in {
203 defm Pt : ALU32ri_Pred<mnemonic, 0>;
204 defm NotPt : ALU32ri_Pred<mnemonic, 1>;
209 defm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
211 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
212 CextOpcode = "OR", InputType = "imm" in
213 def OR_ri : ALU32_ri<(outs IntRegs:$dst),
214 (ins IntRegs:$src1, s10Ext:$src2),
215 "$dst = or($src1, #$src2)",
216 [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
217 s10ExtPred:$src2))]>, ImmRegRel;
219 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
220 InputType = "imm", CextOpcode = "AND" in
221 def AND_ri : ALU32_ri<(outs IntRegs:$dst),
222 (ins IntRegs:$src1, s10Ext:$src2),
223 "$dst = and($src1, #$src2)",
224 [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
225 s10ExtPred:$src2))]>, ImmRegRel;
228 let neverHasSideEffects = 1 in
229 def NOP : ALU32_rr<(outs), (ins),
233 // Rd32=sub(#s10,Rs32)
234 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10,
235 CextOpcode = "SUB", InputType = "imm" in
236 def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
237 (ins s10Ext:$src1, IntRegs:$src2),
238 "$dst = sub(#$src1, $src2)",
239 [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
242 // Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
243 def : Pat<(not (i32 IntRegs:$src1)),
244 (SUB_ri -1, (i32 IntRegs:$src1))>;
246 // Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
247 // Pattern definition for 'neg' was not necessary.
249 multiclass TFR_Pred<bit PredNot> {
250 let isPredicatedFalse = PredNot in {
251 def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
252 (ins PredRegs:$src1, IntRegs:$src2),
253 !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
256 let isPredicatedNew = 1 in
257 def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
258 (ins PredRegs:$src1, IntRegs:$src2),
259 !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
264 let InputType = "reg", neverHasSideEffects = 1 in
265 multiclass TFR_base<string CextOp> {
266 let CextOpcode = CextOp, BaseOpcode = CextOp in {
267 let isPredicable = 1 in
268 def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
272 let isPredicated = 1 in {
273 defm Pt : TFR_Pred<0>;
274 defm NotPt : TFR_Pred<1>;
279 class T_TFR64_Pred<bit PredNot, bit isPredNew>
280 : ALU32_rr<(outs DoubleRegs:$dst),
281 (ins PredRegs:$src1, DoubleRegs:$src2),
282 !if(PredNot, "if (!$src1", "if ($src1")#
283 !if(isPredNew, ".new) ", ") ")#"$dst = $src2", []>
290 let Inst{27-24} = 0b1101;
291 let Inst{13} = isPredNew;
292 let Inst{7} = PredNot;
294 let Inst{6-5} = src1;
295 let Inst{20-17} = src2{4-1};
297 let Inst{12-9} = src2{4-1};
301 multiclass TFR64_Pred<bit PredNot> {
302 let isPredicatedFalse = PredNot in {
303 def _c#NAME : T_TFR64_Pred<PredNot, 0>;
305 let isPredicatedNew = 1 in
306 def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
310 let neverHasSideEffects = 1 in
311 multiclass TFR64_base<string BaseName> {
312 let BaseOpcode = BaseName in {
313 let isPredicable = 1 in
314 def NAME : ALU32Inst <(outs DoubleRegs:$dst),
315 (ins DoubleRegs:$src1),
321 let Inst{27-23} = 0b01010;
323 let Inst{20-17} = src1{4-1};
325 let Inst{12-9} = src1{4-1};
329 let isPredicated = 1 in {
330 defm Pt : TFR64_Pred<0>;
331 defm NotPt : TFR64_Pred<1>;
336 multiclass TFRI_Pred<bit PredNot> {
337 let isMoveImm = 1, isPredicatedFalse = PredNot in {
338 def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
339 (ins PredRegs:$src1, s12Ext:$src2),
340 !if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
344 let isPredicatedNew = 1 in
345 def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
346 (ins PredRegs:$src1, s12Ext:$src2),
347 !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
352 let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in
353 multiclass TFRI_base<string CextOp> {
354 let CextOpcode = CextOp, BaseOpcode = CextOp#I in {
355 let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16,
356 isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in
357 def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
359 [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>;
361 let opExtendable = 2, opExtentBits = 12, neverHasSideEffects = 1,
362 isPredicated = 1 in {
363 defm Pt : TFRI_Pred<0>;
364 defm NotPt : TFRI_Pred<1>;
369 defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel;
370 defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel;
371 defm TFR64 : TFR64_base<"TFR64">, PredNewRel;
373 // Transfer control register.
374 let neverHasSideEffects = 1 in
375 def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
378 //===----------------------------------------------------------------------===//
380 //===----------------------------------------------------------------------===//
383 //===----------------------------------------------------------------------===//
385 //===----------------------------------------------------------------------===//
388 def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
391 "$dst = vmux($src1, $src2, $src3)",
394 let CextOpcode = "MUX", InputType = "reg" in
395 def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
396 IntRegs:$src2, IntRegs:$src3),
397 "$dst = mux($src1, $src2, $src3)",
398 [(set (i32 IntRegs:$dst),
399 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
400 (i32 IntRegs:$src3))))]>, ImmRegRel;
402 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
403 CextOpcode = "MUX", InputType = "imm" in
404 def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
406 "$dst = mux($src1, #$src2, $src3)",
407 [(set (i32 IntRegs:$dst),
408 (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2,
409 (i32 IntRegs:$src3))))]>, ImmRegRel;
411 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
412 CextOpcode = "MUX", InputType = "imm" in
413 def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2,
415 "$dst = mux($src1, $src2, #$src3)",
416 [(set (i32 IntRegs:$dst),
417 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
418 s8ExtPred:$src3)))]>, ImmRegRel;
420 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
421 def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
423 "$dst = mux($src1, #$src2, #$src3)",
424 [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
426 s8ImmPred:$src3)))]>;
428 // ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth
429 multiclass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> {
430 let isPredicatedNew = isPredNew in
431 def NAME : ALU32Inst<(outs IntRegs:$dst),
432 (ins PredRegs:$src1, IntRegs:$src2),
433 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
434 ") $dst = ")#mnemonic#"($src2)">,
438 multiclass ALU32_2op_Pred<string mnemonic, bit PredNot> {
439 let isPredicatedFalse = PredNot in {
440 defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>;
442 defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>;
446 multiclass ALU32_2op_base<string mnemonic> {
447 let BaseOpcode = mnemonic in {
448 let isPredicable = 1, neverHasSideEffects = 1 in
449 def NAME : ALU32Inst<(outs IntRegs:$dst),
451 "$dst = "#mnemonic#"($src1)">;
453 let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1,
454 neverHasSideEffects = 1 in {
455 defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>;
456 defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>;
461 defm ASLH : ALU32_2op_base<"aslh">, PredNewRel;
462 defm ASRH : ALU32_2op_base<"asrh">, PredNewRel;
463 defm SXTB : ALU32_2op_base<"sxtb">, PredNewRel;
464 defm SXTH : ALU32_2op_base<"sxth">, PredNewRel;
465 defm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel;
466 defm ZXTH : ALU32_2op_base<"zxth">, PredNewRel;
468 def : Pat <(shl (i32 IntRegs:$src1), (i32 16)),
469 (ASLH IntRegs:$src1)>;
471 def : Pat <(sra (i32 IntRegs:$src1), (i32 16)),
472 (ASRH IntRegs:$src1)>;
474 def : Pat <(sext_inreg (i32 IntRegs:$src1), i8),
475 (SXTB IntRegs:$src1)>;
477 def : Pat <(sext_inreg (i32 IntRegs:$src1), i16),
478 (SXTH IntRegs:$src1)>;
480 //===----------------------------------------------------------------------===//
482 //===----------------------------------------------------------------------===//
485 //===----------------------------------------------------------------------===//
487 //===----------------------------------------------------------------------===//
490 defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
491 defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
492 defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
494 // SDNode for converting immediate C to C-1.
495 def DEC_CONST_SIGNED : SDNodeXForm<imm, [{
496 // Return the byte immediate const-1 as an SDNode.
497 int32_t imm = N->getSExtValue();
498 return XformSToSM1Imm(imm);
501 // SDNode for converting immediate C to C-1.
502 def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{
503 // Return the byte immediate const-1 as an SDNode.
504 uint32_t imm = N->getZExtValue();
505 return XformUToUM1Imm(imm);
508 def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
510 [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>;
512 def CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
514 [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>;
516 def CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
518 [(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>;
520 def CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
522 [(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>;
524 def TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
525 "$dst = tstbit($src1, $src2)",
526 [(set (i1 PredRegs:$dst),
527 (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>;
529 def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
530 "$dst = tstbit($src1, $src2)",
531 [(set (i1 PredRegs:$dst),
532 (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>;
534 //===----------------------------------------------------------------------===//
536 //===----------------------------------------------------------------------===//
539 //===----------------------------------------------------------------------===//
541 //===----------------------------------------------------------------------===//
543 def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
545 "$dst = add($src1, $src2)",
546 [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1),
547 (i64 DoubleRegs:$src2)))]>;
552 defm CMPEHexagon4 : CMP64_rr<"cmp.eq", seteq>;
553 defm CMPGT64 : CMP64_rr<"cmp.gt", setgt>;
554 defm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>;
556 // Logical operations.
557 def AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
559 "$dst = and($src1, $src2)",
560 [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
561 (i64 DoubleRegs:$src2)))]>;
563 def OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
565 "$dst = or($src1, $src2)",
566 [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1),
567 (i64 DoubleRegs:$src2)))]>;
569 def XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
571 "$dst = xor($src1, $src2)",
572 [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
573 (i64 DoubleRegs:$src2)))]>;
576 def MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
577 "$dst = max($src2, $src1)",
578 [(set (i32 IntRegs:$dst),
579 (i32 (select (i1 (setlt (i32 IntRegs:$src2),
580 (i32 IntRegs:$src1))),
581 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
583 def MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
584 "$dst = maxu($src2, $src1)",
585 [(set (i32 IntRegs:$dst),
586 (i32 (select (i1 (setult (i32 IntRegs:$src2),
587 (i32 IntRegs:$src1))),
588 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
590 def MAXd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
592 "$dst = max($src2, $src1)",
593 [(set (i64 DoubleRegs:$dst),
594 (i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
595 (i64 DoubleRegs:$src1))),
596 (i64 DoubleRegs:$src1),
597 (i64 DoubleRegs:$src2))))]>;
599 def MAXUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
601 "$dst = maxu($src2, $src1)",
602 [(set (i64 DoubleRegs:$dst),
603 (i64 (select (i1 (setult (i64 DoubleRegs:$src2),
604 (i64 DoubleRegs:$src1))),
605 (i64 DoubleRegs:$src1),
606 (i64 DoubleRegs:$src2))))]>;
609 def MINw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
610 "$dst = min($src2, $src1)",
611 [(set (i32 IntRegs:$dst),
612 (i32 (select (i1 (setgt (i32 IntRegs:$src2),
613 (i32 IntRegs:$src1))),
614 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
616 def MINUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
617 "$dst = minu($src2, $src1)",
618 [(set (i32 IntRegs:$dst),
619 (i32 (select (i1 (setugt (i32 IntRegs:$src2),
620 (i32 IntRegs:$src1))),
621 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
623 def MINd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
625 "$dst = min($src2, $src1)",
626 [(set (i64 DoubleRegs:$dst),
627 (i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
628 (i64 DoubleRegs:$src1))),
629 (i64 DoubleRegs:$src1),
630 (i64 DoubleRegs:$src2))))]>;
632 def MINUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
634 "$dst = minu($src2, $src1)",
635 [(set (i64 DoubleRegs:$dst),
636 (i64 (select (i1 (setugt (i64 DoubleRegs:$src2),
637 (i64 DoubleRegs:$src1))),
638 (i64 DoubleRegs:$src1),
639 (i64 DoubleRegs:$src2))))]>;
642 def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
644 "$dst = sub($src1, $src2)",
645 [(set (i64 DoubleRegs:$dst), (sub (i64 DoubleRegs:$src1),
646 (i64 DoubleRegs:$src2)))]>;
648 // Subtract halfword.
650 //===----------------------------------------------------------------------===//
652 //===----------------------------------------------------------------------===//
654 //===----------------------------------------------------------------------===//
656 //===----------------------------------------------------------------------===//
658 //===----------------------------------------------------------------------===//
660 //===----------------------------------------------------------------------===//
662 //===----------------------------------------------------------------------===//
664 //===----------------------------------------------------------------------===//
666 //===----------------------------------------------------------------------===//
668 //===----------------------------------------------------------------------===//
670 //===----------------------------------------------------------------------===//
672 //===----------------------------------------------------------------------===//
673 // Logical reductions on predicates.
675 // Looping instructions.
677 // Pipelined looping instructions.
679 // Logical operations on predicates.
680 def AND_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
681 "$dst = and($src1, $src2)",
682 [(set (i1 PredRegs:$dst), (and (i1 PredRegs:$src1),
683 (i1 PredRegs:$src2)))]>;
685 let neverHasSideEffects = 1 in
686 def AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1,
688 "$dst = and($src1, !$src2)",
691 def ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
692 "$dst = any8($src1)",
695 def ALL_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
696 "$dst = all8($src1)",
699 def VITPACK_pp : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1,
701 "$dst = vitpack($src1, $src2)",
704 def VALIGN_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
707 "$dst = valignb($src1, $src2, $src3)",
710 def VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
713 "$dst = vspliceb($src1, $src2, $src3)",
716 def MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1),
717 "$dst = mask($src1)",
720 def NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
722 [(set (i1 PredRegs:$dst), (not (i1 PredRegs:$src1)))]>;
724 def OR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
725 "$dst = or($src1, $src2)",
726 [(set (i1 PredRegs:$dst), (or (i1 PredRegs:$src1),
727 (i1 PredRegs:$src2)))]>;
729 def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
730 "$dst = xor($src1, $src2)",
731 [(set (i1 PredRegs:$dst), (xor (i1 PredRegs:$src1),
732 (i1 PredRegs:$src2)))]>;
735 // User control register transfer.
736 //===----------------------------------------------------------------------===//
738 //===----------------------------------------------------------------------===//
740 def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
741 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
742 def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone,
745 def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
746 def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
748 let InputType = "imm", isBarrier = 1, isPredicable = 1,
749 Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
751 class T_JMP <dag InsDag, list<dag> JumpList = []>
752 : JInst<(outs), InsDag,
753 "jump $dst" , JumpList> {
758 let Inst{27-25} = 0b100;
759 let Inst{24-16} = dst{23-15};
760 let Inst{13-1} = dst{14-2};
763 let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
764 Defs = [PC], isPredicated = 1, opExtentBits = 17 in
765 class T_JMP_c <bit PredNot, bit isPredNew, bit isTaken>:
766 JInst<(outs ), (ins PredRegs:$src, brtarget:$dst),
767 !if(PredNot, "if (!$src", "if ($src")#
768 !if(isPredNew, ".new) ", ") ")#"jump"#
769 !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
771 let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
772 let isPredicatedFalse = PredNot;
773 let isPredicatedNew = isPredNew;
779 let Inst{27-24} = 0b1100;
780 let Inst{21} = PredNot;
781 let Inst{12} = !if(isPredNew, isTaken, zero);
782 let Inst{11} = isPredNew;
784 let Inst{23-22} = dst{16-15};
785 let Inst{20-16} = dst{14-10};
786 let Inst{13} = dst{9};
787 let Inst{7-1} = dst{8-2};
790 let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in
791 class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
792 : JRInst<(outs ), InsDag,
798 let Inst{27-21} = 0b0010100;
799 let Inst{20-16} = dst;
802 let Defs = [PC], isPredicated = 1, InputType = "reg" in
803 class T_JMPr_c <bit PredNot, bit isPredNew, bit isTaken>:
804 JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst),
805 !if(PredNot, "if (!$src", "if ($src")#
806 !if(isPredNew, ".new) ", ") ")#"jumpr"#
807 !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
809 let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
810 let isPredicatedFalse = PredNot;
811 let isPredicatedNew = isPredNew;
817 let Inst{27-22} = 0b001101;
818 let Inst{21} = PredNot;
819 let Inst{20-16} = dst;
820 let Inst{12} = !if(isPredNew, isTaken, zero);
821 let Inst{11} = isPredNew;
823 let Predicates = !if(isPredNew, [HasV3T], [HasV2T]);
824 let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT);
827 multiclass JMP_Pred<bit PredNot> {
828 def _#NAME : T_JMP_c<PredNot, 0, 0>;
830 def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken
831 def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken
834 multiclass JMP_base<string BaseOp> {
835 let BaseOpcode = BaseOp in {
836 def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>;
837 defm t : JMP_Pred<0>;
838 defm f : JMP_Pred<1>;
842 multiclass JMPR_Pred<bit PredNot> {
843 def NAME: T_JMPr_c<PredNot, 0, 0>;
845 def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken
846 def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken
849 multiclass JMPR_base<string BaseOp> {
850 let BaseOpcode = BaseOp in {
852 defm _t : JMPR_Pred<0>;
853 defm _f : JMPR_Pred<1>;
857 let isTerminator = 1, neverHasSideEffects = 1 in {
859 defm JMP : JMP_base<"JMP">, PredNewRel;
861 let isBranch = 1, isIndirectBranch = 1 in
862 defm JMPR : JMPR_base<"JMPr">, PredNewRel;
864 let isReturn = 1, isCodeGenOnly = 1 in
865 defm JMPret : JMPR_base<"JMPret">, PredNewRel;
871 def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset),
872 (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
874 // A return through builtin_eh_return.
875 let isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1,
876 isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
877 def EH_RETURN_JMPR : T_JMPr;
879 def : Pat<(eh_return),
880 (EH_RETURN_JMPR (i32 R31))>;
882 def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
883 (JMPR (i32 IntRegs:$dst))>;
885 def : Pat<(brind (i32 IntRegs:$dst)),
886 (JMPR (i32 IntRegs:$dst))>;
888 //===----------------------------------------------------------------------===//
890 //===----------------------------------------------------------------------===//
892 //===----------------------------------------------------------------------===//
894 //===----------------------------------------------------------------------===//
896 // Load -- MEMri operand
897 multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
898 bit isNot, bit isPredNew> {
899 let isPredicatedNew = isPredNew in
900 def NAME : LDInst2<(outs RC:$dst),
901 (ins PredRegs:$src1, MEMri:$addr),
902 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
903 ") ")#"$dst = "#mnemonic#"($addr)",
907 multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
908 let isPredicatedFalse = PredNot in {
909 defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
911 defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
915 let isExtendable = 1, neverHasSideEffects = 1 in
916 multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC,
917 bits<5> ImmBits, bits<5> PredImmBits> {
919 let CextOpcode = CextOp, BaseOpcode = CextOp in {
920 let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
922 def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr),
923 "$dst = "#mnemonic#"($addr)",
926 let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
927 isPredicated = 1 in {
928 defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >;
929 defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >;
934 let addrMode = BaseImmOffset, isMEMri = "true" in {
935 defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel;
936 defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel;
937 defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel;
938 defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel;
939 defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel;
940 defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel;
943 def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)),
944 (LDrib ADDRriS11_0:$addr) >;
946 def : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)),
947 (LDriub ADDRriS11_0:$addr) >;
949 def : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)),
950 (LDrih ADDRriS11_1:$addr) >;
952 def : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)),
953 (LDriuh ADDRriS11_1:$addr) >;
955 def : Pat < (i32 (load ADDRriS11_2:$addr)),
956 (LDriw ADDRriS11_2:$addr) >;
958 def : Pat < (i64 (load ADDRriS11_3:$addr)),
959 (LDrid ADDRriS11_3:$addr) >;
962 // Load - Base with Immediate offset addressing mode
963 multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
964 bit isNot, bit isPredNew> {
965 let isPredicatedNew = isPredNew in
966 def NAME : LDInst2<(outs RC:$dst),
967 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
968 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
969 ") ")#"$dst = "#mnemonic#"($src2+#$src3)",
973 multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
975 let isPredicatedFalse = PredNot in {
976 defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
978 defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
982 let isExtendable = 1, neverHasSideEffects = 1 in
983 multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
984 Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
985 bits<5> PredImmBits> {
987 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
988 let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
989 isPredicable = 1, AddedComplexity = 20 in
990 def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset),
991 "$dst = "#mnemonic#"($src1+#$offset)",
994 let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
995 isPredicated = 1 in {
996 defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >;
997 defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >;
1002 let addrMode = BaseImmOffset in {
1003 defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext,
1004 11, 6>, AddrModeRel;
1005 defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext,
1006 11, 6>, AddrModeRel;
1007 defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext,
1008 12, 7>, AddrModeRel;
1009 defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext,
1010 12, 7>, AddrModeRel;
1011 defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext,
1012 13, 8>, AddrModeRel;
1013 defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext,
1014 14, 9>, AddrModeRel;
1017 let AddedComplexity = 20 in {
1018 def : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
1019 (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
1021 def : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
1022 (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
1024 def : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
1025 (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
1027 def : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
1028 (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
1030 def : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))),
1031 (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >;
1033 def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
1034 (LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
1037 //===----------------------------------------------------------------------===//
1038 // Post increment load
1039 // Make sure that in post increment load, the first operand is always the post
1040 // increment operand.
1041 //===----------------------------------------------------------------------===//
1043 multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
1044 bit isNot, bit isPredNew> {
1045 let isPredicatedNew = isPredNew in
1046 def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
1047 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
1048 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1049 ") ")#"$dst = "#mnemonic#"($src2++#$offset)",
1054 multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
1055 Operand ImmOp, bit PredNot> {
1056 let isPredicatedFalse = PredNot in {
1057 defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
1059 let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1060 defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
1064 multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
1067 let BaseOpcode = "POST_"#BaseOp in {
1068 let isPredicable = 1 in
1069 def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
1070 (ins IntRegs:$src1, ImmOp:$offset),
1071 "$dst = "#mnemonic#"($src1++#$offset)",
1075 let isPredicated = 1 in {
1076 defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
1077 defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
1082 let hasCtrlDep = 1, neverHasSideEffects = 1 in {
1083 defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
1085 defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
1087 defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>,
1089 defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>,
1091 defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>,
1093 defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>,
1097 def : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)),
1098 (i32 (LDrib ADDRriS11_0:$addr)) >;
1100 // Load byte any-extend.
1101 def : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)),
1102 (i32 (LDrib ADDRriS11_0:$addr)) >;
1104 // Indexed load byte any-extend.
1105 let AddedComplexity = 20 in
1106 def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
1107 (i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
1109 def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
1110 (i32 (LDrih ADDRriS11_1:$addr))>;
1112 let AddedComplexity = 20 in
1113 def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
1114 (i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
1116 let AddedComplexity = 10 in
1117 def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
1118 (i32 (LDriub ADDRriS11_0:$addr))>;
1120 let AddedComplexity = 20 in
1121 def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
1122 (i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
1125 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
1126 isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
1127 def LDriw_pred : LDInst2<(outs PredRegs:$dst),
1129 "Error; should not emit",
1132 // Deallocate stack frame.
1133 let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
1134 def DEALLOCFRAME : LDInst2<(outs), (ins),
1139 // Load and unpack bytes to halfwords.
1140 //===----------------------------------------------------------------------===//
1142 //===----------------------------------------------------------------------===//
1144 //===----------------------------------------------------------------------===//
1146 //===----------------------------------------------------------------------===//
1147 //===----------------------------------------------------------------------===//
1149 //===----------------------------------------------------------------------===//
1151 //===----------------------------------------------------------------------===//
1153 //===----------------------------------------------------------------------===//
1154 //===----------------------------------------------------------------------===//
1156 //===----------------------------------------------------------------------===//
1158 //===----------------------------------------------------------------------===//
1160 //===----------------------------------------------------------------------===//
1161 // Multiply and use lower result.
1163 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
1164 def MPYI_riu : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Ext:$src2),
1165 "$dst =+ mpyi($src1, #$src2)",
1166 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1167 u8ExtPred:$src2))]>;
1170 def MPYI_rin : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2),
1171 "$dst =- mpyi($src1, #$src2)",
1172 [(set (i32 IntRegs:$dst), (ineg (mul (i32 IntRegs:$src1),
1173 u8ImmPred:$src2)))]>;
1176 // s9 is NOT the same as m9 - but it works.. so far.
1177 // Assembler maps to either Rd=+mpyi(Rs,#u8 or Rd=-mpyi(Rs,#u8)
1178 // depending on the value of m9. See Arch Spec.
1179 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 9,
1180 CextOpcode = "MPYI", InputType = "imm" in
1181 def MPYI_ri : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2),
1182 "$dst = mpyi($src1, #$src2)",
1183 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1184 s9ExtPred:$src2))]>, ImmRegRel;
1187 let CextOpcode = "MPYI", InputType = "reg" in
1188 def MPYI : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1189 "$dst = mpyi($src1, $src2)",
1190 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
1191 (i32 IntRegs:$src2)))]>, ImmRegRel;
1194 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8,
1195 CextOpcode = "MPYI_acc", InputType = "imm" in
1196 def MPYI_acc_ri : MInst_acc<(outs IntRegs:$dst),
1197 (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
1198 "$dst += mpyi($src2, #$src3)",
1199 [(set (i32 IntRegs:$dst),
1200 (add (mul (i32 IntRegs:$src2), u8ExtPred:$src3),
1201 (i32 IntRegs:$src1)))],
1202 "$src1 = $dst">, ImmRegRel;
1205 let CextOpcode = "MPYI_acc", InputType = "reg" in
1206 def MPYI_acc_rr : MInst_acc<(outs IntRegs:$dst),
1207 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1208 "$dst += mpyi($src2, $src3)",
1209 [(set (i32 IntRegs:$dst),
1210 (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1211 (i32 IntRegs:$src1)))],
1212 "$src1 = $dst">, ImmRegRel;
1215 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8 in
1216 def MPYI_sub_ri : MInst_acc<(outs IntRegs:$dst),
1217 (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
1218 "$dst -= mpyi($src2, #$src3)",
1219 [(set (i32 IntRegs:$dst),
1220 (sub (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1221 u8ExtPred:$src3)))],
1224 // Multiply and use upper result.
1225 // Rd=mpy(Rs,Rt.H):<<1:rnd:sat
1226 // Rd=mpy(Rs,Rt.L):<<1:rnd:sat
1228 def MPY : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1229 "$dst = mpy($src1, $src2)",
1230 [(set (i32 IntRegs:$dst), (mulhs (i32 IntRegs:$src1),
1231 (i32 IntRegs:$src2)))]>;
1233 // Rd=mpy(Rs,Rt):rnd
1235 def MPYU : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1236 "$dst = mpyu($src1, $src2)",
1237 [(set (i32 IntRegs:$dst), (mulhu (i32 IntRegs:$src1),
1238 (i32 IntRegs:$src2)))]>;
1240 // Multiply and use full result.
1242 def MPYU64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1243 "$dst = mpyu($src1, $src2)",
1244 [(set (i64 DoubleRegs:$dst),
1245 (mul (i64 (anyext (i32 IntRegs:$src1))),
1246 (i64 (anyext (i32 IntRegs:$src2)))))]>;
1249 def MPY64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1250 "$dst = mpy($src1, $src2)",
1251 [(set (i64 DoubleRegs:$dst),
1252 (mul (i64 (sext (i32 IntRegs:$src1))),
1253 (i64 (sext (i32 IntRegs:$src2)))))]>;
1255 // Multiply and accumulate, use full result.
1256 // Rxx[+-]=mpy(Rs,Rt)
1258 def MPY64_acc : MInst_acc<(outs DoubleRegs:$dst),
1259 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1260 "$dst += mpy($src2, $src3)",
1261 [(set (i64 DoubleRegs:$dst),
1262 (add (mul (i64 (sext (i32 IntRegs:$src2))),
1263 (i64 (sext (i32 IntRegs:$src3)))),
1264 (i64 DoubleRegs:$src1)))],
1268 def MPY64_sub : MInst_acc<(outs DoubleRegs:$dst),
1269 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1270 "$dst -= mpy($src2, $src3)",
1271 [(set (i64 DoubleRegs:$dst),
1272 (sub (i64 DoubleRegs:$src1),
1273 (mul (i64 (sext (i32 IntRegs:$src2))),
1274 (i64 (sext (i32 IntRegs:$src3))))))],
1277 // Rxx[+-]=mpyu(Rs,Rt)
1279 def MPYU64_acc : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1280 IntRegs:$src2, IntRegs:$src3),
1281 "$dst += mpyu($src2, $src3)",
1282 [(set (i64 DoubleRegs:$dst),
1283 (add (mul (i64 (anyext (i32 IntRegs:$src2))),
1284 (i64 (anyext (i32 IntRegs:$src3)))),
1285 (i64 DoubleRegs:$src1)))], "$src1 = $dst">;
1288 def MPYU64_sub : MInst_acc<(outs DoubleRegs:$dst),
1289 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1290 "$dst -= mpyu($src2, $src3)",
1291 [(set (i64 DoubleRegs:$dst),
1292 (sub (i64 DoubleRegs:$src1),
1293 (mul (i64 (anyext (i32 IntRegs:$src2))),
1294 (i64 (anyext (i32 IntRegs:$src3))))))],
1298 let InputType = "reg", CextOpcode = "ADD_acc" in
1299 def ADDrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1300 IntRegs:$src2, IntRegs:$src3),
1301 "$dst += add($src2, $src3)",
1302 [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
1303 (i32 IntRegs:$src3)),
1304 (i32 IntRegs:$src1)))],
1305 "$src1 = $dst">, ImmRegRel;
1307 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
1308 InputType = "imm", CextOpcode = "ADD_acc" in
1309 def ADDri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1310 IntRegs:$src2, s8Ext:$src3),
1311 "$dst += add($src2, #$src3)",
1312 [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
1313 s8_16ExtPred:$src3),
1314 (i32 IntRegs:$src1)))],
1315 "$src1 = $dst">, ImmRegRel;
1317 let CextOpcode = "SUB_acc", InputType = "reg" in
1318 def SUBrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1319 IntRegs:$src2, IntRegs:$src3),
1320 "$dst -= add($src2, $src3)",
1321 [(set (i32 IntRegs:$dst),
1322 (sub (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
1323 (i32 IntRegs:$src3))))],
1324 "$src1 = $dst">, ImmRegRel;
1326 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
1327 CextOpcode = "SUB_acc", InputType = "imm" in
1328 def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
1329 IntRegs:$src2, s8Ext:$src3),
1330 "$dst -= add($src2, #$src3)",
1331 [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1),
1332 (add (i32 IntRegs:$src2),
1333 s8_16ExtPred:$src3)))],
1334 "$src1 = $dst">, ImmRegRel;
1336 //===----------------------------------------------------------------------===//
1338 //===----------------------------------------------------------------------===//
1340 //===----------------------------------------------------------------------===//
1342 //===----------------------------------------------------------------------===//
1343 //===----------------------------------------------------------------------===//
1345 //===----------------------------------------------------------------------===//
1347 //===----------------------------------------------------------------------===//
1349 //===----------------------------------------------------------------------===//
1350 //===----------------------------------------------------------------------===//
1352 //===----------------------------------------------------------------------===//
1354 //===----------------------------------------------------------------------===//
1356 //===----------------------------------------------------------------------===//
1357 //===----------------------------------------------------------------------===//
1359 //===----------------------------------------------------------------------===//
1361 //===----------------------------------------------------------------------===//
1363 //===----------------------------------------------------------------------===//
1365 // Store doubleword.
1367 //===----------------------------------------------------------------------===//
1368 // Post increment store
1369 //===----------------------------------------------------------------------===//
1371 multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
1372 bit isNot, bit isPredNew> {
1373 let isPredicatedNew = isPredNew in
1374 def NAME : STInst2PI<(outs IntRegs:$dst),
1375 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1376 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1377 ") ")#mnemonic#"($src2++#$offset) = $src3",
1382 multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
1383 Operand ImmOp, bit PredNot> {
1384 let isPredicatedFalse = PredNot in {
1385 defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
1387 let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1388 defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
1392 let hasCtrlDep = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1393 multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
1396 let hasCtrlDep = 1, BaseOpcode = "POST_"#BaseOp in {
1397 let isPredicable = 1 in
1398 def NAME : STInst2PI<(outs IntRegs:$dst),
1399 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1400 #mnemonic#"($src1++#$offset) = $src2",
1404 let isPredicated = 1 in {
1405 defm Pt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
1406 defm NotPt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
1411 defm POST_STbri: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1412 defm POST_SThri: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1413 defm POST_STwri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1415 let isNVStorable = 0 in
1416 defm POST_STdri: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm>, AddrModeRel;
1418 def : Pat<(post_truncsti8 (i32 IntRegs:$src1), IntRegs:$src2,
1419 s4_3ImmPred:$offset),
1420 (POST_STbri IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>;
1422 def : Pat<(post_truncsti16 (i32 IntRegs:$src1), IntRegs:$src2,
1423 s4_3ImmPred:$offset),
1424 (POST_SThri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
1426 def : Pat<(post_store (i32 IntRegs:$src1), IntRegs:$src2, s4_2ImmPred:$offset),
1427 (POST_STwri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
1429 def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2,
1430 s4_3ImmPred:$offset),
1431 (POST_STdri IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>;
1433 //===----------------------------------------------------------------------===//
1434 // multiclass for the store instructions with MEMri operand.
1435 //===----------------------------------------------------------------------===//
1436 multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1438 let isPredicatedNew = isPredNew in
1439 def NAME : STInst2<(outs),
1440 (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1441 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1442 ") ")#mnemonic#"($addr) = $src2",
1446 multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1447 let isPredicatedFalse = PredNot in {
1448 defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
1451 let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
1452 defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
1456 let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1457 multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC,
1458 bits<5> ImmBits, bits<5> PredImmBits> {
1460 let CextOpcode = CextOp, BaseOpcode = CextOp in {
1461 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1463 def NAME : STInst2<(outs),
1464 (ins MEMri:$addr, RC:$src),
1465 mnemonic#"($addr) = $src",
1468 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1469 isPredicated = 1 in {
1470 defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>;
1471 defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>;
1476 let addrMode = BaseImmOffset, isMEMri = "true" in {
1477 defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1478 defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1479 defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1481 let isNVStorable = 0 in
1482 defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
1485 def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr),
1486 (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>;
1488 def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr),
1489 (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>;
1491 def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr),
1492 (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>;
1494 def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
1495 (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>;
1498 //===----------------------------------------------------------------------===//
1499 // multiclass for the store instructions with base+immediate offset
1501 //===----------------------------------------------------------------------===//
1502 multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
1503 bit isNot, bit isPredNew> {
1504 let isPredicatedNew = isPredNew in
1505 def NAME : STInst2<(outs),
1506 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1507 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1508 ") ")#mnemonic#"($src2+#$src3) = $src4",
1512 multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
1514 let isPredicatedFalse = PredNot, isPredicated = 1 in {
1515 defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
1518 let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
1519 defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
1523 let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
1524 multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
1525 Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1526 bits<5> PredImmBits> {
1528 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1529 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1531 def NAME : STInst2<(outs),
1532 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1533 mnemonic#"($src1+#$src2) = $src3",
1536 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in {
1537 defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>;
1538 defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>;
1543 let addrMode = BaseImmOffset, InputType = "reg" in {
1544 defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext,
1545 u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel;
1546 defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext,
1547 u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel;
1548 defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext,
1549 u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel;
1550 let isNVStorable = 0 in
1551 defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
1552 u6_3Ext, 14, 9>, AddrModeRel;
1555 let AddedComplexity = 10 in {
1556 def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2,
1557 s11_0ExtPred:$offset)),
1558 (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset,
1559 (i32 IntRegs:$src1))>;
1561 def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2,
1562 s11_1ExtPred:$offset)),
1563 (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset,
1564 (i32 IntRegs:$src1))>;
1566 def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2,
1567 s11_2ExtPred:$offset)),
1568 (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset,
1569 (i32 IntRegs:$src1))>;
1571 def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
1572 s11_3ExtPred:$offset)),
1573 (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset,
1574 (i64 DoubleRegs:$src1))>;
1577 // memh(Rx++#s4:1)=Rt.H
1581 let Defs = [R10,R11,D5], neverHasSideEffects = 1 in
1582 def STriw_pred : STInst2<(outs),
1583 (ins MEMri:$addr, PredRegs:$src1),
1584 "Error; should not emit",
1587 // Allocate stack frame.
1588 let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
1589 def ALLOCFRAME : STInst2<(outs),
1591 "allocframe(#$amt)",
1594 //===----------------------------------------------------------------------===//
1596 //===----------------------------------------------------------------------===//
1598 //===----------------------------------------------------------------------===//
1600 //===----------------------------------------------------------------------===//
1602 def NOT_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
1603 "$dst = not($src1)",
1604 [(set (i64 DoubleRegs:$dst), (not (i64 DoubleRegs:$src1)))]>;
1607 // Sign extend word to doubleword.
1608 def SXTW : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1),
1609 "$dst = sxtw($src1)",
1610 [(set (i64 DoubleRegs:$dst), (sext (i32 IntRegs:$src1)))]>;
1611 //===----------------------------------------------------------------------===//
1613 //===----------------------------------------------------------------------===//
1615 //===----------------------------------------------------------------------===//
1617 //===----------------------------------------------------------------------===//
1619 def CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1620 "$dst = clrbit($src1, #$src2)",
1621 [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
1623 (shl 1, u5ImmPred:$src2))))]>;
1625 def CLRBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1626 "$dst = clrbit($src1, #$src2)",
1629 // Map from r0 = and(r1, 2147483647) to r0 = clrbit(r1, #31).
1630 def : Pat <(and (i32 IntRegs:$src1), 2147483647),
1631 (CLRBIT_31 (i32 IntRegs:$src1), 31)>;
1634 def SETBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1635 "$dst = setbit($src1, #$src2)",
1636 [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
1637 (shl 1, u5ImmPred:$src2)))]>;
1639 // Map from r0 = or(r1, -2147483648) to r0 = setbit(r1, #31).
1640 def SETBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1641 "$dst = setbit($src1, #$src2)",
1644 def : Pat <(or (i32 IntRegs:$src1), -2147483648),
1645 (SETBIT_31 (i32 IntRegs:$src1), 31)>;
1648 def TOGBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1649 "$dst = setbit($src1, #$src2)",
1650 [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1),
1651 (shl 1, u5ImmPred:$src2)))]>;
1653 // Map from r0 = xor(r1, -2147483648) to r0 = togglebit(r1, #31).
1654 def TOGBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1655 "$dst = togglebit($src1, #$src2)",
1658 def : Pat <(xor (i32 IntRegs:$src1), -2147483648),
1659 (TOGBIT_31 (i32 IntRegs:$src1), 31)>;
1661 // Predicate transfer.
1662 let neverHasSideEffects = 1 in
1663 def TFR_RsPd : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1),
1664 "$dst = $src1 /* Should almost never emit this. */",
1667 def TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1),
1668 "$dst = $src1 /* Should almost never emit this. */",
1669 [(set (i1 PredRegs:$dst), (trunc (i32 IntRegs:$src1)))]>;
1670 //===----------------------------------------------------------------------===//
1672 //===----------------------------------------------------------------------===//
1674 //===----------------------------------------------------------------------===//
1676 //===----------------------------------------------------------------------===//
1677 // Shift by immediate.
1678 def ASR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1679 "$dst = asr($src1, #$src2)",
1680 [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
1681 u5ImmPred:$src2))]>;
1683 def ASRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1684 "$dst = asr($src1, #$src2)",
1685 [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
1686 u6ImmPred:$src2))]>;
1688 def ASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1689 "$dst = asl($src1, #$src2)",
1690 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1691 u5ImmPred:$src2))]>;
1693 def ASLd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1694 "$dst = asl($src1, #$src2)",
1695 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1696 u6ImmPred:$src2))]>;
1698 def LSR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
1699 "$dst = lsr($src1, #$src2)",
1700 [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
1701 u5ImmPred:$src2))]>;
1703 def LSRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
1704 "$dst = lsr($src1, #$src2)",
1705 [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
1706 u6ImmPred:$src2))]>;
1708 // Shift by immediate and add.
1709 let AddedComplexity = 100 in
1710 def ADDASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
1712 "$dst = addasl($src1, $src2, #$src3)",
1713 [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1),
1714 (shl (i32 IntRegs:$src2),
1715 u3ImmPred:$src3)))]>;
1717 // Shift by register.
1718 def ASL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1719 "$dst = asl($src1, $src2)",
1720 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1721 (i32 IntRegs:$src2)))]>;
1723 def ASR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1724 "$dst = asr($src1, $src2)",
1725 [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
1726 (i32 IntRegs:$src2)))]>;
1728 def LSL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1729 "$dst = lsl($src1, $src2)",
1730 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
1731 (i32 IntRegs:$src2)))]>;
1733 def LSR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1734 "$dst = lsr($src1, $src2)",
1735 [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
1736 (i32 IntRegs:$src2)))]>;
1738 def ASLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
1739 "$dst = asl($src1, $src2)",
1740 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1741 (i32 IntRegs:$src2)))]>;
1743 def LSLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
1744 "$dst = lsl($src1, $src2)",
1745 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
1746 (i32 IntRegs:$src2)))]>;
1748 def ASRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1750 "$dst = asr($src1, $src2)",
1751 [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
1752 (i32 IntRegs:$src2)))]>;
1754 def LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
1756 "$dst = lsr($src1, $src2)",
1757 [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
1758 (i32 IntRegs:$src2)))]>;
1760 //===----------------------------------------------------------------------===//
1762 //===----------------------------------------------------------------------===//
1764 //===----------------------------------------------------------------------===//
1766 //===----------------------------------------------------------------------===//
1767 //===----------------------------------------------------------------------===//
1769 //===----------------------------------------------------------------------===//
1771 //===----------------------------------------------------------------------===//
1773 //===----------------------------------------------------------------------===//
1774 //===----------------------------------------------------------------------===//
1776 //===----------------------------------------------------------------------===//
1778 //===----------------------------------------------------------------------===//
1780 //===----------------------------------------------------------------------===//
1782 //===----------------------------------------------------------------------===//
1784 //===----------------------------------------------------------------------===//
1785 def SDHexagonBARRIER: SDTypeProfile<0, 0, []>;
1786 def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER,
1789 let hasSideEffects = 1, isSolo = 1 in
1790 def BARRIER : SYSInst<(outs), (ins),
1792 [(HexagonBARRIER)]>;
1794 //===----------------------------------------------------------------------===//
1796 //===----------------------------------------------------------------------===//
1798 // TFRI64 - assembly mapped.
1799 let isReMaterializable = 1 in
1800 def TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1),
1802 [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>;
1804 // Pseudo instruction to encode a set of conditional transfers.
1805 // This instruction is used instead of a mux and trades-off codesize
1806 // for performance. We conduct this transformation optimistically in
1807 // the hope that these instructions get promoted to dot-new transfers.
1808 let AddedComplexity = 100, isPredicated = 1 in
1809 def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
1812 "Error; should not emit",
1813 [(set (i32 IntRegs:$dst),
1814 (i32 (select (i1 PredRegs:$src1),
1815 (i32 IntRegs:$src2),
1816 (i32 IntRegs:$src3))))]>;
1817 let AddedComplexity = 100, isPredicated = 1 in
1818 def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst),
1819 (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3),
1820 "Error; should not emit",
1821 [(set (i32 IntRegs:$dst),
1822 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
1823 s12ImmPred:$src3)))]>;
1825 let AddedComplexity = 100, isPredicated = 1 in
1826 def TFR_condset_ir : ALU32_rr<(outs IntRegs:$dst),
1827 (ins PredRegs:$src1, s12Imm:$src2, IntRegs:$src3),
1828 "Error; should not emit",
1829 [(set (i32 IntRegs:$dst),
1830 (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2,
1831 (i32 IntRegs:$src3))))]>;
1833 let AddedComplexity = 100, isPredicated = 1 in
1834 def TFR_condset_ii : ALU32_rr<(outs IntRegs:$dst),
1835 (ins PredRegs:$src1, s12Imm:$src2, s12Imm:$src3),
1836 "Error; should not emit",
1837 [(set (i32 IntRegs:$dst),
1838 (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2,
1839 s12ImmPred:$src3)))]>;
1841 // Generate frameindex addresses.
1842 let isReMaterializable = 1 in
1843 def TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1),
1844 "$dst = add($src1)",
1845 [(set (i32 IntRegs:$dst), ADDRri:$src1)]>;
1850 let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
1851 def LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2),
1852 "loop0($offset, #$src2)",
1856 let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
1857 def LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2),
1858 "loop0($offset, $src2)",
1862 let isBranch = 1, isTerminator = 1, neverHasSideEffects = 1,
1863 Defs = [PC, LC0], Uses = [SA0, LC0] in {
1864 def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset),
1869 // Support for generating global address.
1870 // Taken from X86InstrInfo.td.
1871 def SDTHexagonCONST32 : SDTypeProfile<1, 1, [
1875 def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>;
1876 def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
1878 // HI/LO Instructions
1879 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1880 def LO : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
1881 "$dst.l = #LO($global)",
1884 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1885 def HI : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
1886 "$dst.h = #HI($global)",
1889 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1890 def LOi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
1891 "$dst.l = #LO($imm_value)",
1895 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1896 def HIi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
1897 "$dst.h = #HI($imm_value)",
1900 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1901 def LO_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
1902 "$dst.l = #LO($jt)",
1905 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1906 def HI_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
1907 "$dst.h = #HI($jt)",
1911 let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
1912 def LO_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
1913 "$dst.l = #LO($label)",
1916 let isReMaterializable = 1, isMoveImm = 1 , neverHasSideEffects = 1 in
1917 def HI_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
1918 "$dst.h = #HI($label)",
1921 // This pattern is incorrect. When we add small data, we should change
1922 // this pattern to use memw(#foo).
1923 // This is for sdata.
1924 let isMoveImm = 1 in
1925 def CONST32 : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
1926 "$dst = CONST32(#$global)",
1927 [(set (i32 IntRegs:$dst),
1928 (load (HexagonCONST32 tglobaltlsaddr:$global)))]>;
1930 // This is for non-sdata.
1931 let isReMaterializable = 1, isMoveImm = 1 in
1932 def CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
1933 "$dst = CONST32(#$global)",
1934 [(set (i32 IntRegs:$dst),
1935 (HexagonCONST32 tglobaladdr:$global))]>;
1937 let isReMaterializable = 1, isMoveImm = 1 in
1938 def CONST32_set_jt : LDInst2<(outs IntRegs:$dst), (ins jumptablebase:$jt),
1939 "$dst = CONST32(#$jt)",
1940 [(set (i32 IntRegs:$dst),
1941 (HexagonCONST32 tjumptable:$jt))]>;
1943 let isReMaterializable = 1, isMoveImm = 1 in
1944 def CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
1945 "$dst = CONST32(#$global)",
1946 [(set (i32 IntRegs:$dst),
1947 (HexagonCONST32_GP tglobaladdr:$global))]>;
1949 let isReMaterializable = 1, isMoveImm = 1 in
1950 def CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global),
1951 "$dst = CONST32(#$global)",
1952 [(set (i32 IntRegs:$dst), imm:$global) ]>;
1954 // Map BlockAddress lowering to CONST32_Int_Real
1955 def : Pat<(HexagonCONST32_GP tblockaddress:$addr),
1956 (CONST32_Int_Real tblockaddress:$addr)>;
1958 let isReMaterializable = 1, isMoveImm = 1 in
1959 def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label),
1960 "$dst = CONST32($label)",
1961 [(set (i32 IntRegs:$dst), (HexagonCONST32 bbl:$label))]>;
1963 let isReMaterializable = 1, isMoveImm = 1 in
1964 def CONST64_Int_Real : LDInst2<(outs DoubleRegs:$dst), (ins i64imm:$global),
1965 "$dst = CONST64(#$global)",
1966 [(set (i64 DoubleRegs:$dst), imm:$global) ]>;
1968 def TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins),
1969 "$dst = xor($dst, $dst)",
1970 [(set (i1 PredRegs:$dst), 0)]>;
1972 def MPY_trsext : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
1973 "$dst = mpy($src1, $src2)",
1974 [(set (i32 IntRegs:$dst),
1975 (trunc (i64 (srl (i64 (mul (i64 (sext (i32 IntRegs:$src1))),
1976 (i64 (sext (i32 IntRegs:$src2))))),
1979 // Pseudo instructions.
1980 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
1982 def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
1983 SDTCisVT<1, i32> ]>;
1985 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
1986 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
1988 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
1989 [SDNPHasChain, SDNPOutGlue]>;
1991 def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
1993 def call : SDNode<"HexagonISD::CALL", SDT_SPCall,
1994 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
1996 // For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain,
1997 // Optional Flag and Variable Arguments.
1998 // Its 1 Operand has pointer type.
1999 def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
2000 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2002 let Defs = [R29, R30], Uses = [R31, R30, R29] in {
2003 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
2004 "Should never be emitted",
2005 [(callseq_start timm:$amt)]>;
2008 let Defs = [R29, R30, R31], Uses = [R29] in {
2009 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
2010 "Should never be emitted",
2011 [(callseq_end timm:$amt1, timm:$amt2)]>;
2014 let isCall = 1, neverHasSideEffects = 1,
2015 Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
2016 R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
2017 def CALL : JInst<(outs), (ins calltarget:$dst),
2021 // Call subroutine from register.
2022 let isCall = 1, neverHasSideEffects = 1,
2023 Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
2024 R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
2025 def CALLR : JRInst<(outs), (ins IntRegs:$dst),
2031 // Indirect tail-call.
2032 let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in
2033 def TCRETURNR : T_JMPr;
2035 // Direct tail-calls.
2036 let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
2037 isTerminator = 1, isCodeGenOnly = 1 in {
2038 def TCRETURNtg : T_JMP<(ins calltarget:$dst)>;
2039 def TCRETURNtext : T_JMP<(ins calltarget:$dst)>;
2042 // Map call instruction.
2043 def : Pat<(call (i32 IntRegs:$dst)),
2044 (CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
2045 def : Pat<(call tglobaladdr:$dst),
2046 (CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>;
2047 def : Pat<(call texternalsym:$dst),
2048 (CALL texternalsym:$dst)>, Requires<[HasV2TOnly]>;
2050 def : Pat<(HexagonTCRet tglobaladdr:$dst),
2051 (TCRETURNtg tglobaladdr:$dst)>;
2052 def : Pat<(HexagonTCRet texternalsym:$dst),
2053 (TCRETURNtext texternalsym:$dst)>;
2054 def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
2055 (TCRETURNR (i32 IntRegs:$dst))>;
2057 // Atomic load and store support
2058 // 8 bit atomic load
2059 def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
2060 (i32 (LDriub ADDRriS11_0:$src1))>;
2062 def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
2063 (i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
2065 // 16 bit atomic load
2066 def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
2067 (i32 (LDriuh ADDRriS11_1:$src1))>;
2069 def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
2070 (i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
2072 def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
2073 (i32 (LDriw ADDRriS11_2:$src1))>;
2075 def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
2076 (i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
2078 // 64 bit atomic load
2079 def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
2080 (i64 (LDrid ADDRriS11_3:$src1))>;
2082 def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
2083 (i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
2086 def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
2087 (STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
2089 def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
2090 (i32 IntRegs:$src1)),
2091 (STrib_indexed (i32 IntRegs:$src2), s11_0ImmPred:$offset,
2092 (i32 IntRegs:$src1))>;
2095 def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
2096 (STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
2098 def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
2099 (add (i32 IntRegs:$src2), s11_1ImmPred:$offset)),
2100 (STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
2101 (i32 IntRegs:$src1))>;
2103 def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
2104 (STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
2106 def : Pat<(atomic_store_32 (add (i32 IntRegs:$src2), s11_2ImmPred:$offset),
2107 (i32 IntRegs:$src1)),
2108 (STriw_indexed (i32 IntRegs:$src2), s11_2ImmPred:$offset,
2109 (i32 IntRegs:$src1))>;
2114 def : Pat<(atomic_store_64 ADDRriS11_3:$src2, (i64 DoubleRegs:$src1)),
2115 (STrid ADDRriS11_3:$src2, (i64 DoubleRegs:$src1))>;
2117 def : Pat<(atomic_store_64 (add (i32 IntRegs:$src2), s11_3ImmPred:$offset),
2118 (i64 DoubleRegs:$src1)),
2119 (STrid_indexed (i32 IntRegs:$src2), s11_3ImmPred:$offset,
2120 (i64 DoubleRegs:$src1))>;
2122 // Map from r0 = and(r1, 65535) to r0 = zxth(r1)
2123 def : Pat <(and (i32 IntRegs:$src1), 65535),
2124 (ZXTH (i32 IntRegs:$src1))>;
2126 // Map from r0 = and(r1, 255) to r0 = zxtb(r1).
2127 def : Pat <(and (i32 IntRegs:$src1), 255),
2128 (ZXTB (i32 IntRegs:$src1))>;
2130 // Map Add(p1, true) to p1 = not(p1).
2131 // Add(p1, false) should never be produced,
2132 // if it does, it got to be mapped to NOOP.
2133 def : Pat <(add (i1 PredRegs:$src1), -1),
2134 (NOT_p (i1 PredRegs:$src1))>;
2136 // Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
2137 // p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
2138 // cmp.lt(r0, r1) -> cmp.gt(r1, r0)
2139 def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2140 (i32 IntRegs:$src3),
2141 (i32 IntRegs:$src4)),
2142 (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)),
2143 (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
2144 Requires<[HasV2TOnly]>;
2146 // Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
2147 def : Pat <(select (not (i1 PredRegs:$src1)), s8ImmPred:$src2, s8ImmPred:$src3),
2148 (i32 (TFR_condset_ii (i1 PredRegs:$src1), s8ImmPred:$src3,
2151 // Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
2152 // => r0 = TFR_condset_ri(p0, r1, #i)
2153 def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2,
2154 (i32 IntRegs:$src3)),
2155 (i32 (TFR_condset_ri (i1 PredRegs:$src1), (i32 IntRegs:$src3),
2156 s12ImmPred:$src2))>;
2158 // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
2159 // => r0 = TFR_condset_ir(p0, #i, r1)
2160 def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
2161 (i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3,
2162 (i32 IntRegs:$src2)))>;
2164 // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
2165 def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
2166 (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
2168 // Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
2169 def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
2170 (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
2173 let AddedComplexity = 100 in
2174 def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))),
2175 (i64 (COMBINE_rr (TFRI 0),
2176 (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>,
2179 // Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
2180 let AddedComplexity = 10 in
2181 def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
2182 (i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
2184 // Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo).
2185 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)),
2186 (i64 (SXTW (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>;
2188 // Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = SXTW(SXTH(Rss.lo)).
2189 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i16)),
2190 (i64 (SXTW (i32 (SXTH (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2191 subreg_loreg))))))>;
2193 // Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = SXTW(SXTB(Rss.lo)).
2194 def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
2195 (i64 (SXTW (i32 (SXTB (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2196 subreg_loreg))))))>;
2198 // We want to prevent emitting pnot's as much as possible.
2199 // Map brcond with an unsupported setcc to a JMP_f.
2200 def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2202 (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
2205 def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
2207 (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
2209 def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
2210 (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
2212 def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
2213 (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
2215 // cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
2216 def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
2218 (JMP_f (CMPGTri (i32 IntRegs:$src1),
2219 (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
2221 // cmp.lt(r0, r1) -> cmp.gt(r1, r0)
2222 def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2224 (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
2226 def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2228 (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
2231 def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2233 (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
2236 def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2238 (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2241 // Map from a 64-bit select to an emulated 64-bit mux.
2242 // Hexagon does not support 64-bit MUXes; so emulate with combines.
2243 def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2),
2244 (i64 DoubleRegs:$src3)),
2245 (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1),
2246 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2248 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
2250 (i32 (MUX_rr (i1 PredRegs:$src1),
2251 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2253 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
2254 subreg_loreg))))))>;
2256 // Map from a 1-bit select to logical ops.
2257 // From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
2258 def : Pat <(select (i1 PredRegs:$src1), (i1 PredRegs:$src2),
2259 (i1 PredRegs:$src3)),
2260 (OR_pp (AND_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)),
2261 (AND_pp (NOT_p (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>;
2263 // Map Pd = load(addr) -> Rs = load(addr); Pd = Rs.
2264 def : Pat<(i1 (load ADDRriS11_2:$addr)),
2265 (i1 (TFR_PdRs (i32 (LDrib ADDRriS11_2:$addr))))>;
2267 // Map for truncating from 64 immediates to 32 bit immediates.
2268 def : Pat<(i32 (trunc (i64 DoubleRegs:$src))),
2269 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), subreg_loreg))>;
2271 // Map for truncating from i64 immediates to i1 bit immediates.
2272 def : Pat<(i1 (trunc (i64 DoubleRegs:$src))),
2273 (i1 (TFR_PdRs (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2276 // Map memb(Rs) = Rdd -> memb(Rs) = Rt.
2277 def : Pat<(truncstorei8 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2278 (STrib ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2281 // Map memh(Rs) = Rdd -> memh(Rs) = Rt.
2282 def : Pat<(truncstorei16 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2283 (STrih ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2285 // Map memw(Rs) = Rdd -> memw(Rs) = Rt
2286 def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2287 (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2290 // Map memw(Rs) = Rdd -> memw(Rs) = Rt.
2291 def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
2292 (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
2295 // Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0.
2296 def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
2297 (STrib ADDRriS11_2:$addr, (TFRI 1))>;
2300 // Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
2301 def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
2302 (STrib ADDRriS11_2:$addr, (TFRI 1))>;
2304 // Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt.
2305 def : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr),
2306 (STrib ADDRriS11_2:$addr, (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0)) )>;
2308 // Map Rdd = anyext(Rs) -> Rdd = sxtw(Rs).
2309 // Hexagon_TODO: We can probably use combine but that will cost 2 instructions.
2310 // Better way to do this?
2311 def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
2312 (i64 (SXTW (i32 IntRegs:$src1)))>;
2314 // Map cmple -> cmpgt.
2315 // rs <= rt -> !(rs > rt).
2316 def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)),
2317 (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
2319 // rs <= rt -> !(rs > rt).
2320 def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2321 (i1 (NOT_p (CMPGTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
2323 // Rss <= Rtt -> !(Rss > Rtt).
2324 def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2325 (i1 (NOT_p (CMPGT64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
2327 // Map cmpne -> cmpeq.
2328 // Hexagon_TODO: We should improve on this.
2329 // rs != rt -> !(rs == rt).
2330 def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)),
2331 (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
2333 // Map cmpne(Rs) -> !cmpeqe(Rs).
2334 // rs != rt -> !(rs == rt).
2335 def : Pat <(i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2336 (i1 (NOT_p (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>;
2338 // Convert setne back to xor for hexagon since we compute w/ pred registers.
2339 def : Pat <(i1 (setne (i1 PredRegs:$src1), (i1 PredRegs:$src2))),
2340 (i1 (XOR_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
2342 // Map cmpne(Rss) -> !cmpew(Rss).
2343 // rs != rt -> !(rs == rt).
2344 def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2345 (i1 (NOT_p (i1 (CMPEHexagon4rr (i64 DoubleRegs:$src1),
2346 (i64 DoubleRegs:$src2)))))>;
2348 // Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt).
2349 // rs >= rt -> !(rt > rs).
2350 def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2351 (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
2353 // cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
2354 def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)),
2355 (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
2357 // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
2358 // rss >= rtt -> !(rtt > rss).
2359 def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2360 (i1 (NOT_p (i1 (CMPGT64rr (i64 DoubleRegs:$src2),
2361 (i64 DoubleRegs:$src1)))))>;
2363 // Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
2364 // !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
2365 // rs < rt -> !(rs >= rt).
2366 def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)),
2367 (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
2369 // Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
2370 // rs < rt -> rt > rs.
2371 // We can let assembler map it, or we can do in the compiler itself.
2372 def : Pat <(i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2373 (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
2375 // Map cmplt(Rss, Rtt) -> cmpgt(Rtt, Rss).
2376 // rss < rtt -> (rtt > rss).
2377 def : Pat <(i1 (setlt (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2378 (i1 (CMPGT64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
2380 // Map from cmpltu(Rs, Rd) -> cmpgtu(Rd, Rs)
2381 // rs < rt -> rt > rs.
2382 // We can let assembler map it, or we can do in the compiler itself.
2383 def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2384 (i1 (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
2386 // Map from cmpltu(Rss, Rdd) -> cmpgtu(Rdd, Rss).
2387 // rs < rt -> rt > rs.
2388 def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2389 (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
2391 // Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
2392 def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)),
2393 (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
2395 // Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
2396 def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)),
2397 (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
2399 // Generate cmpgtu(Rs, #u9)
2400 def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)),
2401 (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>;
2403 // Map from Rs >= Rt -> !(Rt > Rs).
2404 // rs >= rt -> !(rt > rs).
2405 def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2406 (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>;
2408 // Map from Rs >= Rt -> !(Rt > Rs).
2409 // rs >= rt -> !(rt > rs).
2410 def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2411 (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
2413 // Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt).
2414 // Map from (Rs <= Rt) -> !(Rs > Rt).
2415 def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
2416 (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
2418 // Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
2419 // Map from (Rs <= Rt) -> !(Rs > Rt).
2420 def : Pat <(i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
2421 (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
2425 def : Pat <(i32 (sext (i1 PredRegs:$src1))),
2426 (i32 (MUX_ii (i1 PredRegs:$src1), -1, 0))>;
2429 def : Pat <(i64 (sext (i1 PredRegs:$src1))),
2430 (i64 (COMBINE_rr (TFRI -1), (MUX_ii (i1 PredRegs:$src1), -1, 0)))>;
2432 // Convert sign-extended load back to load and sign extend.
2434 def: Pat <(i64 (sextloadi8 ADDRriS11_0:$src1)),
2435 (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
2437 // Convert any-extended load back to load and sign extend.
2439 def: Pat <(i64 (extloadi8 ADDRriS11_0:$src1)),
2440 (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
2442 // Convert sign-extended load back to load and sign extend.
2444 def: Pat <(i64 (sextloadi16 ADDRriS11_1:$src1)),
2445 (i64 (SXTW (LDrih ADDRriS11_1:$src1)))>;
2447 // Convert sign-extended load back to load and sign extend.
2449 def: Pat <(i64 (sextloadi32 ADDRriS11_2:$src1)),
2450 (i64 (SXTW (LDriw ADDRriS11_2:$src1)))>;
2455 def : Pat <(i32 (zext (i1 PredRegs:$src1))),
2456 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2459 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
2460 (i64 (COMBINE_rr (TFRI 0), (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
2464 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
2465 (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
2469 def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
2470 (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
2473 let AddedComplexity = 20 in
2474 def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
2475 s11_0ExtPred:$offset))),
2476 (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1,
2477 s11_0ExtPred:$offset)))>,
2481 def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
2482 (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
2485 let AddedComplexity = 20 in
2486 def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
2487 s11_0ExtPred:$offset))),
2488 (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1,
2489 s11_0ExtPred:$offset)))>,
2493 def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
2494 (i64 (COMBINE_rr (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>,
2497 let AddedComplexity = 20 in
2498 def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
2499 s11_1ExtPred:$offset))),
2500 (i64 (COMBINE_rr (TFRI 0), (LDriuh_indexed IntRegs:$src1,
2501 s11_1ExtPred:$offset)))>,
2505 def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
2506 (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
2509 let AddedComplexity = 100 in
2510 def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
2511 (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
2512 s11_2ExtPred:$offset)))>,
2515 let AddedComplexity = 10 in
2516 def: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)),
2517 (i32 (LDriw ADDRriS11_0:$src1))>;
2519 // Map from Rs = Pd to Pd = mux(Pd, #1, #0)
2520 def : Pat <(i32 (zext (i1 PredRegs:$src1))),
2521 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2523 // Map from Rs = Pd to Pd = mux(Pd, #1, #0)
2524 def : Pat <(i32 (anyext (i1 PredRegs:$src1))),
2525 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
2527 // Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0))
2528 def : Pat <(i64 (anyext (i1 PredRegs:$src1))),
2529 (i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>;
2532 let AddedComplexity = 100 in
2533 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2535 (i64 (zextloadi32 (i32 (add IntRegs:$src2,
2536 s11_2ExtPred:$offset2)))))),
2537 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2538 (LDriw_indexed IntRegs:$src2,
2539 s11_2ExtPred:$offset2)))>;
2541 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2543 (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
2544 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2545 (LDriw ADDRriS11_2:$srcLow)))>;
2547 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2549 (i64 (zext (i32 IntRegs:$srcLow))))),
2550 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2553 let AddedComplexity = 100 in
2554 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2556 (i64 (zextloadi32 (i32 (add IntRegs:$src2,
2557 s11_2ExtPred:$offset2)))))),
2558 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2559 (LDriw_indexed IntRegs:$src2,
2560 s11_2ExtPred:$offset2)))>;
2562 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2564 (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
2565 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2566 (LDriw ADDRriS11_2:$srcLow)))>;
2568 def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
2570 (i64 (zext (i32 IntRegs:$srcLow))))),
2571 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
2574 // Any extended 64-bit load.
2575 // anyext i32 -> i64
2576 def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
2577 (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
2580 // When there is an offset we should prefer the pattern below over the pattern above.
2581 // The complexity of the above is 13 (gleaned from HexagonGenDAGIsel.inc)
2582 // So this complexity below is comfortably higher to allow for choosing the below.
2583 // If this is not done then we generate addresses such as
2584 // ********************************************
2585 // r1 = add (r0, #4)
2586 // r1 = memw(r1 + #0)
2588 // r1 = memw(r0 + #4)
2589 // ********************************************
2590 let AddedComplexity = 100 in
2591 def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
2592 (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
2593 s11_2ExtPred:$offset)))>,
2596 // anyext i16 -> i64.
2597 def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
2598 (i64 (COMBINE_rr (TFRI 0), (LDrih ADDRriS11_2:$src1)))>,
2601 let AddedComplexity = 20 in
2602 def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
2603 s11_1ExtPred:$offset))),
2604 (i64 (COMBINE_rr (TFRI 0), (LDrih_indexed IntRegs:$src1,
2605 s11_1ExtPred:$offset)))>,
2608 // Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs).
2609 def : Pat<(i64 (zext (i32 IntRegs:$src1))),
2610 (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
2613 // Multiply 64-bit unsigned and use upper result.
2614 def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2629 (COMBINE_rr (TFRI 0),
2635 (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2637 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2638 subreg_loreg)))), 32)),
2640 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2641 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))),
2642 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
2643 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))),
2644 32)), subreg_loreg)))),
2645 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2646 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>;
2648 // Multiply 64-bit signed and use upper result.
2649 def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
2653 (COMBINE_rr (TFRI 0),
2663 (COMBINE_rr (TFRI 0),
2669 (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
2671 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
2672 subreg_loreg)))), 32)),
2674 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2675 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))),
2676 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
2677 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))),
2678 32)), subreg_loreg)))),
2679 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)),
2680 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>;
2682 // Hexagon specific ISD nodes.
2683 //def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>]>;
2684 def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2,
2685 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
2686 def Hexagon_ADJDYNALLOC : SDNode<"HexagonISD::ADJDYNALLOC",
2687 SDTHexagonADJDYNALLOC>;
2688 // Needed to tag these instructions for stack layout.
2689 let usesCustomInserter = 1 in
2690 def ADJDYNALLOC : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1,
2692 "$dst = add($src1, #$src2)",
2693 [(set (i32 IntRegs:$dst),
2694 (Hexagon_ADJDYNALLOC (i32 IntRegs:$src1),
2695 s16ImmPred:$src2))]>;
2697 def SDTHexagonARGEXTEND : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>;
2698 def Hexagon_ARGEXTEND : SDNode<"HexagonISD::ARGEXTEND", SDTHexagonARGEXTEND>;
2699 def ARGEXTEND : ALU32_rr <(outs IntRegs:$dst), (ins IntRegs:$src1),
2701 [(set (i32 IntRegs:$dst),
2702 (Hexagon_ARGEXTEND (i32 IntRegs:$src1)))]>;
2704 let AddedComplexity = 100 in
2705 def : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)),
2706 (COPY (i32 IntRegs:$src1))>;
2708 def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>;
2710 def : Pat<(HexagonWrapperJT tjumptable:$dst),
2711 (i32 (CONST32_set_jt tjumptable:$dst))>;
2715 // Multi-class for logical operators :
2716 // Shift by immediate/register and accumulate/logical
2717 multiclass xtype_imm<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
2718 def _ri : SInst_acc<(outs IntRegs:$dst),
2719 (ins IntRegs:$src1, IntRegs:$src2, u5Imm:$src3),
2720 !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
2721 [(set (i32 IntRegs:$dst),
2722 (OpNode2 (i32 IntRegs:$src1),
2723 (OpNode1 (i32 IntRegs:$src2),
2724 u5ImmPred:$src3)))],
2727 def d_ri : SInst_acc<(outs DoubleRegs:$dst),
2728 (ins DoubleRegs:$src1, DoubleRegs:$src2, u6Imm:$src3),
2729 !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
2730 [(set (i64 DoubleRegs:$dst), (OpNode2 (i64 DoubleRegs:$src1),
2731 (OpNode1 (i64 DoubleRegs:$src2), u6ImmPred:$src3)))],
2735 // Multi-class for logical operators :
2736 // Shift by register and accumulate/logical (32/64 bits)
2737 multiclass xtype_reg<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
2738 def _rr : SInst_acc<(outs IntRegs:$dst),
2739 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
2740 !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
2741 [(set (i32 IntRegs:$dst),
2742 (OpNode2 (i32 IntRegs:$src1),
2743 (OpNode1 (i32 IntRegs:$src2),
2744 (i32 IntRegs:$src3))))],
2747 def d_rr : SInst_acc<(outs DoubleRegs:$dst),
2748 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2749 !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
2750 [(set (i64 DoubleRegs:$dst),
2751 (OpNode2 (i64 DoubleRegs:$src1),
2752 (OpNode1 (i64 DoubleRegs:$src2),
2753 (i32 IntRegs:$src3))))],
2758 multiclass basic_xtype_imm<string OpcStr, SDNode OpNode> {
2759 let AddedComplexity = 100 in
2760 defm _ADD : xtype_imm< !strconcat("+= ", OpcStr), OpNode, add>;
2761 defm _SUB : xtype_imm< !strconcat("-= ", OpcStr), OpNode, sub>;
2762 defm _AND : xtype_imm< !strconcat("&= ", OpcStr), OpNode, and>;
2763 defm _OR : xtype_imm< !strconcat("|= ", OpcStr), OpNode, or>;
2766 multiclass basic_xtype_reg<string OpcStr, SDNode OpNode> {
2767 let AddedComplexity = 100 in
2768 defm _ADD : xtype_reg< !strconcat("+= ", OpcStr), OpNode, add>;
2769 defm _SUB : xtype_reg< !strconcat("-= ", OpcStr), OpNode, sub>;
2770 defm _AND : xtype_reg< !strconcat("&= ", OpcStr), OpNode, and>;
2771 defm _OR : xtype_reg< !strconcat("|= ", OpcStr), OpNode, or>;
2774 multiclass xtype_xor_imm<string OpcStr, SDNode OpNode> {
2775 let AddedComplexity = 100 in
2776 defm _XOR : xtype_imm< !strconcat("^= ", OpcStr), OpNode, xor>;
2779 defm ASL : basic_xtype_imm<"asl", shl>, basic_xtype_reg<"asl", shl>,
2780 xtype_xor_imm<"asl", shl>;
2782 defm LSR : basic_xtype_imm<"lsr", srl>, basic_xtype_reg<"lsr", srl>,
2783 xtype_xor_imm<"lsr", srl>;
2785 defm ASR : basic_xtype_imm<"asr", sra>, basic_xtype_reg<"asr", sra>;
2786 defm LSL : basic_xtype_reg<"lsl", shl>;
2788 // Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
2789 def : Pat <(mul (i32 IntRegs:$src1), (ineg n8ImmPred:$src2)),
2790 (i32 (MPYI_rin (i32 IntRegs:$src1), u8ImmPred:$src2))>;
2792 //===----------------------------------------------------------------------===//
2793 // V3 Instructions +
2794 //===----------------------------------------------------------------------===//
2796 include "HexagonInstrInfoV3.td"
2798 //===----------------------------------------------------------------------===//
2799 // V3 Instructions -
2800 //===----------------------------------------------------------------------===//
2802 //===----------------------------------------------------------------------===//
2803 // V4 Instructions +
2804 //===----------------------------------------------------------------------===//
2806 include "HexagonInstrInfoV4.td"
2808 //===----------------------------------------------------------------------===//
2809 // V4 Instructions -
2810 //===----------------------------------------------------------------------===//
2812 //===----------------------------------------------------------------------===//
2813 // V5 Instructions +
2814 //===----------------------------------------------------------------------===//
2816 include "HexagonInstrInfoV5.td"
2818 //===----------------------------------------------------------------------===//
2819 // V5 Instructions -
2820 //===----------------------------------------------------------------------===//