[Hexagon] Dropping old combine instructions without encodings.
[oota-llvm.git] / lib / Target / Hexagon / HexagonInstrInfoV4.td
1 //=- HexagonInstrInfoV4.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the Hexagon V4 instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 let hasSideEffects = 0 in
15 class T_Immext<Operand ImmType>
16   : EXTENDERInst<(outs), (ins ImmType:$imm),
17                  "immext(#$imm)", []> {
18     bits<32> imm;
19     let IClass = 0b0000;
20
21     let Inst{27-16} = imm{31-20};
22     let Inst{13-0} = imm{19-6};
23   }
24
25 def A4_ext : T_Immext<u26_6Imm>;
26 let isCodeGenOnly = 1 in {
27   let isBranch = 1 in
28     def A4_ext_b : T_Immext<brtarget>;
29   let isCall = 1 in
30     def A4_ext_c : T_Immext<calltarget>;
31   def A4_ext_g : T_Immext<globaladdress>;
32 }
33
34 // Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address.
35 def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>;
36
37 // Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address.
38 def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>;
39
40 def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
41                                        (HexagonCONST32 node:$addr), [{
42   return hasNumUsesBelowThresGA(N->getOperand(0).getNode());
43 }]>;
44
45 // Hexagon V4 Architecture spec defines 8 instruction classes:
46 // LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
47 // compiler)
48
49 // LD Instructions:
50 // ========================================
51 // Loads (8/16/32/64 bit)
52 // Deallocframe
53
54 // ST Instructions:
55 // ========================================
56 // Stores (8/16/32/64 bit)
57 // Allocframe
58
59 // ALU32 Instructions:
60 // ========================================
61 // Arithmetic / Logical (32 bit)
62 // Vector Halfword
63
64 // XTYPE Instructions (32/64 bit):
65 // ========================================
66 // Arithmetic, Logical, Bit Manipulation
67 // Multiply (Integer, Fractional, Complex)
68 // Permute / Vector Permute Operations
69 // Predicate Operations
70 // Shift / Shift with Add/Sub/Logical
71 // Vector Byte ALU
72 // Vector Halfword (ALU, Shift, Multiply)
73 // Vector Word (ALU, Shift)
74
75 // J Instructions:
76 // ========================================
77 // Jump/Call PC-relative
78
79 // JR Instructions:
80 // ========================================
81 // Jump/Call Register
82
83 // MEMOP Instructions:
84 // ========================================
85 // Operation on memory (8/16/32 bit)
86
87 // NV Instructions:
88 // ========================================
89 // New-value Jumps
90 // New-value Stores
91
92 // CR Instructions:
93 // ========================================
94 // Control-Register Transfers
95 // Hardware Loop Setup
96 // Predicate Logicals & Reductions
97
98 // SYSTEM Instructions (not implemented in the compiler):
99 // ========================================
100 // Prefetch
101 // Cache Maintenance
102 // Bus Operations
103
104
105 //===----------------------------------------------------------------------===//
106 // ALU32 +
107 //===----------------------------------------------------------------------===//
108
109 class T_ALU32_3op_not<string mnemonic, bits<3> MajOp, bits<3> MinOp,
110                       bit OpsRev>
111   : T_ALU32_3op<mnemonic, MajOp, MinOp, OpsRev, 0> {
112   let AsmString = "$Rd = "#mnemonic#"($Rs, ~$Rt)";
113 }
114
115 let BaseOpcode = "andn_rr", CextOpcode = "andn", isCodeGenOnly = 0 in
116 def A4_andn    : T_ALU32_3op_not<"and", 0b001, 0b100, 1>;
117 let BaseOpcode = "orn_rr", CextOpcode = "orn", isCodeGenOnly = 0 in
118 def A4_orn     : T_ALU32_3op_not<"or",  0b001, 0b101, 1>;
119
120 let CextOpcode = "rcmp.eq", isCodeGenOnly = 0 in
121 def A4_rcmpeq  : T_ALU32_3op<"cmp.eq",  0b011, 0b010, 0, 1>;
122 let CextOpcode = "!rcmp.eq", isCodeGenOnly = 0 in
123 def A4_rcmpneq : T_ALU32_3op<"!cmp.eq", 0b011, 0b011, 0, 1>;
124
125 let isCodeGenOnly = 0 in {
126 def C4_cmpneq  : T_ALU32_3op_cmp<"!cmp.eq",  0b00, 1, 1>;
127 def C4_cmplte  : T_ALU32_3op_cmp<"!cmp.gt",  0b10, 1, 0>;
128 def C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>;
129 }
130
131 // Pats for instruction selection.
132
133 // A class to embed the usual comparison patfrags within a zext to i32.
134 // The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
135 // names, or else the frag's "body" won't match the operands.
136 class CmpInReg<PatFrag Op>
137   : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
138
139 def: T_cmp32_rr_pat<A4_rcmpeq,  CmpInReg<seteq>, i32>;
140 def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
141
142 class T_CMP_rrbh<string mnemonic, bits<3> MinOp, bit IsComm>
143   : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
144     "$Pd = "#mnemonic#"($Rs, $Rt)", [], "", S_3op_tc_2early_SLOT23>,
145     ImmRegRel {
146   let validSubTargets = HasV4SubT;
147   let InputType = "reg";
148   let CextOpcode = mnemonic;
149   let isCompare = 1;
150   let isCommutable = IsComm;
151   let hasSideEffects = 0;
152
153   bits<2> Pd;
154   bits<5> Rs;
155   bits<5> Rt;
156
157   let IClass = 0b1100;
158   let Inst{27-21} = 0b0111110;
159   let Inst{20-16} = Rs;
160   let Inst{12-8} = Rt;
161   let Inst{7-5} = MinOp;
162   let Inst{1-0} = Pd;
163 }
164
165 let isCodeGenOnly = 0 in {
166 def A4_cmpbeq  : T_CMP_rrbh<"cmpb.eq",  0b110, 1>;
167 def A4_cmpbgt  : T_CMP_rrbh<"cmpb.gt",  0b010, 0>;
168 def A4_cmpbgtu : T_CMP_rrbh<"cmpb.gtu", 0b111, 0>;
169 def A4_cmpheq  : T_CMP_rrbh<"cmph.eq",  0b011, 1>;
170 def A4_cmphgt  : T_CMP_rrbh<"cmph.gt",  0b100, 0>;
171 def A4_cmphgtu : T_CMP_rrbh<"cmph.gtu", 0b101, 0>;
172 }
173
174 class T_CMP_ribh<string mnemonic, bits<2> MajOp, bit IsHalf, bit IsComm,
175                  Operand ImmType, bit IsImmExt, bit IsImmSigned, int ImmBits>
176   : ALU64Inst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, ImmType:$Imm),
177     "$Pd = "#mnemonic#"($Rs, #$Imm)", [], "", ALU64_tc_2early_SLOT23>,
178     ImmRegRel {
179   let validSubTargets = HasV4SubT;
180   let InputType = "imm";
181   let CextOpcode = mnemonic;
182   let isCompare = 1;
183   let isCommutable = IsComm;
184   let hasSideEffects = 0;
185   let isExtendable = IsImmExt;
186   let opExtendable = !if (IsImmExt, 2, 0);
187   let isExtentSigned = IsImmSigned;
188   let opExtentBits = ImmBits;
189
190   bits<2> Pd;
191   bits<5> Rs;
192   bits<8> Imm;
193
194   let IClass = 0b1101;
195   let Inst{27-24} = 0b1101;
196   let Inst{22-21} = MajOp;
197   let Inst{20-16} = Rs;
198   let Inst{12-5} = Imm;
199   let Inst{4} = 0b0;
200   let Inst{3} = IsHalf;
201   let Inst{1-0} = Pd;
202 }
203
204 let isCodeGenOnly = 0 in {
205 def A4_cmpbeqi  : T_CMP_ribh<"cmpb.eq",  0b00, 0, 1, u8Imm, 0, 0, 8>;
206 def A4_cmpbgti  : T_CMP_ribh<"cmpb.gt",  0b01, 0, 0, s8Imm, 0, 1, 8>;
207 def A4_cmpbgtui : T_CMP_ribh<"cmpb.gtu", 0b10, 0, 0, u7Ext, 1, 0, 7>;
208 def A4_cmpheqi  : T_CMP_ribh<"cmph.eq",  0b00, 1, 1, s8Ext, 1, 1, 8>;
209 def A4_cmphgti  : T_CMP_ribh<"cmph.gt",  0b01, 1, 0, s8Ext, 1, 1, 8>;
210 def A4_cmphgtui : T_CMP_ribh<"cmph.gtu", 0b10, 1, 0, u7Ext, 1, 0, 7>;
211 }
212 class T_RCMP_EQ_ri<string mnemonic, bit IsNeg>
213   : ALU32_ri<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s8Ext:$s8),
214     "$Rd = "#mnemonic#"($Rs, #$s8)", [], "", ALU32_2op_tc_1_SLOT0123>,
215     ImmRegRel {
216   let validSubTargets = HasV4SubT;
217   let InputType = "imm";
218   let CextOpcode = !if (IsNeg, "!rcmp.eq", "rcmp.eq");
219   let isExtendable = 1;
220   let opExtendable = 2;
221   let isExtentSigned = 1;
222   let opExtentBits = 8;
223   let hasNewValue = 1;
224
225   bits<5> Rd;
226   bits<5> Rs;
227   bits<8> s8;
228
229   let IClass = 0b0111;
230   let Inst{27-24} = 0b0011;
231   let Inst{22} = 0b1;
232   let Inst{21} = IsNeg;
233   let Inst{20-16} = Rs;
234   let Inst{13} = 0b1;
235   let Inst{12-5} = s8;
236   let Inst{4-0} = Rd;
237 }
238
239 let isCodeGenOnly = 0 in {
240 def A4_rcmpeqi  : T_RCMP_EQ_ri<"cmp.eq",  0>;
241 def A4_rcmpneqi : T_RCMP_EQ_ri<"!cmp.eq", 1>;
242 }
243
244 def: Pat<(i32 (zext (i1 (seteq (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
245          (A4_rcmpeqi IntRegs:$Rs, s8ExtPred:$s8)>;
246 def: Pat<(i32 (zext (i1 (setne (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
247          (A4_rcmpneqi IntRegs:$Rs, s8ExtPred:$s8)>;
248
249 // Preserve the S2_tstbit_r generation
250 def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
251                                          (i32 IntRegs:$src1))), 0)))),
252          (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
253
254
255 //===----------------------------------------------------------------------===//
256 // ALU32 -
257 //===----------------------------------------------------------------------===//
258
259
260 //===----------------------------------------------------------------------===//
261 // ALU32/PERM +
262 //===----------------------------------------------------------------------===//
263
264 // Combine a word and an immediate into a register pair.
265 let hasSideEffects = 0, isExtentSigned = 1, isExtendable = 1,
266     opExtentBits = 8 in
267 class T_Combine1 <bits<2> MajOp, dag ins, string AsmStr>
268   : ALU32Inst <(outs DoubleRegs:$Rdd), ins, AsmStr> {
269     bits<5> Rdd;
270     bits<5> Rs;
271     bits<8> s8;
272
273     let IClass      = 0b0111;
274     let Inst{27-24} = 0b0011;
275     let Inst{22-21} = MajOp;
276     let Inst{20-16} = Rs;
277     let Inst{13}    = 0b1;
278     let Inst{12-5}  = s8;
279     let Inst{4-0}   = Rdd;
280   }
281
282 let opExtendable = 2, isCodeGenOnly = 0 in
283 def A4_combineri : T_Combine1<0b00, (ins IntRegs:$Rs, s8Ext:$s8),
284                                     "$Rdd = combine($Rs, #$s8)">;
285
286 let opExtendable = 1, isCodeGenOnly = 0 in
287 def A4_combineir : T_Combine1<0b01, (ins s8Ext:$s8, IntRegs:$Rs),
288                                     "$Rdd = combine(#$s8, $Rs)">;
289
290 def HexagonWrapperCombineRI_V4 :
291   SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>;
292 def HexagonWrapperCombineIR_V4 :
293   SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
294
295 def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
296            (A4_combineri IntRegs:$r, s8ExtPred:$i)>,
297           Requires<[HasV4T]>;
298
299 def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
300            (A4_combineir s8ExtPred:$i, IntRegs:$r)>,
301           Requires<[HasV4T]>;
302
303 // A4_combineii: Set two small immediates.
304 let hasSideEffects = 0, isExtendable = 1, opExtentBits = 6, opExtendable = 2 in
305 def A4_combineii: ALU32Inst<(outs DoubleRegs:$Rdd), (ins s8Imm:$s8, u6Ext:$U6),
306   "$Rdd = combine(#$s8, #$U6)"> {
307     bits<5> Rdd;
308     bits<8> s8;
309     bits<6> U6;
310
311     let IClass = 0b0111;
312     let Inst{27-23} = 0b11001;
313     let Inst{20-16} = U6{5-1};
314     let Inst{13}    = U6{0};
315     let Inst{12-5}  = s8;
316     let Inst{4-0}   = Rdd;
317   }
318
319 //===----------------------------------------------------------------------===//
320 // ALU32/PERM -
321 //===----------------------------------------------------------------------===//
322
323 //===----------------------------------------------------------------------===//
324 // LD +
325 //===----------------------------------------------------------------------===//
326 //===----------------------------------------------------------------------===//
327 // Template class for load instructions with Absolute set addressing mode.
328 //===----------------------------------------------------------------------===//
329 let isExtended = 1, opExtendable = 2, hasSideEffects = 0,
330 validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
331 class T_LD_abs_set<string mnemonic, RegisterClass RC>:
332             LDInst2<(outs RC:$dst1, IntRegs:$dst2),
333             (ins u0AlwaysExt:$addr),
334             "$dst1 = "#mnemonic#"($dst2=##$addr)",
335             []>,
336             Requires<[HasV4T]>;
337
338 def LDrid_abs_set_V4  : T_LD_abs_set <"memd", DoubleRegs>;
339 def LDrib_abs_set_V4  : T_LD_abs_set <"memb", IntRegs>;
340 def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
341 def LDrih_abs_set_V4  : T_LD_abs_set <"memh", IntRegs>;
342 def LDriw_abs_set_V4  : T_LD_abs_set <"memw", IntRegs>;
343 def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
344
345
346 // multiclass for load instructions with base + register offset
347 // addressing mode
348 multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
349                              bit isPredNew> {
350   let isPredicatedNew = isPredNew in
351   def NAME : LDInst2<(outs RC:$dst),
352             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
353             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
354             ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
355             []>, Requires<[HasV4T]>;
356 }
357
358 multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
359   let isPredicatedFalse = PredNot in {
360     defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
361     // Predicate new
362     defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
363   }
364 }
365
366 let hasSideEffects = 0 in
367 multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
368   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
369     let isPredicable = 1 in
370     def NAME#_V4 : LDInst2<(outs RC:$dst),
371             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
372             "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
373             []>, Requires<[HasV4T]>;
374
375     let isPredicated = 1 in {
376       defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
377       defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
378     }
379   }
380 }
381
382 let addrMode = BaseRegOffset in {
383   let accessSize = ByteAccess in {
384     defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>,
385                                         AddrModeRel;
386     defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>,
387                                         AddrModeRel;
388   }
389   let accessSize = HalfWordAccess in {
390     defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
391     defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>,
392                              AddrModeRel;
393   }
394   let accessSize = WordAccess in
395      defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
396
397   let accessSize = DoubleWordAccess in
398     defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>,
399                              AddrModeRel;
400 }
401
402 // 'def pats' for load instructions with base + register offset and non-zero
403 // immediate value. Immediate value is used to left-shift the second
404 // register operand.
405 let AddedComplexity = 40 in {
406 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
407                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
408            (LDrib_indexed_shl_V4 IntRegs:$src1,
409             IntRegs:$src2, u2ImmPred:$offset)>,
410             Requires<[HasV4T]>;
411
412 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
413                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
414            (LDriub_indexed_shl_V4 IntRegs:$src1,
415             IntRegs:$src2, u2ImmPred:$offset)>,
416             Requires<[HasV4T]>;
417
418 def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
419                                 (shl IntRegs:$src2, u2ImmPred:$offset)))),
420            (LDriub_indexed_shl_V4 IntRegs:$src1,
421             IntRegs:$src2, u2ImmPred:$offset)>,
422             Requires<[HasV4T]>;
423
424 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
425                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
426            (LDrih_indexed_shl_V4 IntRegs:$src1,
427             IntRegs:$src2, u2ImmPred:$offset)>,
428             Requires<[HasV4T]>;
429
430 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
431                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
432            (LDriuh_indexed_shl_V4 IntRegs:$src1,
433             IntRegs:$src2, u2ImmPred:$offset)>,
434             Requires<[HasV4T]>;
435
436 def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
437                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
438            (LDriuh_indexed_shl_V4 IntRegs:$src1,
439             IntRegs:$src2, u2ImmPred:$offset)>,
440             Requires<[HasV4T]>;
441
442 def : Pat <(i32 (load (add IntRegs:$src1,
443                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
444            (LDriw_indexed_shl_V4 IntRegs:$src1,
445             IntRegs:$src2, u2ImmPred:$offset)>,
446             Requires<[HasV4T]>;
447
448 def : Pat <(i64 (load (add IntRegs:$src1,
449                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
450            (LDrid_indexed_shl_V4 IntRegs:$src1,
451             IntRegs:$src2, u2ImmPred:$offset)>,
452             Requires<[HasV4T]>;
453 }
454
455
456 // 'def pats' for load instruction base + register offset and
457 // zero immediate value.
458 let AddedComplexity = 10 in {
459 def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))),
460            (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
461             Requires<[HasV4T]>;
462
463 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
464            (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
465             Requires<[HasV4T]>;
466
467 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
468            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
469             Requires<[HasV4T]>;
470
471 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))),
472            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
473             Requires<[HasV4T]>;
474
475 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
476            (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
477             Requires<[HasV4T]>;
478
479 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
480            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
481             Requires<[HasV4T]>;
482
483 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))),
484            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
485             Requires<[HasV4T]>;
486
487 def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
488            (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
489             Requires<[HasV4T]>;
490 }
491
492 // zext i1->i64
493 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
494       (i64 (A4_combineir 0, (C2_muxii (i1 PredRegs:$src1), 1, 0)))>,
495       Requires<[HasV4T]>;
496
497 // zext i32->i64
498 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
499       (i64 (A4_combineir 0, (i32 IntRegs:$src1)))>,
500       Requires<[HasV4T]>;
501 // zext i8->i64
502 def:  Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
503       (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>,
504       Requires<[HasV4T]>;
505
506 let AddedComplexity = 20 in
507 def:  Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
508                                 s11_0ExtPred:$offset))),
509       (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1,
510                                   s11_0ExtPred:$offset)))>,
511       Requires<[HasV4T]>;
512
513 // zext i1->i64
514 def:  Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
515       (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>,
516       Requires<[HasV4T]>;
517
518 let AddedComplexity = 20 in
519 def:  Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
520                                 s11_0ExtPred:$offset))),
521       (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1,
522                                   s11_0ExtPred:$offset)))>,
523       Requires<[HasV4T]>;
524
525 // zext i16->i64
526 def:  Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
527       (i64 (A4_combineir 0, (L2_loadruh_io AddrFI:$src1, 0)))>,
528       Requires<[HasV4T]>;
529
530 let AddedComplexity = 20 in
531 def:  Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
532                                   s11_1ExtPred:$offset))),
533       (i64 (A4_combineir 0, (L2_loadruh_io IntRegs:$src1,
534                                   s11_1ExtPred:$offset)))>,
535       Requires<[HasV4T]>;
536
537 // anyext i16->i64
538 def:  Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
539       (i64 (A4_combineir 0, (L2_loadrh_io AddrFI:$src1, 0)))>,
540       Requires<[HasV4T]>;
541
542 let AddedComplexity = 20 in
543 def:  Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
544                                   s11_1ExtPred:$offset))),
545       (i64 (A4_combineir 0, (L2_loadrh_io IntRegs:$src1,
546                                   s11_1ExtPred:$offset)))>,
547       Requires<[HasV4T]>;
548
549 // zext i32->i64
550 def:  Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
551       (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
552       Requires<[HasV4T]>;
553
554 let AddedComplexity = 100 in
555 def:  Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
556       (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
557                                   s11_2ExtPred:$offset)))>,
558       Requires<[HasV4T]>;
559
560 // anyext i32->i64
561 def:  Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
562       (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
563       Requires<[HasV4T]>;
564
565 let AddedComplexity = 100 in
566 def:  Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
567       (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
568                                   s11_2ExtPred:$offset)))>,
569       Requires<[HasV4T]>;
570
571
572
573 //===----------------------------------------------------------------------===//
574 // LD -
575 //===----------------------------------------------------------------------===//
576
577 //===----------------------------------------------------------------------===//
578 // ST +
579 //===----------------------------------------------------------------------===//
580 ///
581 //===----------------------------------------------------------------------===//
582 // Template class for store instructions with Absolute set addressing mode.
583 //===----------------------------------------------------------------------===//
584 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT,
585 addrMode = AbsoluteSet in
586 class T_ST_abs_set<string mnemonic, RegisterClass RC>:
587             STInst2<(outs IntRegs:$dst1),
588             (ins RC:$src1, u0AlwaysExt:$src2),
589             mnemonic#"($dst1=##$src2) = $src1",
590             []>,
591             Requires<[HasV4T]>;
592
593 def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
594 def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
595 def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
596 def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
597
598 //===----------------------------------------------------------------------===//
599 // multiclass for store instructions with base + register offset addressing
600 // mode
601 //===----------------------------------------------------------------------===//
602 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
603                              bit isPredNew> {
604   let isPredicatedNew = isPredNew in
605   def NAME : STInst2<(outs),
606             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
607                  RC:$src5),
608             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
609             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
610             []>,
611             Requires<[HasV4T]>;
612 }
613
614 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
615   let isPredicatedFalse = PredNot in {
616     defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
617     // Predicate new
618     defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
619   }
620 }
621
622 let isNVStorable = 1 in
623 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
624   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
625     let isPredicable = 1 in
626     def NAME#_V4 : STInst2<(outs),
627             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
628             mnemonic#"($src1+$src2<<#$src3) = $src4",
629             []>,
630             Requires<[HasV4T]>;
631
632     let isPredicated = 1 in {
633       defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
634       defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
635     }
636   }
637 }
638
639 // multiclass for new-value store instructions with base + register offset
640 // addressing mode.
641 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
642                              bit isPredNew> {
643   let isPredicatedNew = isPredNew in
644   def NAME#_nv_V4 : NVInst_V4<(outs),
645             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
646                  RC:$src5),
647             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
648             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
649             []>,
650             Requires<[HasV4T]>;
651 }
652
653 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
654   let isPredicatedFalse = PredNot in {
655     defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
656     // Predicate new
657     defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
658   }
659 }
660
661 let mayStore = 1, isNVStore = 1 in
662 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
663   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
664     let isPredicable = 1 in
665     def NAME#_nv_V4 : NVInst_V4<(outs),
666             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
667             mnemonic#"($src1+$src2<<#$src3) = $src4.new",
668             []>,
669             Requires<[HasV4T]>;
670
671     let isPredicated = 1 in {
672       defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
673       defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
674     }
675   }
676 }
677
678 let addrMode = BaseRegOffset, hasSideEffects = 0,
679 validSubTargets = HasV4SubT in {
680   let accessSize = ByteAccess in
681     defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
682                             ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
683
684   let accessSize = HalfWordAccess in
685     defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
686                             ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
687
688   let accessSize = WordAccess in
689     defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
690                             ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
691
692   let isNVStorable = 0, accessSize = DoubleWordAccess in
693     defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
694 }
695
696 let Predicates = [HasV4T], AddedComplexity = 10 in {
697 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
698                        (add IntRegs:$src1, (shl IntRegs:$src2,
699                                                 u2ImmPred:$src3))),
700           (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
701                                 u2ImmPred:$src3, IntRegs:$src4)>;
702
703 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
704                         (add IntRegs:$src1, (shl IntRegs:$src2,
705                                                  u2ImmPred:$src3))),
706           (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
707                                 u2ImmPred:$src3, IntRegs:$src4)>;
708
709 def : Pat<(store (i32 IntRegs:$src4),
710                  (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
711           (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
712                                 u2ImmPred:$src3, IntRegs:$src4)>;
713
714 def : Pat<(store (i64 DoubleRegs:$src4),
715                 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
716           (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
717                                 u2ImmPred:$src3, DoubleRegs:$src4)>;
718 }
719
720 let isExtended = 1, opExtendable = 2 in
721 class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> :
722             STInst<(outs),
723             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4),
724             mnemonic#"($src1<<#$src2+##$src3) = $src4",
725             [(stOp (VT RC:$src4),
726                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
727                          u0AlwaysExtPred:$src3))]>,
728             Requires<[HasV4T]>;
729
730 let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in
731 class T_ST_LongOff_nv <string mnemonic> :
732             NVInst_V4<(outs),
733             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
734             mnemonic#"($src1<<#$src2+##$src3) = $src4.new",
735             []>,
736             Requires<[HasV4T]>;
737
738 multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> {
739   let  BaseOpcode = BaseOp#"_shl" in {
740     let isNVStorable = 1 in
741     def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>;
742
743     def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>;
744   }
745 }
746
747 let AddedComplexity = 10, validSubTargets = HasV4SubT in {
748   def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>;
749   defm STrib_shl   : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel;
750   defm STrih_shl   : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel;
751   defm STriw_shl   : ST_LongOff <"memw", "STriw", store>, NewValueRel;
752 }
753
754 let AddedComplexity = 40 in
755 multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT,
756                            PatFrag stOp> {
757  def : Pat<(stOp (VT RC:$src4),
758            (add (shl IntRegs:$src1, u2ImmPred:$src2),
759                (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
760            (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
761
762  def : Pat<(stOp (VT RC:$src4),
763            (add IntRegs:$src1,
764                (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
765            (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
766 }
767
768 defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>;
769 defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>;
770 defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>;
771 defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
772
773 // memd(Rx++#s4:3)=Rtt
774 // memd(Rx++#s4:3:circ(Mu))=Rtt
775 // memd(Rx++I:circ(Mu))=Rtt
776 // memd(Rx++Mu)=Rtt
777 // memd(Rx++Mu:brev)=Rtt
778 // memd(gp+#u16:3)=Rtt
779
780 // Store doubleword conditionally.
781 // if ([!]Pv[.new]) memd(#u6)=Rtt
782 // TODO: needs to be implemented.
783
784 //===----------------------------------------------------------------------===//
785 // multiclass for store instructions with base + immediate offset
786 // addressing mode and immediate stored value.
787 // mem[bhw](Rx++#s4:3)=#s8
788 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
789 //===----------------------------------------------------------------------===//
790 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
791                         bit isPredNew> {
792   let isPredicatedNew = isPredNew in
793   def NAME : STInst2<(outs),
794             (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
795             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
796             ") ")#mnemonic#"($src2+#$src3) = #$src4",
797             []>,
798             Requires<[HasV4T]>;
799 }
800
801 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
802   let isPredicatedFalse = PredNot in {
803     defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
804     // Predicate new
805     defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
806   }
807 }
808
809 let isExtendable = 1, isExtentSigned = 1, hasSideEffects = 0 in
810 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
811   let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
812     let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
813     def NAME#_V4 : STInst2<(outs),
814             (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
815             mnemonic#"($src1+#$src2) = #$src3",
816             []>,
817             Requires<[HasV4T]>;
818
819     let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
820       defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
821       defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
822     }
823   }
824 }
825
826 let addrMode = BaseImmOffset, InputType = "imm",
827 validSubTargets = HasV4SubT in {
828   let accessSize = ByteAccess in
829     defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
830
831   let accessSize = HalfWordAccess in
832     defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
833
834   let accessSize = WordAccess in
835     defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
836 }
837
838 let Predicates = [HasV4T], AddedComplexity = 10 in {
839 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
840             (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
841
842 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
843                                               u6_1ImmPred:$src2)),
844             (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
845
846 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
847             (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
848 }
849
850 let AddedComplexity = 6 in
851 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
852            (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
853            Requires<[HasV4T]>;
854
855 // memb(Rx++#s4:0:circ(Mu))=Rt
856 // memb(Rx++I:circ(Mu))=Rt
857 // memb(Rx++Mu)=Rt
858 // memb(Rx++Mu:brev)=Rt
859 // memb(gp+#u16:0)=Rt
860
861
862 // Store halfword.
863 // TODO: needs to be implemented
864 // memh(Re=#U6)=Rt.H
865 // memh(Rs+#s11:1)=Rt.H
866 let AddedComplexity = 6 in
867 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
868            (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
869            Requires<[HasV4T]>;
870
871 // memh(Rs+Ru<<#u2)=Rt.H
872 // TODO: needs to be implemented.
873
874 // memh(Ru<<#u2+#U6)=Rt.H
875 // memh(Rx++#s4:1:circ(Mu))=Rt.H
876 // memh(Rx++#s4:1:circ(Mu))=Rt
877 // memh(Rx++I:circ(Mu))=Rt.H
878 // memh(Rx++I:circ(Mu))=Rt
879 // memh(Rx++Mu)=Rt.H
880 // memh(Rx++Mu)=Rt
881 // memh(Rx++Mu:brev)=Rt.H
882 // memh(Rx++Mu:brev)=Rt
883 // memh(gp+#u16:1)=Rt
884 // if ([!]Pv[.new]) memh(#u6)=Rt.H
885 // if ([!]Pv[.new]) memh(#u6)=Rt
886
887
888 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
889 // TODO: needs to be implemented.
890
891 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
892 // TODO: Needs to be implemented.
893
894 // Store word.
895 // memw(Re=#U6)=Rt
896 // TODO: Needs to be implemented.
897
898 // Store predicate:
899 let hasSideEffects = 0 in
900 def STriw_pred_V4 : STInst2<(outs),
901             (ins MEMri:$addr, PredRegs:$src1),
902             "Error; should not emit",
903             []>,
904             Requires<[HasV4T]>;
905
906 let AddedComplexity = 6 in
907 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
908            (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
909            Requires<[HasV4T]>;
910
911 // memw(Rx++#s4:2)=Rt
912 // memw(Rx++#s4:2:circ(Mu))=Rt
913 // memw(Rx++I:circ(Mu))=Rt
914 // memw(Rx++Mu)=Rt
915 // memw(Rx++Mu:brev)=Rt
916
917 //===----------------------------------------------------------------------===
918 // ST -
919 //===----------------------------------------------------------------------===
920
921
922 //===----------------------------------------------------------------------===//
923 // NV/ST +
924 //===----------------------------------------------------------------------===//
925
926 // multiclass for new-value store instructions with base + immediate offset.
927 //
928 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
929                             Operand predImmOp, bit isNot, bit isPredNew> {
930   let isPredicatedNew = isPredNew in
931   def NAME#_nv_V4 : NVInst_V4<(outs),
932             (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
933             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
934             ") ")#mnemonic#"($src2+#$src3) = $src4.new",
935             []>,
936             Requires<[HasV4T]>;
937 }
938
939 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
940                            bit PredNot> {
941   let isPredicatedFalse = PredNot in {
942     defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
943     // Predicate new
944     defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
945   }
946 }
947
948 let mayStore = 1, isNVStore = 1, hasSideEffects = 0, isExtendable = 1 in
949 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
950                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
951                    bits<5> PredImmBits> {
952
953   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
954     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
955     isPredicable = 1 in
956     def NAME#_nv_V4 : NVInst_V4<(outs),
957             (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
958             mnemonic#"($src1+#$src2) = $src3.new",
959             []>,
960             Requires<[HasV4T]>;
961
962     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
963     isPredicated = 1 in {
964       defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
965       defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
966     }
967   }
968 }
969
970 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
971   let accessSize = ByteAccess in
972     defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
973                                    u6_0Ext, 11, 6>, AddrModeRel;
974
975   let accessSize = HalfWordAccess in
976     defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
977                                    u6_1Ext, 12, 7>, AddrModeRel;
978
979   let accessSize = WordAccess in
980     defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
981                                    u6_2Ext, 13, 8>, AddrModeRel;
982 }
983
984 // multiclass for new-value store instructions with base + immediate offset.
985 // and MEMri operand.
986 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
987                           bit isPredNew> {
988   let isPredicatedNew = isPredNew in
989   def NAME#_nv_V4 : NVInst_V4<(outs),
990             (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
991             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
992             ") ")#mnemonic#"($addr) = $src2.new",
993             []>,
994             Requires<[HasV4T]>;
995 }
996
997 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
998   let isPredicatedFalse = PredNot in {
999     defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
1000
1001     // Predicate new
1002     defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
1003   }
1004 }
1005
1006 let mayStore = 1, isNVStore = 1, isExtendable = 1, hasSideEffects = 0 in
1007 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
1008                     bits<5> ImmBits, bits<5> PredImmBits> {
1009
1010   let CextOpcode = CextOp, BaseOpcode = CextOp in {
1011     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1012          isPredicable = 1 in
1013     def NAME#_nv_V4 : NVInst_V4<(outs),
1014             (ins MEMri:$addr, RC:$src),
1015             mnemonic#"($addr) = $src.new",
1016             []>,
1017             Requires<[HasV4T]>;
1018
1019     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1020         hasSideEffects = 0, isPredicated = 1 in {
1021       defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
1022       defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
1023     }
1024   }
1025 }
1026
1027 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1028 mayStore = 1 in {
1029   let accessSize = ByteAccess in
1030     defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1031
1032   let accessSize = HalfWordAccess in
1033     defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1034
1035   let accessSize = WordAccess in
1036     defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1037 }
1038
1039 //===----------------------------------------------------------------------===//
1040 // Post increment store
1041 // mem[bhwd](Rx++#s4:[0123])=Nt.new
1042 //===----------------------------------------------------------------------===//
1043
1044 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
1045                             bit isNot, bit isPredNew> {
1046   let isPredicatedNew = isPredNew in
1047   def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1048             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1049             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1050             ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1051             [],
1052             "$src2 = $dst">,
1053             Requires<[HasV4T]>;
1054 }
1055
1056 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
1057                            Operand ImmOp, bit PredNot> {
1058   let isPredicatedFalse = PredNot in {
1059     defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
1060     // Predicate new
1061     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1062     defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
1063   }
1064 }
1065
1066 let hasCtrlDep = 1, isNVStore = 1, hasSideEffects = 0 in
1067 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
1068                       Operand ImmOp> {
1069
1070   let BaseOpcode = "POST_"#BaseOp in {
1071     let isPredicable = 1 in
1072     def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1073                 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1074                 mnemonic#"($src1++#$offset) = $src2.new",
1075                 [],
1076                 "$src1 = $dst">,
1077                 Requires<[HasV4T]>;
1078
1079     let isPredicated = 1 in {
1080       defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
1081       defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
1082     }
1083   }
1084 }
1085
1086 let addrMode = PostInc, validSubTargets = HasV4SubT in {
1087 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1088 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1089 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1090 }
1091
1092 // memb(Rx++#s4:0:circ(Mu))=Nt.new
1093 // memb(Rx++I:circ(Mu))=Nt.new
1094 // memb(Rx++Mu)=Nt.new
1095 // memb(Rx++Mu:brev)=Nt.new
1096 // memh(Rx++#s4:1:circ(Mu))=Nt.new
1097 // memh(Rx++I:circ(Mu))=Nt.new
1098 // memh(Rx++Mu)=Nt.new
1099 // memh(Rx++Mu:brev)=Nt.new
1100
1101 // memw(Rx++#s4:2:circ(Mu))=Nt.new
1102 // memw(Rx++I:circ(Mu))=Nt.new
1103 // memw(Rx++Mu)=Nt.new
1104 // memw(Rx++Mu:brev)=Nt.new
1105
1106 //===----------------------------------------------------------------------===//
1107 // NV/ST -
1108 //===----------------------------------------------------------------------===//
1109
1110 //===----------------------------------------------------------------------===//
1111 // NV/J +
1112 //===----------------------------------------------------------------------===//
1113
1114 //===----------------------------------------------------------------------===//
1115 // multiclass/template class for the new-value compare jumps with the register
1116 // operands.
1117 //===----------------------------------------------------------------------===//
1118
1119 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
1120 class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
1121                       bit isNegCond, bit isTak>
1122   : NVInst_V4<(outs),
1123     (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1124     "if ("#!if(isNegCond, "!","")#mnemonic#
1125     "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
1126     "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:"
1127     #!if(isTak, "t","nt")#" $offset",
1128     []>, Requires<[HasV4T]> {
1129
1130       bits<5> src1;
1131       bits<5> src2;
1132       bits<3> Ns;    // New-Value Operand
1133       bits<5> RegOp; // Non-New-Value Operand
1134       bits<11> offset;
1135
1136       let isTaken = isTak;
1137       let isBrTaken = !if(isTaken, "true", "false");
1138       let isPredicatedFalse = isNegCond;
1139
1140       let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
1141       let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
1142
1143       let IClass = 0b0010;
1144       let Inst{26} = 0b0;
1145       let Inst{25-23} = majOp;
1146       let Inst{22} = isNegCond;
1147       let Inst{18-16} = Ns;
1148       let Inst{13} = isTak;
1149       let Inst{12-8} = RegOp;
1150       let Inst{21-20} = offset{10-9};
1151       let Inst{7-1} = offset{8-2};
1152 }
1153
1154
1155 multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
1156                        bit isNegCond> {
1157   // Branch not taken:
1158   def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
1159   // Branch taken:
1160   def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
1161 }
1162
1163 // NvOpNum = 0 -> First Operand is a new-value Register
1164 // NvOpNum = 1 -> Second Operand is a new-value Register
1165
1166 multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
1167                        bit NvOpNum> {
1168   let BaseOpcode = BaseOp#_NVJ in {
1169     defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
1170     defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
1171   }
1172 }
1173
1174 // if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
1175 // if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
1176 // if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
1177 // if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
1178 // if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
1179
1180 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1181   Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT in {
1182   defm CMPEQrr  : NVJrr_base<"cmp.eq",  "CMPEQ",  0b000, 0>, PredRel;
1183   defm CMPGTrr  : NVJrr_base<"cmp.gt",  "CMPGT",  0b001, 0>, PredRel;
1184   defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
1185   defm CMPLTrr  : NVJrr_base<"cmp.gt",  "CMPLT",  0b011, 1>, PredRel;
1186   defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
1187 }
1188
1189 //===----------------------------------------------------------------------===//
1190 // multiclass/template class for the new-value compare jumps instruction
1191 // with a register and an unsigned immediate (U5) operand.
1192 //===----------------------------------------------------------------------===//
1193
1194 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
1195 class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
1196                          bit isTak>
1197   : NVInst_V4<(outs),
1198     (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1199     "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
1200     #!if(isTak, "t","nt")#" $offset",
1201     []>, Requires<[HasV4T]> {
1202
1203       let isTaken = isTak;
1204       let isPredicatedFalse = isNegCond;
1205       let isBrTaken = !if(isTaken, "true", "false");
1206
1207       bits<3> src1;
1208       bits<5> src2;
1209       bits<11> offset;
1210
1211       let IClass = 0b0010;
1212       let Inst{26} = 0b1;
1213       let Inst{25-23} = majOp;
1214       let Inst{22} = isNegCond;
1215       let Inst{18-16} = src1;
1216       let Inst{13} = isTak;
1217       let Inst{12-8} = src2;
1218       let Inst{21-20} = offset{10-9};
1219       let Inst{7-1} = offset{8-2};
1220 }
1221
1222 multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
1223   // Branch not taken:
1224   def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
1225   // Branch taken:
1226   def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
1227 }
1228
1229 multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
1230   let BaseOpcode = BaseOp#_NVJri in {
1231     defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
1232     defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
1233   }
1234 }
1235
1236 // if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2
1237 // if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2
1238 // if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
1239
1240 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1241   Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT in {
1242   defm CMPEQri  : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
1243   defm CMPGTri  : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
1244   defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
1245 }
1246
1247 //===----------------------------------------------------------------------===//
1248 // multiclass/template class for the new-value compare jumps instruction
1249 // with a register and an hardcoded 0/-1 immediate value.
1250 //===----------------------------------------------------------------------===//
1251
1252 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
1253 class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
1254                             bit isNegCond, bit isTak>
1255   : NVInst_V4<(outs),
1256     (ins IntRegs:$src1, brtarget:$offset),
1257     "if ("#!if(isNegCond, "!","")#mnemonic
1258     #"($src1.new, #"#ImmVal#")) jump:"
1259     #!if(isTak, "t","nt")#" $offset",
1260     []>, Requires<[HasV4T]> {
1261
1262       let isTaken = isTak;
1263       let isPredicatedFalse = isNegCond;
1264       let isBrTaken = !if(isTaken, "true", "false");
1265
1266       bits<3> src1;
1267       bits<11> offset;
1268       let IClass = 0b0010;
1269       let Inst{26} = 0b1;
1270       let Inst{25-23} = majOp;
1271       let Inst{22} = isNegCond;
1272       let Inst{18-16} = src1;
1273       let Inst{13} = isTak;
1274       let Inst{21-20} = offset{10-9};
1275       let Inst{7-1} = offset{8-2};
1276 }
1277
1278 multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
1279                              bit isNegCond> {
1280   // Branch not taken:
1281   def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
1282   // Branch taken:
1283   def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
1284 }
1285
1286 multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
1287                              string ImmVal> {
1288   let BaseOpcode = BaseOp#_NVJ_ConstImm in {
1289   defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
1290   defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
1291   }
1292 }
1293
1294 // if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2
1295 // if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2
1296 // if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
1297
1298 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
1299   Defs = [PC], hasSideEffects = 0 in {
1300   defm TSTBIT0  : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
1301   defm CMPEQn1  : NVJ_ConstImm_base<"cmp.eq", "CMPEQ",  0b100, "-1">, PredRel;
1302   defm CMPGTn1  : NVJ_ConstImm_base<"cmp.gt", "CMPGT",  0b101, "-1">, PredRel;
1303 }
1304
1305 //===----------------------------------------------------------------------===//
1306 // XTYPE/ALU +
1307 //===----------------------------------------------------------------------===//
1308
1309 //  Add and accumulate.
1310 //  Rd=add(Rs,add(Ru,#s6))
1311 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
1312 validSubTargets = HasV4SubT in
1313 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
1314           (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
1315           "$dst = add($src1, add($src2, #$src3))",
1316           [(set (i32 IntRegs:$dst),
1317            (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
1318                                           s6_16ExtPred:$src3)))]>,
1319           Requires<[HasV4T]>;
1320
1321 //  Rd=add(Rs,sub(#s6,Ru))
1322 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
1323 validSubTargets = HasV4SubT in
1324 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
1325           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
1326           "$dst = add($src1, sub(#$src2, $src3))",
1327           [(set (i32 IntRegs:$dst),
1328            (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
1329                                           (i32 IntRegs:$src3))))]>,
1330           Requires<[HasV4T]>;
1331
1332 // Generates the same instruction as ADDr_SUBri_V4 but matches different
1333 // pattern.
1334 //  Rd=add(Rs,sub(#s6,Ru))
1335 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
1336 validSubTargets = HasV4SubT in
1337 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
1338           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
1339           "$dst = add($src1, sub(#$src2, $src3))",
1340           [(set (i32 IntRegs:$dst),
1341                 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
1342                      (i32 IntRegs:$src3)))]>,
1343           Requires<[HasV4T]>;
1344
1345
1346 //  Add or subtract doublewords with carry.
1347 //TODO:
1348 //  Rdd=add(Rss,Rtt,Px):carry
1349 //TODO:
1350 //  Rdd=sub(Rss,Rtt,Px):carry
1351
1352
1353 //  Logical doublewords.
1354 //  Rdd=and(Rtt,~Rss)
1355 let validSubTargets = HasV4SubT in
1356 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
1357           (ins DoubleRegs:$src1, DoubleRegs:$src2),
1358           "$dst = and($src1, ~$src2)",
1359           [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
1360                                       (not (i64 DoubleRegs:$src2))))]>,
1361           Requires<[HasV4T]>;
1362
1363 //  Rdd=or(Rtt,~Rss)
1364 let validSubTargets = HasV4SubT in
1365 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
1366           (ins DoubleRegs:$src1, DoubleRegs:$src2),
1367           "$dst = or($src1, ~$src2)",
1368           [(set (i64 DoubleRegs:$dst),
1369            (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
1370           Requires<[HasV4T]>;
1371
1372
1373 //  Logical-logical doublewords.
1374 //  Rxx^=xor(Rss,Rtt)
1375 let validSubTargets = HasV4SubT in
1376 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
1377           (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
1378           "$dst ^= xor($src2, $src3)",
1379           [(set (i64 DoubleRegs:$dst),
1380            (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
1381                                              (i64 DoubleRegs:$src3))))],
1382           "$src1 = $dst">,
1383           Requires<[HasV4T]>;
1384
1385
1386 // Logical-logical words.
1387 // Rx=or(Ru,and(Rx,#s10))
1388 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1389 validSubTargets = HasV4SubT in
1390 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
1391             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1392             "$dst = or($src1, and($src2, #$src3))",
1393             [(set (i32 IntRegs:$dst),
1394                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1395                                                 s10ExtPred:$src3)))],
1396             "$src2 = $dst">,
1397             Requires<[HasV4T]>;
1398
1399 // Rx[&|^]=and(Rs,Rt)
1400 // Rx&=and(Rs,Rt)
1401 let validSubTargets = HasV4SubT in
1402 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1403             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1404             "$dst &= and($src2, $src3)",
1405             [(set (i32 IntRegs:$dst),
1406                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1407                                                  (i32 IntRegs:$src3))))],
1408             "$src1 = $dst">,
1409             Requires<[HasV4T]>;
1410
1411 // Rx|=and(Rs,Rt)
1412 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
1413 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1414             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1415             "$dst |= and($src2, $src3)",
1416             [(set (i32 IntRegs:$dst),
1417                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1418                                                 (i32 IntRegs:$src3))))],
1419             "$src1 = $dst">,
1420             Requires<[HasV4T]>, ImmRegRel;
1421
1422 // Rx^=and(Rs,Rt)
1423 let validSubTargets = HasV4SubT in
1424 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1425             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1426             "$dst ^= and($src2, $src3)",
1427             [(set (i32 IntRegs:$dst),
1428              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1429                                             (i32 IntRegs:$src3))))],
1430             "$src1 = $dst">,
1431             Requires<[HasV4T]>;
1432
1433 // Rx[&|^]=and(Rs,~Rt)
1434 // Rx&=and(Rs,~Rt)
1435 let validSubTargets = HasV4SubT in
1436 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1437             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1438             "$dst &= and($src2, ~$src3)",
1439             [(set (i32 IntRegs:$dst),
1440                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1441                                                  (not (i32 IntRegs:$src3)))))],
1442             "$src1 = $dst">,
1443             Requires<[HasV4T]>;
1444
1445 // Rx|=and(Rs,~Rt)
1446 let validSubTargets = HasV4SubT in
1447 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1448             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1449             "$dst |= and($src2, ~$src3)",
1450             [(set (i32 IntRegs:$dst),
1451              (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1452                                            (not (i32 IntRegs:$src3)))))],
1453             "$src1 = $dst">,
1454             Requires<[HasV4T]>;
1455
1456 // Rx^=and(Rs,~Rt)
1457 let validSubTargets = HasV4SubT in
1458 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1459             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1460             "$dst ^= and($src2, ~$src3)",
1461             [(set (i32 IntRegs:$dst),
1462              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1463                                             (not (i32 IntRegs:$src3)))))],
1464             "$src1 = $dst">,
1465             Requires<[HasV4T]>;
1466
1467 // Rx[&|^]=or(Rs,Rt)
1468 // Rx&=or(Rs,Rt)
1469 let validSubTargets = HasV4SubT in
1470 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1471             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1472             "$dst &= or($src2, $src3)",
1473             [(set (i32 IntRegs:$dst),
1474                   (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1475                                                 (i32 IntRegs:$src3))))],
1476             "$src1 = $dst">,
1477             Requires<[HasV4T]>;
1478
1479 // Rx|=or(Rs,Rt)
1480 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
1481 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1482             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1483             "$dst |= or($src2, $src3)",
1484             [(set (i32 IntRegs:$dst),
1485                   (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1486                                                (i32 IntRegs:$src3))))],
1487             "$src1 = $dst">,
1488             Requires<[HasV4T]>, ImmRegRel;
1489
1490 // Rx^=or(Rs,Rt)
1491 let validSubTargets = HasV4SubT in
1492 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1493             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1494             "$dst ^= or($src2, $src3)",
1495             [(set (i32 IntRegs:$dst),
1496              (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1497                                            (i32 IntRegs:$src3))))],
1498             "$src1 = $dst">,
1499             Requires<[HasV4T]>;
1500
1501 // Rx[&|^]=xor(Rs,Rt)
1502 // Rx&=xor(Rs,Rt)
1503 let validSubTargets = HasV4SubT in
1504 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1505             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1506             "$dst &= xor($src2, $src3)",
1507             [(set (i32 IntRegs:$dst),
1508                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1509                                                  (i32 IntRegs:$src3))))],
1510             "$src1 = $dst">,
1511             Requires<[HasV4T]>;
1512
1513 // Rx|=xor(Rs,Rt)
1514 let validSubTargets = HasV4SubT in
1515 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1516             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1517             "$dst |= xor($src2, $src3)",
1518             [(set (i32 IntRegs:$dst),
1519                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1520                                                  (i32 IntRegs:$src3))))],
1521             "$src1 = $dst">,
1522             Requires<[HasV4T]>;
1523
1524 // Rx^=xor(Rs,Rt)
1525 let validSubTargets = HasV4SubT in
1526 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1527             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1528             "$dst ^= xor($src2, $src3)",
1529             [(set (i32 IntRegs:$dst),
1530              (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1531                                             (i32 IntRegs:$src3))))],
1532             "$src1 = $dst">,
1533             Requires<[HasV4T]>;
1534
1535 // Rx|=and(Rs,#s10)
1536 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1537 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
1538 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
1539             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1540             "$dst |= and($src2, #$src3)",
1541             [(set (i32 IntRegs:$dst),
1542                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1543                                                 s10ExtPred:$src3)))],
1544             "$src1 = $dst">,
1545             Requires<[HasV4T]>, ImmRegRel;
1546
1547 // Rx|=or(Rs,#s10)
1548 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1549 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
1550 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
1551             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1552             "$dst |= or($src2, #$src3)",
1553             [(set (i32 IntRegs:$dst),
1554                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1555                                                 s10ExtPred:$src3)))],
1556             "$src1 = $dst">,
1557             Requires<[HasV4T]>, ImmRegRel;
1558
1559
1560 //    Modulo wrap
1561 //        Rd=modwrap(Rs,Rt)
1562 //    Round
1563 //        Rd=cround(Rs,#u5)
1564 //        Rd=cround(Rs,Rt)
1565 //        Rd=round(Rs,#u5)[:sat]
1566 //        Rd=round(Rs,Rt)[:sat]
1567 //    Vector reduce add unsigned halfwords
1568 //        Rd=vraddh(Rss,Rtt)
1569 //    Vector add bytes
1570 //        Rdd=vaddb(Rss,Rtt)
1571 //    Vector conditional negate
1572 //        Rdd=vcnegh(Rss,Rt)
1573 //        Rxx+=vrcnegh(Rss,Rt)
1574 //    Vector maximum bytes
1575 //        Rdd=vmaxb(Rtt,Rss)
1576 //    Vector reduce maximum halfwords
1577 //        Rxx=vrmaxh(Rss,Ru)
1578 //        Rxx=vrmaxuh(Rss,Ru)
1579 //    Vector reduce maximum words
1580 //        Rxx=vrmaxuw(Rss,Ru)
1581 //        Rxx=vrmaxw(Rss,Ru)
1582 //    Vector minimum bytes
1583 //        Rdd=vminb(Rtt,Rss)
1584 //    Vector reduce minimum halfwords
1585 //        Rxx=vrminh(Rss,Ru)
1586 //        Rxx=vrminuh(Rss,Ru)
1587 //    Vector reduce minimum words
1588 //        Rxx=vrminuw(Rss,Ru)
1589 //        Rxx=vrminw(Rss,Ru)
1590 //    Vector subtract bytes
1591 //        Rdd=vsubb(Rss,Rtt)
1592
1593 //===----------------------------------------------------------------------===//
1594 // XTYPE/ALU -
1595 //===----------------------------------------------------------------------===//
1596
1597
1598 //===----------------------------------------------------------------------===//
1599 // XTYPE/MPY +
1600 //===----------------------------------------------------------------------===//
1601
1602 // Multiply and user lower result.
1603 // Rd=add(#u6,mpyi(Rs,#U6))
1604 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
1605 validSubTargets = HasV4SubT in
1606 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
1607             (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
1608             "$dst = add(#$src1, mpyi($src2, #$src3))",
1609             [(set (i32 IntRegs:$dst),
1610                   (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
1611                        u6ExtPred:$src1))]>,
1612             Requires<[HasV4T]>;
1613
1614 // Rd=add(##,mpyi(Rs,#U6))
1615 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
1616                      (HexagonCONST32 tglobaladdr:$src1)),
1617            (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
1618                                u6ImmPred:$src3))>;
1619
1620 // Rd=add(#u6,mpyi(Rs,Rt))
1621 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
1622 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
1623 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
1624             (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
1625             "$dst = add(#$src1, mpyi($src2, $src3))",
1626             [(set (i32 IntRegs:$dst),
1627                   (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1628                        u6ExtPred:$src1))]>,
1629             Requires<[HasV4T]>, ImmRegRel;
1630
1631 // Rd=add(##,mpyi(Rs,Rt))
1632 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1633                      (HexagonCONST32 tglobaladdr:$src1)),
1634            (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
1635                                IntRegs:$src3))>;
1636
1637 // Rd=add(Ru,mpyi(#u6:2,Rs))
1638 let validSubTargets = HasV4SubT in
1639 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
1640             (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
1641             "$dst = add($src1, mpyi(#$src2, $src3))",
1642             [(set (i32 IntRegs:$dst),
1643              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
1644                                             u6_2ImmPred:$src2)))]>,
1645             Requires<[HasV4T]>;
1646
1647 // Rd=add(Ru,mpyi(Rs,#u6))
1648 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
1649 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
1650 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
1651             (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
1652             "$dst = add($src1, mpyi($src2, #$src3))",
1653             [(set (i32 IntRegs:$dst),
1654                   (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1655                                                  u6ExtPred:$src3)))]>,
1656             Requires<[HasV4T]>, ImmRegRel;
1657
1658 // Rx=add(Ru,mpyi(Rx,Rs))
1659 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
1660 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
1661             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1662             "$dst = add($src1, mpyi($src2, $src3))",
1663             [(set (i32 IntRegs:$dst),
1664              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1665                                             (i32 IntRegs:$src3))))],
1666             "$src2 = $dst">,
1667             Requires<[HasV4T]>, ImmRegRel;
1668
1669
1670 // Polynomial multiply words
1671 // Rdd=pmpyw(Rs,Rt)
1672 // Rxx^=pmpyw(Rs,Rt)
1673
1674 // Vector reduce multiply word by signed half (32x16)
1675 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
1676 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
1677 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
1678 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
1679
1680 // Multiply and use upper result
1681 // Rd=mpy(Rs,Rt.H):<<1:sat
1682 // Rd=mpy(Rs,Rt.L):<<1:sat
1683 // Rd=mpy(Rs,Rt):<<1
1684 // Rd=mpy(Rs,Rt):<<1:sat
1685 // Rd=mpysu(Rs,Rt)
1686 // Rx+=mpy(Rs,Rt):<<1:sat
1687 // Rx-=mpy(Rs,Rt):<<1:sat
1688
1689 // Vector multiply bytes
1690 // Rdd=vmpybsu(Rs,Rt)
1691 // Rdd=vmpybu(Rs,Rt)
1692 // Rxx+=vmpybsu(Rs,Rt)
1693 // Rxx+=vmpybu(Rs,Rt)
1694
1695 // Vector polynomial multiply halfwords
1696 // Rdd=vpmpyh(Rs,Rt)
1697 // Rxx^=vpmpyh(Rs,Rt)
1698
1699 //===----------------------------------------------------------------------===//
1700 // XTYPE/MPY -
1701 //===----------------------------------------------------------------------===//
1702
1703
1704 //===----------------------------------------------------------------------===//
1705 // XTYPE/SHIFT +
1706 //===----------------------------------------------------------------------===//
1707
1708 // Shift by immediate and accumulate.
1709 // Rx=add(#u8,asl(Rx,#U5))
1710 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1711 validSubTargets = HasV4SubT in
1712 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1713             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1714             "$dst = add(#$src1, asl($src2, #$src3))",
1715             [(set (i32 IntRegs:$dst),
1716                   (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1717                        u8ExtPred:$src1))],
1718             "$src2 = $dst">,
1719             Requires<[HasV4T]>;
1720
1721 // Rx=add(#u8,lsr(Rx,#U5))
1722 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1723 validSubTargets = HasV4SubT in
1724 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1725             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1726             "$dst = add(#$src1, lsr($src2, #$src3))",
1727             [(set (i32 IntRegs:$dst),
1728                   (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1729                        u8ExtPred:$src1))],
1730             "$src2 = $dst">,
1731             Requires<[HasV4T]>;
1732
1733 // Rx=sub(#u8,asl(Rx,#U5))
1734 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1735 validSubTargets = HasV4SubT in
1736 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1737             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1738             "$dst = sub(#$src1, asl($src2, #$src3))",
1739             [(set (i32 IntRegs:$dst),
1740                   (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1741                        u8ExtPred:$src1))],
1742             "$src2 = $dst">,
1743             Requires<[HasV4T]>;
1744
1745 // Rx=sub(#u8,lsr(Rx,#U5))
1746 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1747 validSubTargets = HasV4SubT in
1748 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1749             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1750             "$dst = sub(#$src1, lsr($src2, #$src3))",
1751             [(set (i32 IntRegs:$dst),
1752                   (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1753                        u8ExtPred:$src1))],
1754             "$src2 = $dst">,
1755             Requires<[HasV4T]>;
1756
1757
1758 //Shift by immediate and logical.
1759 //Rx=and(#u8,asl(Rx,#U5))
1760 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1761 validSubTargets = HasV4SubT in
1762 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1763             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1764             "$dst = and(#$src1, asl($src2, #$src3))",
1765             [(set (i32 IntRegs:$dst),
1766                   (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1767                        u8ExtPred:$src1))],
1768             "$src2 = $dst">,
1769             Requires<[HasV4T]>;
1770
1771 //Rx=and(#u8,lsr(Rx,#U5))
1772 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1773 validSubTargets = HasV4SubT in
1774 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1775             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1776             "$dst = and(#$src1, lsr($src2, #$src3))",
1777             [(set (i32 IntRegs:$dst),
1778                   (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1779                        u8ExtPred:$src1))],
1780             "$src2 = $dst">,
1781             Requires<[HasV4T]>;
1782
1783 //Rx=or(#u8,asl(Rx,#U5))
1784 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1785 AddedComplexity = 30, validSubTargets = HasV4SubT in
1786 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1787             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1788             "$dst = or(#$src1, asl($src2, #$src3))",
1789             [(set (i32 IntRegs:$dst),
1790                   (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1791                       u8ExtPred:$src1))],
1792             "$src2 = $dst">,
1793             Requires<[HasV4T]>;
1794
1795 //Rx=or(#u8,lsr(Rx,#U5))
1796 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1797 AddedComplexity = 30, validSubTargets = HasV4SubT in
1798 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1799             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1800             "$dst = or(#$src1, lsr($src2, #$src3))",
1801             [(set (i32 IntRegs:$dst),
1802                   (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1803                       u8ExtPred:$src1))],
1804             "$src2 = $dst">,
1805             Requires<[HasV4T]>;
1806
1807
1808 //Shift by register.
1809 //Rd=lsl(#s6,Rt)
1810 let validSubTargets = HasV4SubT in {
1811 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
1812             "$dst = lsl(#$src1, $src2)",
1813             [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
1814                                            (i32 IntRegs:$src2)))]>,
1815             Requires<[HasV4T]>;
1816
1817
1818 //Shift by register and logical.
1819 //Rxx^=asl(Rss,Rt)
1820 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1821             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1822             "$dst ^= asl($src2, $src3)",
1823             [(set (i64 DoubleRegs:$dst),
1824                   (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
1825                                                     (i32 IntRegs:$src3))))],
1826             "$src1 = $dst">,
1827             Requires<[HasV4T]>;
1828
1829 //Rxx^=asr(Rss,Rt)
1830 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1831             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1832             "$dst ^= asr($src2, $src3)",
1833             [(set (i64 DoubleRegs:$dst),
1834                   (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
1835                                                     (i32 IntRegs:$src3))))],
1836             "$src1 = $dst">,
1837             Requires<[HasV4T]>;
1838
1839 //Rxx^=lsl(Rss,Rt)
1840 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1841             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1842             "$dst ^= lsl($src2, $src3)",
1843             [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
1844                                               (shl (i64 DoubleRegs:$src2),
1845                                                    (i32 IntRegs:$src3))))],
1846             "$src1 = $dst">,
1847             Requires<[HasV4T]>;
1848
1849 //Rxx^=lsr(Rss,Rt)
1850 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1851             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1852             "$dst ^= lsr($src2, $src3)",
1853             [(set (i64 DoubleRegs:$dst),
1854                   (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
1855                                                     (i32 IntRegs:$src3))))],
1856             "$src1 = $dst">,
1857             Requires<[HasV4T]>;
1858 }
1859
1860 //===----------------------------------------------------------------------===//
1861 // XTYPE/SHIFT -
1862 //===----------------------------------------------------------------------===//
1863
1864 //===----------------------------------------------------------------------===//
1865 // MEMOP: Word, Half, Byte
1866 //===----------------------------------------------------------------------===//
1867
1868 def MEMOPIMM : SDNodeXForm<imm, [{
1869   // Call the transformation function XformM5ToU5Imm to get the negative
1870   // immediate's positive counterpart.
1871   int32_t imm = N->getSExtValue();
1872   return XformM5ToU5Imm(imm);
1873 }]>;
1874
1875 def MEMOPIMM_HALF : SDNodeXForm<imm, [{
1876   // -1 .. -31 represented as 65535..65515
1877   // assigning to a short restores our desired signed value.
1878   // Call the transformation function XformM5ToU5Imm to get the negative
1879   // immediate's positive counterpart.
1880   int16_t imm = N->getSExtValue();
1881   return XformM5ToU5Imm(imm);
1882 }]>;
1883
1884 def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
1885   // -1 .. -31 represented as 255..235
1886   // assigning to a char restores our desired signed value.
1887   // Call the transformation function XformM5ToU5Imm to get the negative
1888   // immediate's positive counterpart.
1889   int8_t imm = N->getSExtValue();
1890   return XformM5ToU5Imm(imm);
1891 }]>;
1892
1893 def SETMEMIMM : SDNodeXForm<imm, [{
1894    // Return the bit position we will set [0-31].
1895    // As an SDNode.
1896    int32_t imm = N->getSExtValue();
1897    return XformMskToBitPosU5Imm(imm);
1898 }]>;
1899
1900 def CLRMEMIMM : SDNodeXForm<imm, [{
1901    // Return the bit position we will clear [0-31].
1902    // As an SDNode.
1903    // we bit negate the value first
1904    int32_t imm = ~(N->getSExtValue());
1905    return XformMskToBitPosU5Imm(imm);
1906 }]>;
1907
1908 def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
1909    // Return the bit position we will set [0-15].
1910    // As an SDNode.
1911    int16_t imm = N->getSExtValue();
1912    return XformMskToBitPosU4Imm(imm);
1913 }]>;
1914
1915 def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
1916    // Return the bit position we will clear [0-15].
1917    // As an SDNode.
1918    // we bit negate the value first
1919    int16_t imm = ~(N->getSExtValue());
1920    return XformMskToBitPosU4Imm(imm);
1921 }]>;
1922
1923 def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
1924    // Return the bit position we will set [0-7].
1925    // As an SDNode.
1926    int8_t imm =  N->getSExtValue();
1927    return XformMskToBitPosU3Imm(imm);
1928 }]>;
1929
1930 def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
1931    // Return the bit position we will clear [0-7].
1932    // As an SDNode.
1933    // we bit negate the value first
1934    int8_t imm = ~(N->getSExtValue());
1935    return XformMskToBitPosU3Imm(imm);
1936 }]>;
1937
1938 //===----------------------------------------------------------------------===//
1939 // Template class for MemOp instructions with the register value.
1940 //===----------------------------------------------------------------------===//
1941 class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
1942                      string memOp, bits<2> memOpBits> :
1943       MEMInst_V4<(outs),
1944                  (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
1945                  opc#"($base+#$offset)"#memOp#"$delta",
1946                  []>,
1947                  Requires<[HasV4T, UseMEMOP]> {
1948
1949     bits<5> base;
1950     bits<5> delta;
1951     bits<32> offset;
1952     bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
1953
1954     let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
1955                      !if (!eq(opcBits, 0b01), offset{6-1},
1956                      !if (!eq(opcBits, 0b10), offset{7-2},0)));
1957
1958     let IClass = 0b0011;
1959     let Inst{27-24} = 0b1110;
1960     let Inst{22-21} = opcBits;
1961     let Inst{20-16} = base;
1962     let Inst{13} = 0b0;
1963     let Inst{12-7} = offsetBits;
1964     let Inst{6-5} = memOpBits;
1965     let Inst{4-0} = delta;
1966 }
1967
1968 //===----------------------------------------------------------------------===//
1969 // Template class for MemOp instructions with the immediate value.
1970 //===----------------------------------------------------------------------===//
1971 class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
1972                      string memOp, bits<2> memOpBits> :
1973       MEMInst_V4 <(outs),
1974                   (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
1975                   opc#"($base+#$offset)"#memOp#"#$delta"
1976                   #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
1977                   []>,
1978                   Requires<[HasV4T, UseMEMOP]> {
1979
1980     bits<5> base;
1981     bits<5> delta;
1982     bits<32> offset;
1983     bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
1984
1985     let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
1986                      !if (!eq(opcBits, 0b01), offset{6-1},
1987                      !if (!eq(opcBits, 0b10), offset{7-2},0)));
1988
1989     let IClass = 0b0011;
1990     let Inst{27-24} = 0b1111;
1991     let Inst{22-21} = opcBits;
1992     let Inst{20-16} = base;
1993     let Inst{13} = 0b0;
1994     let Inst{12-7} = offsetBits;
1995     let Inst{6-5} = memOpBits;
1996     let Inst{4-0} = delta;
1997 }
1998
1999 // multiclass to define MemOp instructions with register operand.
2000 multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
2001   def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
2002   def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
2003   def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
2004   def _OR#NAME#_V4  : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
2005 }
2006
2007 // multiclass to define MemOp instructions with immediate Operand.
2008 multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
2009   def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
2010   def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
2011   def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
2012   def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
2013 }
2014
2015 multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
2016   defm r : MemOp_rr <opc, opcBits, ImmOp>;
2017   defm i : MemOp_ri <opc, opcBits, ImmOp>;
2018 }
2019
2020 // Define MemOp instructions.
2021 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
2022 validSubTargets =HasV4SubT in {
2023   let opExtentBits = 6, accessSize = ByteAccess in
2024   defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
2025
2026   let opExtentBits = 7, accessSize = HalfWordAccess in
2027   defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
2028
2029   let opExtentBits = 8, accessSize = WordAccess in
2030   defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
2031 }
2032
2033 //===----------------------------------------------------------------------===//
2034 // Multiclass to define 'Def Pats' for ALU operations on the memory
2035 // Here value used for the ALU operation is an immediate value.
2036 // mem[bh](Rs+#0) += #U5
2037 // mem[bh](Rs+#u6) += #U5
2038 //===----------------------------------------------------------------------===//
2039
2040 multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
2041                           InstHexagon MI, SDNode OpNode> {
2042   let AddedComplexity = 180 in
2043   def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
2044                     IntRegs:$addr),
2045               (MI IntRegs:$addr, #0, u5ImmPred:$addend )>;
2046
2047   let AddedComplexity = 190 in
2048   def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)),
2049                      u5ImmPred:$addend),
2050              (add IntRegs:$base, ExtPred:$offset)),
2051        (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>;
2052 }
2053
2054 multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
2055                           InstHexagon addMI, InstHexagon subMI> {
2056   defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>;
2057   defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>;
2058 }
2059
2060 multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2061   // Half Word
2062   defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
2063                          MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
2064   // Byte
2065   defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
2066                          MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
2067 }
2068
2069 let Predicates = [HasV4T, UseMEMOP] in {
2070   defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
2071   defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
2072   defm : MemOpi_u5ExtType<extloadi8,  extloadi16>;  // any extend
2073
2074   // Word
2075   defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
2076                          MemOPw_SUBi_V4>;
2077 }
2078
2079 //===----------------------------------------------------------------------===//
2080 // multiclass to define 'Def Pats' for ALU operations on the memory.
2081 // Here value used for the ALU operation is a negative value.
2082 // mem[bh](Rs+#0) += #m5
2083 // mem[bh](Rs+#u6) += #m5
2084 //===----------------------------------------------------------------------===//
2085
2086 multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
2087                           PatLeaf immPred, ComplexPattern addrPred,
2088                           SDNodeXForm xformFunc, InstHexagon MI> {
2089   let AddedComplexity = 190 in
2090   def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend),
2091                    IntRegs:$addr),
2092              (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>;
2093
2094   let AddedComplexity = 195 in
2095   def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)),
2096                        immPred:$subend),
2097                   (add IntRegs:$base, extPred:$offset)),
2098             (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>;
2099 }
2100
2101 multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2102   // Half Word
2103   defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
2104                         ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
2105   // Byte
2106   defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
2107                         ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
2108 }
2109
2110 let Predicates = [HasV4T, UseMEMOP] in {
2111   defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
2112   defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
2113   defm : MemOpi_m5ExtType<extloadi8,  extloadi16>;  // any extend
2114
2115   // Word
2116   defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
2117                           ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
2118 }
2119
2120 //===----------------------------------------------------------------------===//
2121 // Multiclass to define 'def Pats' for bit operations on the memory.
2122 // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
2123 // mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
2124 //===----------------------------------------------------------------------===//
2125
2126 multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
2127                      PatLeaf extPred, ComplexPattern addrPred,
2128                      SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> {
2129
2130   // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
2131   let AddedComplexity = 250 in
2132   def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
2133                           immPred:$bitend),
2134                   (add IntRegs:$base, extPred:$offset)),
2135             (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
2136
2137   // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
2138   let AddedComplexity = 225 in
2139   def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)),
2140                            immPred:$bitend),
2141                    (addrPred (i32 IntRegs:$addr), extPred:$offset)),
2142              (MI IntRegs:$addr, extPred:$offset, (xformFunc immPred:$bitend))>;
2143 }
2144
2145 multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2146   // Byte - clrbit
2147   defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
2148                        ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
2149   // Byte - setbit
2150   defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred,  u6ExtPred,
2151                        ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
2152   // Half Word - clrbit
2153   defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
2154                        ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
2155   // Half Word - setbit
2156   defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
2157                        ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
2158 }
2159
2160 let Predicates = [HasV4T, UseMEMOP] in {
2161   // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
2162   // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
2163   defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
2164   defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
2165   defm : MemOpi_bitExtType<extloadi8,  extloadi16>;  // any extend
2166
2167   // memw(Rs+#0) = [clrbit|setbit](#U5)
2168   // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
2169   defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
2170                        CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
2171   defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
2172                        SETMEMIMM, MemOPw_SETBITi_V4, or>;
2173 }
2174
2175 //===----------------------------------------------------------------------===//
2176 // Multiclass to define 'def Pats' for ALU operations on the memory
2177 // where addend is a register.
2178 // mem[bhw](Rs+#0) [+-&|]= Rt
2179 // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
2180 //===----------------------------------------------------------------------===//
2181
2182 multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred,
2183                      PatLeaf extPred, InstHexagon MI, SDNode OpNode> {
2184   let AddedComplexity = 141 in
2185   // mem[bhw](Rs+#0) [+-&|]= Rt
2186   def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)),
2187                            (i32 IntRegs:$addend)),
2188                    (addrPred (i32 IntRegs:$addr), extPred:$offset)),
2189              (MI IntRegs:$addr, extPred:$offset, (i32 IntRegs:$addend) )>;
2190
2191   // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
2192   let AddedComplexity = 150 in
2193   def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
2194                            (i32 IntRegs:$orend)),
2195                    (add IntRegs:$base, extPred:$offset)),
2196              (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>;
2197 }
2198
2199 multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
2200                         ComplexPattern addrPred, PatLeaf extPred,
2201                         InstHexagon addMI, InstHexagon subMI,
2202                         InstHexagon andMI, InstHexagon orMI > {
2203
2204   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>;
2205   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>;
2206   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>;
2207   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI,  or>;
2208 }
2209
2210 multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2211   // Half Word
2212   defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
2213                        MemOPh_ADDr_V4, MemOPh_SUBr_V4,
2214                        MemOPh_ANDr_V4, MemOPh_ORr_V4>;
2215   // Byte
2216   defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
2217                        MemOPb_ADDr_V4, MemOPb_SUBr_V4,
2218                        MemOPb_ANDr_V4, MemOPb_ORr_V4>;
2219 }
2220
2221 // Define 'def Pats' for MemOps with register addend.
2222 let Predicates = [HasV4T, UseMEMOP] in {
2223   // Byte, Half Word
2224   defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
2225   defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
2226   defm : MemOPr_ExtType<extloadi8,  extloadi16>;  // any extend
2227   // Word
2228   defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
2229                        MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
2230 }
2231
2232 //===----------------------------------------------------------------------===//
2233 // XTYPE/PRED +
2234 //===----------------------------------------------------------------------===//
2235
2236 // Hexagon V4 only supports these flavors of byte/half compare instructions:
2237 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
2238 // hardware. However, compiler can still implement these patterns through
2239 // appropriate patterns combinations based on current implemented patterns.
2240 // The implemented patterns are: EQ/GT/GTU.
2241 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
2242
2243 // Following instruction is not being extended as it results into the
2244 // incorrect code for negative numbers.
2245 // Pd=cmpb.eq(Rs,#u8)
2246
2247 let isCompare = 1, isExtendable = 1, opExtendable = 2, hasSideEffects = 0,
2248     validSubTargets = HasV4SubT in
2249 class CMP_NOT_REG_IMM<string OpName, bits<2> op, Operand ImmOp,
2250                       list<dag> Pattern>
2251   : ALU32Inst <(outs PredRegs:$dst), (ins IntRegs:$src1, ImmOp:$src2),
2252     "$dst = !cmp."#OpName#"($src1, #$src2)",
2253     Pattern,
2254     "", ALU32_2op_tc_2early_SLOT0123> {
2255     bits<2> dst;
2256     bits<5> src1;
2257     bits<10> src2;
2258
2259     let IClass = 0b0111;
2260     let Inst{27-24} = 0b0101;
2261     let Inst{23-22} = op;
2262     let Inst{20-16} = src1;
2263     let Inst{21} = !if (!eq(OpName, "gtu"), 0b0, src2{9});
2264     let Inst{13-5} = src2{8-0};
2265     let Inst{4-2} = 0b100;
2266     let Inst{1-0} = dst;
2267 }
2268
2269 let opExtentBits = 10, isExtentSigned = 1 in {
2270 def C4_cmpneqi : CMP_NOT_REG_IMM <"eq", 0b00, s10Ext, [(set (i1 PredRegs:$dst),
2271                  (setne (i32 IntRegs:$src1), s10ExtPred:$src2))]>;
2272
2273 def C4_cmpltei : CMP_NOT_REG_IMM <"gt", 0b01, s10Ext, [(set (i1 PredRegs:$dst),
2274                  (not (setgt (i32 IntRegs:$src1), s10ExtPred:$src2)))]>;
2275
2276 }
2277 let opExtentBits = 9 in
2278 def C4_cmplteui : CMP_NOT_REG_IMM <"gtu", 0b10, u9Ext, [(set (i1 PredRegs:$dst),
2279                   (not (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)))]>;
2280
2281
2282
2283 // p=!cmp.eq(r1,r2)
2284 let isCompare = 1, validSubTargets = HasV4SubT in
2285 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
2286                            (ins IntRegs:$src1, IntRegs:$src2),
2287       "$dst = !cmp.eq($src1, $src2)",
2288       [(set (i1 PredRegs:$dst),
2289             (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
2290       Requires<[HasV4T]>;
2291
2292 // p=!cmp.gt(r1,r2)
2293 let isCompare = 1, validSubTargets = HasV4SubT in
2294 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
2295                            (ins IntRegs:$src1, IntRegs:$src2),
2296       "$dst = !cmp.gt($src1, $src2)",
2297       [(set (i1 PredRegs:$dst),
2298             (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
2299       Requires<[HasV4T]>;
2300
2301
2302 // p=!cmp.gtu(r1,r2)
2303 let isCompare = 1, validSubTargets = HasV4SubT in
2304 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
2305                             (ins IntRegs:$src1, IntRegs:$src2),
2306       "$dst = !cmp.gtu($src1, $src2)",
2307       [(set (i1 PredRegs:$dst),
2308             (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
2309       Requires<[HasV4T]>;
2310
2311 let isCompare = 1, validSubTargets = HasV4SubT in
2312 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
2313             (ins IntRegs:$src1, u8Imm:$src2),
2314             "$dst = cmpb.eq($src1, #$src2)",
2315             [(set (i1 PredRegs:$dst),
2316                   (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
2317             Requires<[HasV4T]>;
2318
2319 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
2320                        bb:$offset),
2321       (J2_jumpf (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
2322                 bb:$offset)>,
2323       Requires<[HasV4T]>;
2324
2325 // Pd=cmpb.eq(Rs,Rt)
2326 let isCompare = 1, validSubTargets = HasV4SubT in
2327 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
2328             (ins IntRegs:$src1, IntRegs:$src2),
2329             "$dst = cmpb.eq($src1, $src2)",
2330             [(set (i1 PredRegs:$dst),
2331                   (seteq (and (xor (i32 IntRegs:$src1),
2332                                    (i32 IntRegs:$src2)), 255), 0))]>,
2333             Requires<[HasV4T]>;
2334
2335 // Pd=cmpb.eq(Rs,Rt)
2336 let isCompare = 1, validSubTargets = HasV4SubT in
2337 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
2338             (ins IntRegs:$src1, IntRegs:$src2),
2339             "$dst = cmpb.eq($src1, $src2)",
2340             [(set (i1 PredRegs:$dst),
2341                   (seteq (shl (i32 IntRegs:$src1), (i32 24)),
2342                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
2343             Requires<[HasV4T]>;
2344
2345 // Pd=cmpb.gt(Rs,Rt)
2346 let isCompare = 1, validSubTargets = HasV4SubT in
2347 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
2348             (ins IntRegs:$src1, IntRegs:$src2),
2349             "$dst = cmpb.gt($src1, $src2)",
2350             [(set (i1 PredRegs:$dst),
2351                   (setgt (shl (i32 IntRegs:$src1), (i32 24)),
2352                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
2353             Requires<[HasV4T]>;
2354
2355 // Pd=cmpb.gtu(Rs,#u7)
2356 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
2357 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
2358 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
2359             (ins IntRegs:$src1, u7Ext:$src2),
2360             "$dst = cmpb.gtu($src1, #$src2)",
2361             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
2362                                               u7ExtPred:$src2))]>,
2363             Requires<[HasV4T]>, ImmRegRel;
2364
2365 // SDNode for converting immediate C to C-1.
2366 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
2367    // Return the byte immediate const-1 as an SDNode.
2368    int32_t imm = N->getSExtValue();
2369    return XformU7ToU7M1Imm(imm);
2370 }]>;
2371
2372 // For the sequence
2373 //   zext( seteq ( and(Rs, 255), u8))
2374 // Generate
2375 //   Pd=cmpb.eq(Rs, #u8)
2376 //   if (Pd.new) Rd=#1
2377 //   if (!Pd.new) Rd=#0
2378 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
2379                                            u8ExtPred:$u8)))),
2380            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
2381                                                  (u8ExtPred:$u8))),
2382                                 1, 0))>,
2383            Requires<[HasV4T]>;
2384
2385 // For the sequence
2386 //   zext( setne ( and(Rs, 255), u8))
2387 // Generate
2388 //   Pd=cmpb.eq(Rs, #u8)
2389 //   if (Pd.new) Rd=#0
2390 //   if (!Pd.new) Rd=#1
2391 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
2392                                            u8ExtPred:$u8)))),
2393            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
2394                                                  (u8ExtPred:$u8))),
2395                                 0, 1))>,
2396            Requires<[HasV4T]>;
2397
2398 // For the sequence
2399 //   zext( seteq (Rs, and(Rt, 255)))
2400 // Generate
2401 //   Pd=cmpb.eq(Rs, Rt)
2402 //   if (Pd.new) Rd=#1
2403 //   if (!Pd.new) Rd=#0
2404 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
2405                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
2406            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
2407                                                       (i32 IntRegs:$Rt))),
2408                                 1, 0))>,
2409            Requires<[HasV4T]>;
2410
2411 // For the sequence
2412 //   zext( setne (Rs, and(Rt, 255)))
2413 // Generate
2414 //   Pd=cmpb.eq(Rs, Rt)
2415 //   if (Pd.new) Rd=#0
2416 //   if (!Pd.new) Rd=#1
2417 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
2418                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
2419            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
2420                                                       (i32 IntRegs:$Rt))),
2421                                 0, 1))>,
2422            Requires<[HasV4T]>;
2423
2424 // For the sequence
2425 //   zext( setugt ( and(Rs, 255), u8))
2426 // Generate
2427 //   Pd=cmpb.gtu(Rs, #u8)
2428 //   if (Pd.new) Rd=#1
2429 //   if (!Pd.new) Rd=#0
2430 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
2431                                             u8ExtPred:$u8)))),
2432            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
2433                                                   (u8ExtPred:$u8))),
2434                                 1, 0))>,
2435            Requires<[HasV4T]>;
2436
2437 // For the sequence
2438 //   zext( setugt ( and(Rs, 254), u8))
2439 // Generate
2440 //   Pd=cmpb.gtu(Rs, #u8)
2441 //   if (Pd.new) Rd=#1
2442 //   if (!Pd.new) Rd=#0
2443 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
2444                                             u8ExtPred:$u8)))),
2445            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
2446                                                   (u8ExtPred:$u8))),
2447                                 1, 0))>,
2448            Requires<[HasV4T]>;
2449
2450 // For the sequence
2451 //   zext( setult ( Rs, Rt))
2452 // Generate
2453 //   Pd=cmp.ltu(Rs, Rt)
2454 //   if (Pd.new) Rd=#1
2455 //   if (!Pd.new) Rd=#0
2456 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
2457 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2458            (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
2459                                               (i32 IntRegs:$Rs))),
2460                                 1, 0))>,
2461            Requires<[HasV4T]>;
2462
2463 // For the sequence
2464 //   zext( setlt ( Rs, Rt))
2465 // Generate
2466 //   Pd=cmp.lt(Rs, Rt)
2467 //   if (Pd.new) Rd=#1
2468 //   if (!Pd.new) Rd=#0
2469 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
2470 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2471            (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
2472                                              (i32 IntRegs:$Rs))),
2473                                 1, 0))>,
2474            Requires<[HasV4T]>;
2475
2476 // For the sequence
2477 //   zext( setugt ( Rs, Rt))
2478 // Generate
2479 //   Pd=cmp.gtu(Rs, Rt)
2480 //   if (Pd.new) Rd=#1
2481 //   if (!Pd.new) Rd=#0
2482 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2483            (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
2484                                               (i32 IntRegs:$Rt))),
2485                                 1, 0))>,
2486            Requires<[HasV4T]>;
2487
2488 // This pattern interefers with coremark performance, not implementing at this
2489 // time.
2490 // For the sequence
2491 //   zext( setgt ( Rs, Rt))
2492 // Generate
2493 //   Pd=cmp.gt(Rs, Rt)
2494 //   if (Pd.new) Rd=#1
2495 //   if (!Pd.new) Rd=#0
2496
2497 // For the sequence
2498 //   zext( setuge ( Rs, Rt))
2499 // Generate
2500 //   Pd=cmp.ltu(Rs, Rt)
2501 //   if (Pd.new) Rd=#0
2502 //   if (!Pd.new) Rd=#1
2503 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
2504 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2505            (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
2506                                               (i32 IntRegs:$Rs))),
2507                                 0, 1))>,
2508            Requires<[HasV4T]>;
2509
2510 // For the sequence
2511 //   zext( setge ( Rs, Rt))
2512 // Generate
2513 //   Pd=cmp.lt(Rs, Rt)
2514 //   if (Pd.new) Rd=#0
2515 //   if (!Pd.new) Rd=#1
2516 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
2517 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2518            (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
2519                                              (i32 IntRegs:$Rs))),
2520                                 0, 1))>,
2521            Requires<[HasV4T]>;
2522
2523 // For the sequence
2524 //   zext( setule ( Rs, Rt))
2525 // Generate
2526 //   Pd=cmp.gtu(Rs, Rt)
2527 //   if (Pd.new) Rd=#0
2528 //   if (!Pd.new) Rd=#1
2529 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2530            (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
2531                                               (i32 IntRegs:$Rt))),
2532                                 0, 1))>,
2533            Requires<[HasV4T]>;
2534
2535 // For the sequence
2536 //   zext( setle ( Rs, Rt))
2537 // Generate
2538 //   Pd=cmp.gt(Rs, Rt)
2539 //   if (Pd.new) Rd=#0
2540 //   if (!Pd.new) Rd=#1
2541 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2542            (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rs),
2543                                              (i32 IntRegs:$Rt))),
2544                                 0, 1))>,
2545            Requires<[HasV4T]>;
2546
2547 // For the sequence
2548 //   zext( setult ( and(Rs, 255), u8))
2549 // Use the isdigit transformation below
2550
2551 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
2552 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
2553 // The isdigit transformation relies on two 'clever' aspects:
2554 // 1) The data type is unsigned which allows us to eliminate a zero test after
2555 //    biasing the expression by 48. We are depending on the representation of
2556 //    the unsigned types, and semantics.
2557 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
2558 //
2559 // For the C code:
2560 //   retval = ((c>='0') & (c<='9')) ? 1 : 0;
2561 // The code is transformed upstream of llvm into
2562 //   retval = (c-48) < 10 ? 1 : 0;
2563 let AddedComplexity = 139 in
2564 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
2565                                   u7StrictPosImmPred:$src2)))),
2566   (i32 (C2_muxii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
2567                                  (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
2568                    0, 1))>,
2569                    Requires<[HasV4T]>;
2570
2571 // Pd=cmpb.gtu(Rs,Rt)
2572 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
2573 InputType = "reg" in
2574 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
2575             (ins IntRegs:$src1, IntRegs:$src2),
2576             "$dst = cmpb.gtu($src1, $src2)",
2577             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
2578                                              (and (i32 IntRegs:$src2), 255)))]>,
2579             Requires<[HasV4T]>, ImmRegRel;
2580
2581 // Following instruction is not being extended as it results into the incorrect
2582 // code for negative numbers.
2583
2584 // Signed half compare(.eq) ri.
2585 // Pd=cmph.eq(Rs,#s8)
2586 let isCompare = 1, validSubTargets = HasV4SubT in
2587 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
2588             (ins IntRegs:$src1, s8Imm:$src2),
2589             "$dst = cmph.eq($src1, #$src2)",
2590             [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
2591                                              s8ImmPred:$src2))]>,
2592             Requires<[HasV4T]>;
2593
2594 // Signed half compare(.eq) rr.
2595 // Case 1: xor + and, then compare:
2596 //   r0=xor(r0,r1)
2597 //   r0=and(r0,#0xffff)
2598 //   p0=cmp.eq(r0,#0)
2599 // Pd=cmph.eq(Rs,Rt)
2600 let isCompare = 1, validSubTargets = HasV4SubT in
2601 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
2602             (ins IntRegs:$src1, IntRegs:$src2),
2603             "$dst = cmph.eq($src1, $src2)",
2604             [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
2605                                                        (i32 IntRegs:$src2)),
2606                                                   65535), 0))]>,
2607             Requires<[HasV4T]>;
2608
2609 // Signed half compare(.eq) rr.
2610 // Case 2: shift left 16 bits then compare:
2611 //   r0=asl(r0,16)
2612 //   r1=asl(r1,16)
2613 //   p0=cmp.eq(r0,r1)
2614 // Pd=cmph.eq(Rs,Rt)
2615 let isCompare = 1, validSubTargets = HasV4SubT in
2616 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
2617             (ins IntRegs:$src1, IntRegs:$src2),
2618             "$dst = cmph.eq($src1, $src2)",
2619             [(set (i1 PredRegs:$dst),
2620                   (seteq (shl (i32 IntRegs:$src1), (i32 16)),
2621                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
2622             Requires<[HasV4T]>;
2623
2624 /* Incorrect Pattern -- immediate should be right shifted before being
2625 used in the cmph.gt instruction.
2626 // Signed half compare(.gt) ri.
2627 // Pd=cmph.gt(Rs,#s8)
2628
2629 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
2630 isCompare = 1, validSubTargets = HasV4SubT in
2631 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
2632             (ins IntRegs:$src1, s8Ext:$src2),
2633             "$dst = cmph.gt($src1, #$src2)",
2634             [(set (i1 PredRegs:$dst),
2635                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
2636                          s8ExtPred:$src2))]>,
2637             Requires<[HasV4T]>;
2638 */
2639
2640 // Signed half compare(.gt) rr.
2641 // Pd=cmph.gt(Rs,Rt)
2642 let isCompare = 1, validSubTargets = HasV4SubT in
2643 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
2644             (ins IntRegs:$src1, IntRegs:$src2),
2645             "$dst = cmph.gt($src1, $src2)",
2646             [(set (i1 PredRegs:$dst),
2647                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
2648                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
2649             Requires<[HasV4T]>;
2650
2651 // Unsigned half compare rr (.gtu).
2652 // Pd=cmph.gtu(Rs,Rt)
2653 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
2654 InputType = "reg" in
2655 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
2656             (ins IntRegs:$src1, IntRegs:$src2),
2657             "$dst = cmph.gtu($src1, $src2)",
2658             [(set (i1 PredRegs:$dst),
2659                   (setugt (and (i32 IntRegs:$src1), 65535),
2660                           (and (i32 IntRegs:$src2), 65535)))]>,
2661             Requires<[HasV4T]>, ImmRegRel;
2662
2663 // Unsigned half compare ri (.gtu).
2664 // Pd=cmph.gtu(Rs,#u7)
2665 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
2666 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
2667 InputType = "imm" in
2668 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
2669             (ins IntRegs:$src1, u7Ext:$src2),
2670             "$dst = cmph.gtu($src1, #$src2)",
2671             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
2672                                               u7ExtPred:$src2))]>,
2673             Requires<[HasV4T]>, ImmRegRel;
2674
2675 let validSubTargets = HasV4SubT in
2676 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
2677     "$dst = !tstbit($src1, $src2)",
2678     [(set (i1 PredRegs:$dst),
2679           (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
2680     Requires<[HasV4T]>;
2681
2682 let validSubTargets = HasV4SubT in
2683 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
2684     "$dst = !tstbit($src1, $src2)",
2685     [(set (i1 PredRegs:$dst),
2686           (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
2687     Requires<[HasV4T]>;
2688
2689 //===----------------------------------------------------------------------===//
2690 // XTYPE/PRED -
2691 //===----------------------------------------------------------------------===//
2692
2693 //Deallocate frame and return.
2694 //    dealloc_return
2695 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
2696   Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0 in {
2697 let validSubTargets = HasV4SubT in
2698   def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
2699             "dealloc_return",
2700             []>,
2701             Requires<[HasV4T]>;
2702 }
2703
2704 // Restore registers and dealloc return function call.
2705 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
2706   Defs = [R29, R30, R31, PC] in {
2707 let validSubTargets = HasV4SubT in
2708   def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
2709                                    (ins calltarget:$dst),
2710              "jump $dst",
2711              []>,
2712              Requires<[HasV4T]>;
2713 }
2714
2715 // Restore registers and dealloc frame before a tail call.
2716 let isCall = 1, isBarrier = 1,
2717   Defs = [R29, R30, R31, PC] in {
2718 let validSubTargets = HasV4SubT in
2719   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
2720                                            (ins calltarget:$dst),
2721              "call $dst",
2722              []>,
2723              Requires<[HasV4T]>;
2724 }
2725
2726 // Save registers function call.
2727 let isCall = 1, isBarrier = 1,
2728   Uses = [R29, R31] in {
2729   def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
2730                                (ins calltarget:$dst),
2731              "call $dst // Save_calle_saved_registers",
2732              []>,
2733              Requires<[HasV4T]>;
2734 }
2735
2736 //    if (Ps) dealloc_return
2737 let isReturn = 1, isTerminator = 1,
2738     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2739     isPredicated = 1 in {
2740 let validSubTargets = HasV4SubT in
2741   def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
2742                            (ins PredRegs:$src1),
2743             "if ($src1) dealloc_return",
2744             []>,
2745             Requires<[HasV4T]>;
2746 }
2747
2748 //    if (!Ps) dealloc_return
2749 let isReturn = 1, isTerminator = 1,
2750     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2751     isPredicated = 1, isPredicatedFalse = 1 in {
2752 let validSubTargets = HasV4SubT in
2753   def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2754             "if (!$src1) dealloc_return",
2755             []>,
2756             Requires<[HasV4T]>;
2757 }
2758
2759 //    if (Ps.new) dealloc_return:nt
2760 let isReturn = 1, isTerminator = 1,
2761     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2762     isPredicated = 1 in {
2763 let validSubTargets = HasV4SubT in
2764   def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2765             "if ($src1.new) dealloc_return:nt",
2766             []>,
2767             Requires<[HasV4T]>;
2768 }
2769
2770 //    if (!Ps.new) dealloc_return:nt
2771 let isReturn = 1, isTerminator = 1,
2772     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2773     isPredicated = 1, isPredicatedFalse = 1 in {
2774 let validSubTargets = HasV4SubT in
2775   def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2776             "if (!$src1.new) dealloc_return:nt",
2777             []>,
2778             Requires<[HasV4T]>;
2779 }
2780
2781 //    if (Ps.new) dealloc_return:t
2782 let isReturn = 1, isTerminator = 1,
2783     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2784     isPredicated = 1 in {
2785 let validSubTargets = HasV4SubT in
2786   def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2787             "if ($src1.new) dealloc_return:t",
2788             []>,
2789             Requires<[HasV4T]>;
2790 }
2791
2792 // if (!Ps.new) dealloc_return:nt
2793 let isReturn = 1, isTerminator = 1,
2794     Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
2795     isPredicated = 1, isPredicatedFalse = 1 in {
2796 let validSubTargets = HasV4SubT in
2797   def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2798             "if (!$src1.new) dealloc_return:t",
2799             []>,
2800             Requires<[HasV4T]>;
2801 }
2802
2803 // Load/Store with absolute addressing mode
2804 // memw(#u6)=Rt
2805
2806 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
2807                            bit isPredNew> {
2808   let isPredicatedNew = isPredNew in
2809   def NAME#_V4 : STInst2<(outs),
2810             (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2811             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2812             ") ")#mnemonic#"(##$absaddr) = $src2",
2813             []>,
2814             Requires<[HasV4T]>;
2815 }
2816
2817 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
2818   let isPredicatedFalse = PredNot in {
2819     defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
2820     // Predicate new
2821     defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
2822   }
2823 }
2824
2825 let isNVStorable = 1, isExtended = 1, hasSideEffects = 0 in
2826 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
2827   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2828     let opExtendable = 0, isPredicable = 1 in
2829     def NAME#_V4 : STInst2<(outs),
2830             (ins u0AlwaysExt:$absaddr, RC:$src),
2831             mnemonic#"(##$absaddr) = $src",
2832             []>,
2833             Requires<[HasV4T]>;
2834
2835     let opExtendable = 1, isPredicated = 1 in {
2836       defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
2837       defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
2838     }
2839   }
2840 }
2841
2842 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
2843                            bit isPredNew> {
2844   let isPredicatedNew = isPredNew in
2845   def NAME#_nv_V4 : NVInst_V4<(outs),
2846             (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2847             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2848             ") ")#mnemonic#"(##$absaddr) = $src2.new",
2849             []>,
2850             Requires<[HasV4T]>;
2851 }
2852
2853 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
2854   let isPredicatedFalse = PredNot in {
2855     defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
2856     // Predicate new
2857     defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
2858   }
2859 }
2860
2861 let mayStore = 1, isNVStore = 1, isExtended = 1, hasSideEffects = 0 in
2862 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
2863   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2864     let opExtendable = 0, isPredicable = 1 in
2865     def NAME#_nv_V4 : NVInst_V4<(outs),
2866             (ins u0AlwaysExt:$absaddr, RC:$src),
2867             mnemonic#"(##$absaddr) = $src.new",
2868             []>,
2869             Requires<[HasV4T]>;
2870
2871     let opExtendable = 1, isPredicated = 1 in {
2872       defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
2873       defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
2874     }
2875   }
2876 }
2877
2878 let addrMode = Absolute in {
2879   let accessSize = ByteAccess in
2880     defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
2881                      ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
2882
2883   let accessSize = HalfWordAccess in
2884     defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
2885                      ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
2886
2887   let accessSize = WordAccess in
2888     defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
2889                      ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
2890
2891   let accessSize = DoubleWordAccess, isNVStorable = 0 in
2892     defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
2893 }
2894
2895 let Predicates = [HasV4T], AddedComplexity = 30 in {
2896 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
2897                         (HexagonCONST32 tglobaladdr:$absaddr)),
2898           (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2899
2900 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
2901                           (HexagonCONST32 tglobaladdr:$absaddr)),
2902           (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2903
2904 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
2905           (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2906
2907 def : Pat<(store (i64 DoubleRegs:$src1),
2908                  (HexagonCONST32 tglobaladdr:$absaddr)),
2909           (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
2910 }
2911
2912 //===----------------------------------------------------------------------===//
2913 // multiclass for store instructions with GP-relative addressing mode.
2914 // mem[bhwd](#global)=Rt
2915 // if ([!]Pv[.new]) mem[bhwd](##global) = Rt
2916 //===----------------------------------------------------------------------===//
2917 let mayStore = 1, isNVStorable = 1 in
2918 multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
2919   let BaseOpcode = BaseOp, isPredicable = 1 in
2920   def NAME#_V4 : STInst2<(outs),
2921           (ins globaladdress:$global, RC:$src),
2922           mnemonic#"(#$global) = $src",
2923           []>;
2924
2925   // When GP-relative instructions are predicated, their addressing mode is
2926   // changed to absolute and they are always constant extended.
2927   let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
2928   isPredicated = 1 in {
2929     defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
2930     defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
2931   }
2932 }
2933
2934 let mayStore = 1, isNVStore = 1 in
2935 multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
2936   let BaseOpcode = BaseOp, isPredicable = 1 in
2937   def NAME#_nv_V4 : NVInst_V4<(outs),
2938           (ins u0AlwaysExt:$global, RC:$src),
2939           mnemonic#"(#$global) = $src.new",
2940           []>,
2941           Requires<[HasV4T]>;
2942
2943   // When GP-relative instructions are predicated, their addressing mode is
2944   // changed to absolute and they are always constant extended.
2945   let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
2946   isPredicated = 1 in {
2947     defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
2948     defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
2949   }
2950 }
2951
2952 let validSubTargets = HasV4SubT, hasSideEffects = 0 in {
2953   let isNVStorable = 0 in
2954   defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
2955
2956   defm STb_GP : ST_GP<"memb",  "STb_GP", IntRegs>,
2957                 ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
2958   defm STh_GP : ST_GP<"memh",  "STh_GP", IntRegs>,
2959                 ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
2960   defm STw_GP : ST_GP<"memw",  "STw_GP", IntRegs>,
2961                 ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
2962 }
2963
2964 // 64 bit atomic store
2965 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
2966                             (i64 DoubleRegs:$src1)),
2967            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
2968            Requires<[HasV4T]>;
2969
2970 // Map from store(globaladdress) -> memd(#foo)
2971 let AddedComplexity = 100 in
2972 def : Pat <(store (i64 DoubleRegs:$src1),
2973                   (HexagonCONST32_GP tglobaladdr:$global)),
2974            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
2975
2976 // 8 bit atomic store
2977 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
2978                             (i32 IntRegs:$src1)),
2979             (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2980
2981 // Map from store(globaladdress) -> memb(#foo)
2982 let AddedComplexity = 100 in
2983 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
2984           (HexagonCONST32_GP tglobaladdr:$global)),
2985           (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2986
2987 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
2988 //       to "r0 = 1; memw(#foo) = r0"
2989 let AddedComplexity = 100 in
2990 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2991           (STb_GP_V4 tglobaladdr:$global, (A2_tfrsi 1))>;
2992
2993 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
2994                            (i32 IntRegs:$src1)),
2995           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2996
2997 // Map from store(globaladdress) -> memh(#foo)
2998 let AddedComplexity = 100 in
2999 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
3000                          (HexagonCONST32_GP tglobaladdr:$global)),
3001           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
3002
3003 // 32 bit atomic store
3004 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
3005                            (i32 IntRegs:$src1)),
3006           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
3007
3008 // Map from store(globaladdress) -> memw(#foo)
3009 let AddedComplexity = 100 in
3010 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
3011           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
3012
3013 //===----------------------------------------------------------------------===//
3014 // Multiclass for the load instructions with absolute addressing mode.
3015 //===----------------------------------------------------------------------===//
3016 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3017                            bit isPredNew> {
3018   let isPredicatedNew = isPredNew in
3019   def NAME : LDInst2<(outs RC:$dst),
3020             (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
3021             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3022             ") ")#"$dst = "#mnemonic#"(##$absaddr)",
3023             []>,
3024             Requires<[HasV4T]>;
3025 }
3026
3027 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3028   let isPredicatedFalse = PredNot in {
3029     defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3030     // Predicate new
3031     defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3032   }
3033 }
3034
3035 let isExtended = 1, hasSideEffects = 0 in
3036 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3037   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3038     let  opExtendable = 1, isPredicable = 1 in
3039     def NAME#_V4 : LDInst2<(outs RC:$dst),
3040             (ins u0AlwaysExt:$absaddr),
3041             "$dst = "#mnemonic#"(##$absaddr)",
3042             []>,
3043             Requires<[HasV4T]>;
3044
3045     let opExtendable = 2, isPredicated = 1 in {
3046       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3047       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3048     }
3049   }
3050 }
3051
3052 let addrMode = Absolute in {
3053   let accessSize = ByteAccess in {
3054     defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3055     defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
3056   }
3057   let accessSize = HalfWordAccess in {
3058     defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3059     defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
3060   }
3061   let accessSize = WordAccess in
3062     defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
3063
3064   let accessSize = DoubleWordAccess in
3065     defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
3066 }
3067
3068 let Predicates = [HasV4T], AddedComplexity  = 30 in {
3069 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3070           (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3071
3072 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3073           (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3074
3075 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3076           (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3077
3078 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3079           (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3080
3081 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3082           (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
3083 }
3084
3085 //===----------------------------------------------------------------------===//
3086 // multiclass for load instructions with GP-relative addressing mode.
3087 // Rx=mem[bhwd](##global)
3088 // if ([!]Pv[.new]) Rx=mem[bhwd](##global)
3089 //===----------------------------------------------------------------------===//
3090 let hasSideEffects = 0, validSubTargets = HasV4SubT in
3091 multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
3092   let BaseOpcode = BaseOp in {
3093     let isPredicable = 1 in
3094     def NAME#_V4 : LDInst2<(outs RC:$dst),
3095             (ins globaladdress:$global),
3096             "$dst = "#mnemonic#"(#$global)",
3097             []>;
3098
3099     let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
3100       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3101       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3102     }
3103   }
3104 }
3105
3106 defm LDd_GP  : LD_GP<"memd",  "LDd_GP",  DoubleRegs>, PredNewRel;
3107 defm LDb_GP  : LD_GP<"memb",  "LDb_GP",  IntRegs>, PredNewRel;
3108 defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
3109 defm LDh_GP  : LD_GP<"memh",  "LDh_GP",  IntRegs>, PredNewRel;
3110 defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
3111 defm LDw_GP  : LD_GP<"memw",  "LDw_GP",  IntRegs>, PredNewRel;
3112
3113 def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
3114            (i64 (LDd_GP_V4 tglobaladdr:$global))>;
3115
3116 def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
3117            (i32 (LDw_GP_V4 tglobaladdr:$global))>;
3118
3119 def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
3120            (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
3121
3122 def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
3123            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
3124
3125 // Map from load(globaladdress) -> memw(#foo + 0)
3126 let AddedComplexity = 100 in
3127 def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
3128            (i64 (LDd_GP_V4 tglobaladdr:$global))>;
3129
3130 // Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
3131 let AddedComplexity = 100 in
3132 def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
3133            (i1 (C2_tfrrp (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
3134
3135 // When the Interprocedural Global Variable optimizer realizes that a certain
3136 // global variable takes only two constant values, it shrinks the global to
3137 // a boolean. Catch those loads here in the following 3 patterns.
3138 let AddedComplexity = 100 in
3139 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3140            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3141
3142 let AddedComplexity = 100 in
3143 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3144            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3145
3146 // Map from load(globaladdress) -> memb(#foo)
3147 let AddedComplexity = 100 in
3148 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
3149            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3150
3151 // Map from load(globaladdress) -> memb(#foo)
3152 let AddedComplexity = 100 in
3153 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
3154            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3155
3156 let AddedComplexity = 100 in
3157 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3158            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
3159
3160 // Map from load(globaladdress) -> memub(#foo)
3161 let AddedComplexity = 100 in
3162 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
3163            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
3164
3165 // Map from load(globaladdress) -> memh(#foo)
3166 let AddedComplexity = 100 in
3167 def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3168            (i32 (LDh_GP_V4 tglobaladdr:$global))>;
3169
3170 // Map from load(globaladdress) -> memh(#foo)
3171 let AddedComplexity = 100 in
3172 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3173            (i32 (LDh_GP_V4 tglobaladdr:$global))>;
3174
3175 // Map from load(globaladdress) -> memuh(#foo)
3176 let AddedComplexity = 100 in
3177 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3178            (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
3179
3180 // Map from load(globaladdress) -> memw(#foo)
3181 let AddedComplexity = 100 in
3182 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
3183            (i32 (LDw_GP_V4 tglobaladdr:$global))>;
3184
3185
3186 // Transfer global address into a register
3187 let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
3188 isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in
3189 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
3190            "$dst = #$src1",
3191            [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3192            Requires<[HasV4T]>;
3193
3194 // Transfer a block address into a register
3195 def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
3196           (TFRI_V4 tblockaddress:$src1)>,
3197           Requires<[HasV4T]>;
3198
3199 let isExtended = 1, opExtendable = 2, AddedComplexity=50,
3200 hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
3201 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3202                            (ins PredRegs:$src1, s16Ext:$src2),
3203            "if($src1) $dst = #$src2",
3204            []>,
3205            Requires<[HasV4T]>;
3206
3207 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
3208 hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
3209 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3210                               (ins PredRegs:$src1, s16Ext:$src2),
3211            "if(!$src1) $dst = #$src2",
3212            []>,
3213            Requires<[HasV4T]>;
3214
3215 let isExtended = 1, opExtendable = 2, AddedComplexity=50,
3216 hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
3217 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3218                              (ins PredRegs:$src1, s16Ext:$src2),
3219            "if($src1.new) $dst = #$src2",
3220            []>,
3221            Requires<[HasV4T]>;
3222
3223 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
3224 hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
3225 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3226                                 (ins PredRegs:$src1, s16Ext:$src2),
3227            "if(!$src1.new) $dst = #$src2",
3228            []>,
3229            Requires<[HasV4T]>;
3230
3231 let AddedComplexity = 50, Predicates = [HasV4T] in
3232 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3233            (TFRI_V4 tglobaladdr:$src1)>,
3234            Requires<[HasV4T]>;
3235
3236
3237 // Load - Indirect with long offset: These instructions take global address
3238 // as an operand
3239 let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
3240 validSubTargets = HasV4SubT in
3241 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3242             (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3243             "$dst=memd($src1<<#$src2+##$offset)",
3244             [(set (i64 DoubleRegs:$dst),
3245                   (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3246                         (HexagonCONST32 tglobaladdr:$offset))))]>,
3247             Requires<[HasV4T]>;
3248
3249 let AddedComplexity = 40 in
3250 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3251 let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
3252   def _lo_V4 : LDInst<(outs IntRegs:$dst),
3253             (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3254             !strconcat("$dst = ",
3255             !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3256             [(set IntRegs:$dst,
3257                   (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3258                           (HexagonCONST32 tglobaladdr:$offset)))))]>,
3259             Requires<[HasV4T]>;
3260 }
3261
3262 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3263 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3264 defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
3265 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3266 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3267 defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
3268 defm LDriw_ind : LD_indirect_lo<"memw", load>;
3269
3270 let AddedComplexity = 40 in
3271 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
3272                                  (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
3273            (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
3274            Requires<[HasV4T]>;
3275
3276 let AddedComplexity = 40 in
3277 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
3278                                  (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
3279            (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
3280            Requires<[HasV4T]>;
3281
3282 let Predicates = [HasV4T], AddedComplexity  = 30 in {
3283 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3284           (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3285
3286 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3287           (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3288
3289 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3290           (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3291 }
3292
3293 let Predicates = [HasV4T], AddedComplexity  = 30 in {
3294 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
3295           (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
3296
3297 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
3298           (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
3299
3300 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
3301           (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
3302
3303 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
3304           (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
3305
3306 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
3307           (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
3308 }
3309
3310 // Indexed store word - global address.
3311 // memw(Rs+#u6:2)=#S8
3312 let AddedComplexity = 10 in
3313 def STriw_offset_ext_V4 : STInst<(outs),
3314             (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
3315             "memw($src1+#$src2) = ##$src3",
3316             [(store (HexagonCONST32 tglobaladdr:$src3),
3317                     (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
3318             Requires<[HasV4T]>;
3319
3320 def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
3321           (i64 (A4_combineir (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
3322           Requires<[HasV4T]>;
3323
3324 def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
3325           (i64 (A4_combineir (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
3326           Requires<[HasV4T]>;
3327
3328
3329 // i8 -> i64 loads
3330 // We need a complexity of 120 here to override preceding handling of
3331 // zextloadi8.
3332 let Predicates = [HasV4T], AddedComplexity = 120 in {
3333 def:  Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3334       (i64 (A4_combineir 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
3335
3336 def:  Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3337       (i64 (A4_combineir 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
3338
3339 def:  Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3340       (i64 (A2_sxtw (LDrib_abs_V4 tglobaladdr:$addr)))>;
3341
3342 def:  Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
3343       (i64 (A4_combineir 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
3344
3345 def:  Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
3346       (i64 (A4_combineir 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
3347
3348 def:  Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
3349       (i64 (A2_sxtw (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
3350 }
3351 // i16 -> i64 loads
3352 // We need a complexity of 120 here to override preceding handling of
3353 // zextloadi16.
3354 let AddedComplexity = 120 in {
3355 def:  Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3356       (i64 (A4_combineir 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
3357       Requires<[HasV4T]>;
3358
3359 def:  Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3360       (i64 (A4_combineir 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
3361       Requires<[HasV4T]>;
3362
3363 def:  Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3364       (i64 (A2_sxtw (LDrih_abs_V4 tglobaladdr:$addr)))>,
3365       Requires<[HasV4T]>;
3366
3367 def:  Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
3368       (i64 (A4_combineir 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
3369       Requires<[HasV4T]>;
3370
3371 def:  Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
3372       (i64 (A4_combineir 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
3373       Requires<[HasV4T]>;
3374
3375 def:  Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
3376       (i64 (A2_sxtw (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
3377       Requires<[HasV4T]>;
3378 }
3379 // i32->i64 loads
3380 // We need a complexity of 120 here to override preceding handling of
3381 // zextloadi32.
3382 let AddedComplexity = 120 in {
3383 def:  Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3384       (i64 (A4_combineir 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
3385       Requires<[HasV4T]>;
3386
3387 def:  Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3388       (i64 (A4_combineir 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
3389       Requires<[HasV4T]>;
3390
3391 def:  Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3392       (i64 (A2_sxtw (LDriw_abs_V4 tglobaladdr:$addr)))>,
3393       Requires<[HasV4T]>;
3394
3395 def:  Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
3396       (i64 (A4_combineir 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3397       Requires<[HasV4T]>;
3398
3399 def:  Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
3400       (i64 (A4_combineir 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3401       Requires<[HasV4T]>;
3402
3403 def:  Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
3404       (i64 (A2_sxtw (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3405       Requires<[HasV4T]>;
3406 }
3407
3408 // Indexed store double word - global address.
3409 // memw(Rs+#u6:2)=#S8
3410 let AddedComplexity = 10 in
3411 def STrih_offset_ext_V4 : STInst<(outs),
3412             (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
3413             "memh($src1+#$src2) = ##$src3",
3414             [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
3415                     (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
3416             Requires<[HasV4T]>;
3417 // Map from store(globaladdress + x) -> memd(#foo + x)
3418 let AddedComplexity = 100 in
3419 def : Pat<(store (i64 DoubleRegs:$src1),
3420                  FoldGlobalAddrGP:$addr),
3421           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
3422           Requires<[HasV4T]>;
3423
3424 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
3425                            (i64 DoubleRegs:$src1)),
3426           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
3427           Requires<[HasV4T]>;
3428
3429 // Map from store(globaladdress + x) -> memb(#foo + x)
3430 let AddedComplexity = 100 in
3431 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3432           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3433             Requires<[HasV4T]>;
3434
3435 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3436           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3437             Requires<[HasV4T]>;
3438
3439 // Map from store(globaladdress + x) -> memh(#foo + x)
3440 let AddedComplexity = 100 in
3441 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3442           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3443             Requires<[HasV4T]>;
3444
3445 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3446           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3447             Requires<[HasV4T]>;
3448
3449 // Map from store(globaladdress + x) -> memw(#foo + x)
3450 let AddedComplexity = 100 in
3451 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3452           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3453            Requires<[HasV4T]>;
3454
3455 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3456           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3457             Requires<[HasV4T]>;
3458
3459 // Map from load(globaladdress + x) -> memd(#foo + x)
3460 let AddedComplexity = 100 in
3461 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
3462           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
3463            Requires<[HasV4T]>;
3464
3465 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
3466           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
3467            Requires<[HasV4T]>;
3468
3469 // Map from load(globaladdress + x) -> memb(#foo + x)
3470 let AddedComplexity = 100 in
3471 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
3472           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
3473            Requires<[HasV4T]>;
3474
3475 // Map from load(globaladdress + x) -> memb(#foo + x)
3476 let AddedComplexity = 100 in
3477 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
3478           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
3479            Requires<[HasV4T]>;
3480
3481 //let AddedComplexity = 100 in
3482 let AddedComplexity = 100 in
3483 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
3484           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
3485            Requires<[HasV4T]>;
3486
3487 // Map from load(globaladdress + x) -> memh(#foo + x)
3488 let AddedComplexity = 100 in
3489 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
3490           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
3491            Requires<[HasV4T]>;
3492
3493 // Map from load(globaladdress + x) -> memuh(#foo + x)
3494 let AddedComplexity = 100 in
3495 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
3496           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
3497            Requires<[HasV4T]>;
3498
3499 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
3500           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
3501            Requires<[HasV4T]>;
3502
3503 // Map from load(globaladdress + x) -> memub(#foo + x)
3504 let AddedComplexity = 100 in
3505 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
3506           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
3507            Requires<[HasV4T]>;
3508
3509 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
3510           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
3511            Requires<[HasV4T]>;
3512
3513 // Map from load(globaladdress + x) -> memw(#foo + x)
3514 let AddedComplexity = 100 in
3515 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
3516           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
3517            Requires<[HasV4T]>;
3518
3519 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
3520           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
3521            Requires<[HasV4T]>;