Hexagon: Add patterns for zero extended loads from i1->i64.
[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 neverHasSideEffects = 1 in
15 class T_Immext<dag ins> :
16   EXTENDERInst<(outs), ins, "immext(#$imm)", []>,
17   Requires<[HasV4T]>;
18
19 def IMMEXT_b : T_Immext<(ins brtarget:$imm)>;
20 def IMMEXT_c : T_Immext<(ins calltarget:$imm)>;
21 def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>;
22 def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>;
23
24 // Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address.
25 def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>;
26
27 // Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address.
28 def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>;
29
30 def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
31                                        (HexagonCONST32 node:$addr), [{
32   return hasNumUsesBelowThresGA(N->getOperand(0).getNode());
33 }]>;
34
35 // Hexagon V4 Architecture spec defines 8 instruction classes:
36 // LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
37 // compiler)
38
39 // LD Instructions:
40 // ========================================
41 // Loads (8/16/32/64 bit)
42 // Deallocframe
43
44 // ST Instructions:
45 // ========================================
46 // Stores (8/16/32/64 bit)
47 // Allocframe
48
49 // ALU32 Instructions:
50 // ========================================
51 // Arithmetic / Logical (32 bit)
52 // Vector Halfword
53
54 // XTYPE Instructions (32/64 bit):
55 // ========================================
56 // Arithmetic, Logical, Bit Manipulation
57 // Multiply (Integer, Fractional, Complex)
58 // Permute / Vector Permute Operations
59 // Predicate Operations
60 // Shift / Shift with Add/Sub/Logical
61 // Vector Byte ALU
62 // Vector Halfword (ALU, Shift, Multiply)
63 // Vector Word (ALU, Shift)
64
65 // J Instructions:
66 // ========================================
67 // Jump/Call PC-relative
68
69 // JR Instructions:
70 // ========================================
71 // Jump/Call Register
72
73 // MEMOP Instructions:
74 // ========================================
75 // Operation on memory (8/16/32 bit)
76
77 // NV Instructions:
78 // ========================================
79 // New-value Jumps
80 // New-value Stores
81
82 // CR Instructions:
83 // ========================================
84 // Control-Register Transfers
85 // Hardware Loop Setup
86 // Predicate Logicals & Reductions
87
88 // SYSTEM Instructions (not implemented in the compiler):
89 // ========================================
90 // Prefetch
91 // Cache Maintenance
92 // Bus Operations
93
94
95 //===----------------------------------------------------------------------===//
96 // ALU32 +
97 //===----------------------------------------------------------------------===//
98
99 // Shift halfword.
100
101 let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
102 def ASLH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
103             (ins PredRegs:$src1, IntRegs:$src2),
104             "if ($src1) $dst = aslh($src2)",
105             []>,
106             Requires<[HasV4T]>;
107
108 def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
109             (ins PredRegs:$src1, IntRegs:$src2),
110             "if (!$src1) $dst = aslh($src2)",
111             []>,
112             Requires<[HasV4T]>;
113
114 def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
115             (ins PredRegs:$src1, IntRegs:$src2),
116             "if ($src1.new) $dst = aslh($src2)",
117             []>,
118             Requires<[HasV4T]>;
119
120 def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
121             (ins PredRegs:$src1, IntRegs:$src2),
122             "if (!$src1.new) $dst = aslh($src2)",
123             []>,
124             Requires<[HasV4T]>;
125
126 def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
127             (ins PredRegs:$src1, IntRegs:$src2),
128             "if ($src1) $dst = asrh($src2)",
129             []>,
130             Requires<[HasV4T]>;
131
132 def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
133             (ins PredRegs:$src1, IntRegs:$src2),
134             "if (!$src1) $dst = asrh($src2)",
135             []>,
136             Requires<[HasV4T]>;
137
138 def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
139             (ins PredRegs:$src1, IntRegs:$src2),
140             "if ($src1.new) $dst = asrh($src2)",
141             []>,
142             Requires<[HasV4T]>;
143
144 def ASRH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
145             (ins PredRegs:$src1, IntRegs:$src2),
146             "if (!$src1.new) $dst = asrh($src2)",
147             []>,
148             Requires<[HasV4T]>;
149 }
150
151 // Sign extend.
152
153 let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
154 def SXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
155             (ins PredRegs:$src1, IntRegs:$src2),
156             "if ($src1) $dst = sxtb($src2)",
157             []>,
158             Requires<[HasV4T]>;
159
160 def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
161             (ins PredRegs:$src1, IntRegs:$src2),
162             "if (!$src1) $dst = sxtb($src2)",
163             []>,
164             Requires<[HasV4T]>;
165
166 def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
167             (ins PredRegs:$src1, IntRegs:$src2),
168             "if ($src1.new) $dst = sxtb($src2)",
169             []>,
170             Requires<[HasV4T]>;
171
172 def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
173             (ins PredRegs:$src1, IntRegs:$src2),
174             "if (!$src1.new) $dst = sxtb($src2)",
175             []>,
176             Requires<[HasV4T]>;
177
178
179 def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
180             (ins PredRegs:$src1, IntRegs:$src2),
181             "if ($src1) $dst = sxth($src2)",
182             []>,
183             Requires<[HasV4T]>;
184
185 def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
186             (ins PredRegs:$src1, IntRegs:$src2),
187             "if (!$src1) $dst = sxth($src2)",
188             []>,
189             Requires<[HasV4T]>;
190
191 def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
192             (ins PredRegs:$src1, IntRegs:$src2),
193             "if ($src1.new) $dst = sxth($src2)",
194             []>,
195             Requires<[HasV4T]>;
196
197 def SXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
198             (ins PredRegs:$src1, IntRegs:$src2),
199             "if (!$src1.new) $dst = sxth($src2)",
200             []>,
201             Requires<[HasV4T]>;
202 }
203
204 // Zero exten.
205
206 let neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in {
207 def ZXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
208             (ins PredRegs:$src1, IntRegs:$src2),
209             "if ($src1) $dst = zxtb($src2)",
210             []>,
211             Requires<[HasV4T]>;
212
213 def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
214             (ins PredRegs:$src1, IntRegs:$src2),
215             "if (!$src1) $dst = zxtb($src2)",
216             []>,
217             Requires<[HasV4T]>;
218
219 def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
220             (ins PredRegs:$src1, IntRegs:$src2),
221             "if ($src1.new) $dst = zxtb($src2)",
222             []>,
223             Requires<[HasV4T]>;
224
225 def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
226             (ins PredRegs:$src1, IntRegs:$src2),
227             "if (!$src1.new) $dst = zxtb($src2)",
228             []>,
229             Requires<[HasV4T]>;
230
231 def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
232             (ins PredRegs:$src1, IntRegs:$src2),
233             "if ($src1) $dst = zxth($src2)",
234             []>,
235             Requires<[HasV4T]>;
236
237 def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
238             (ins PredRegs:$src1, IntRegs:$src2),
239             "if (!$src1) $dst = zxth($src2)",
240             []>,
241             Requires<[HasV4T]>;
242
243 def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
244             (ins PredRegs:$src1, IntRegs:$src2),
245             "if ($src1.new) $dst = zxth($src2)",
246             []>,
247             Requires<[HasV4T]>;
248
249 def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
250             (ins PredRegs:$src1, IntRegs:$src2),
251             "if (!$src1.new) $dst = zxth($src2)",
252             []>,
253             Requires<[HasV4T]>;
254 }
255
256 // Generate frame index addresses.
257 let neverHasSideEffects = 1, isReMaterializable = 1,
258 isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
259 def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
260             (ins IntRegs:$src1, s32Imm:$offset),
261             "$dst = add($src1, ##$offset)",
262             []>,
263             Requires<[HasV4T]>;
264
265 // Rd=cmp.eq(Rs,#s8)
266 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
267 isExtentSigned = 1, opExtentBits = 8 in
268 def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd),
269                     (ins IntRegs:$Rs, s8Ext:$s8),
270                     "$Rd = cmp.eq($Rs, #$s8)",
271                     [(set (i32 IntRegs:$Rd),
272                           (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
273                                                 s8ExtPred:$s8)))))]>,
274                     Requires<[HasV4T]>;
275
276 // Preserve the TSTBIT generation
277 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
278                                            (i32 IntRegs:$src1))), 0)))),
279       (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
280                    1, 0))>;
281
282 // Interfered with tstbit generation, above pattern preserves, see : tstbit.ll
283 // Rd=cmp.ne(Rs,#s8)
284 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
285 isExtentSigned = 1, opExtentBits = 8 in
286 def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd),
287                      (ins IntRegs:$Rs, s8Ext:$s8),
288                      "$Rd = !cmp.eq($Rs, #$s8)",
289                      [(set (i32 IntRegs:$Rd),
290                            (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
291                                                  s8ExtPred:$s8)))))]>,
292                      Requires<[HasV4T]>;
293
294 // Rd=cmp.eq(Rs,Rt)
295 let validSubTargets = HasV4SubT in
296 def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd),
297                    (ins IntRegs:$Rs, IntRegs:$Rt),
298                    "$Rd = cmp.eq($Rs, $Rt)",
299                    [(set (i32 IntRegs:$Rd),
300                          (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
301                                                IntRegs:$Rt)))))]>,
302                    Requires<[HasV4T]>;
303
304 // Rd=cmp.ne(Rs,Rt)
305 let validSubTargets = HasV4SubT in
306 def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
307                     (ins IntRegs:$Rs, IntRegs:$Rt),
308                     "$Rd = !cmp.eq($Rs, $Rt)",
309                     [(set (i32 IntRegs:$Rd),
310                           (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
311                                                IntRegs:$Rt)))))]>,
312                     Requires<[HasV4T]>;
313
314 //===----------------------------------------------------------------------===//
315 // ALU32 -
316 //===----------------------------------------------------------------------===//
317
318
319 //===----------------------------------------------------------------------===//
320 // ALU32/PERM +
321 //===----------------------------------------------------------------------===//
322
323 // Combine
324 // Rdd=combine(Rs, #s8)
325 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
326     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
327 def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst),
328             (ins IntRegs:$src1, s8Ext:$src2),
329             "$dst = combine($src1, #$src2)",
330             []>,
331             Requires<[HasV4T]>;
332
333 // Rdd=combine(#s8, Rs)
334 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
335     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
336 def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
337             (ins s8Ext:$src1, IntRegs:$src2),
338             "$dst = combine(#$src1, $src2)",
339             []>,
340             Requires<[HasV4T]>;
341
342 def HexagonWrapperCombineRI_V4 :
343   SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>;
344 def HexagonWrapperCombineIR_V4 :
345   SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
346
347 def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
348            (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>,
349           Requires<[HasV4T]>;
350
351 def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
352            (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>,
353           Requires<[HasV4T]>;
354
355 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6,
356     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
357 def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
358             (ins s8Imm:$src1, u6Ext:$src2),
359             "$dst = combine(#$src1, #$src2)",
360             []>,
361             Requires<[HasV4T]>;
362
363 //===----------------------------------------------------------------------===//
364 // ALU32/PERM +
365 //===----------------------------------------------------------------------===//
366
367 //===----------------------------------------------------------------------===//
368 // LD +
369 //===----------------------------------------------------------------------===//
370 //
371 // These absolute set addressing mode instructions accept immediate as
372 // an operand. We have duplicated these patterns to take global address.
373
374 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
375 validSubTargets = HasV4SubT in {
376 def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
377             (ins u0AlwaysExt:$addr),
378             "$dst1 = memd($dst2=##$addr)",
379             []>,
380             Requires<[HasV4T]>;
381
382 // Rd=memb(Re=#U6)
383 def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
384             (ins u0AlwaysExt:$addr),
385             "$dst1 = memb($dst2=##$addr)",
386             []>,
387             Requires<[HasV4T]>;
388
389 // Rd=memh(Re=#U6)
390 def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
391             (ins u0AlwaysExt:$addr),
392             "$dst1 = memh($dst2=##$addr)",
393             []>,
394             Requires<[HasV4T]>;
395
396 // Rd=memub(Re=#U6)
397 def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
398             (ins u0AlwaysExt:$addr),
399             "$dst1 = memub($dst2=##$addr)",
400             []>,
401             Requires<[HasV4T]>;
402
403 // Rd=memuh(Re=#U6)
404 def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
405             (ins u0AlwaysExt:$addr),
406             "$dst1 = memuh($dst2=##$addr)",
407             []>,
408             Requires<[HasV4T]>;
409
410 // Rd=memw(Re=#U6)
411 def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
412             (ins u0AlwaysExt:$addr),
413             "$dst1 = memw($dst2=##$addr)",
414             []>,
415             Requires<[HasV4T]>;
416 }
417
418 // Following patterns are defined for absolute set addressing mode
419 // instruction which take global address as operand.
420 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
421 validSubTargets = HasV4SubT in {
422 def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
423             (ins globaladdressExt:$addr),
424             "$dst1 = memd($dst2=##$addr)",
425             []>,
426             Requires<[HasV4T]>;
427
428 // Rd=memb(Re=#U6)
429 def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
430             (ins globaladdressExt:$addr),
431             "$dst1 = memb($dst2=##$addr)",
432             []>,
433             Requires<[HasV4T]>;
434
435 // Rd=memh(Re=#U6)
436 def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
437             (ins globaladdressExt:$addr),
438             "$dst1 = memh($dst2=##$addr)",
439             []>,
440             Requires<[HasV4T]>;
441
442 // Rd=memub(Re=#U6)
443 def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
444             (ins globaladdressExt:$addr),
445             "$dst1 = memub($dst2=##$addr)",
446             []>,
447             Requires<[HasV4T]>;
448
449 // Rd=memuh(Re=#U6)
450 def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
451             (ins globaladdressExt:$addr),
452             "$dst1 = memuh($dst2=##$addr)",
453             []>,
454             Requires<[HasV4T]>;
455
456 // Rd=memw(Re=#U6)
457 def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
458             (ins globaladdressExt:$addr),
459             "$dst1 = memw($dst2=##$addr)",
460             []>,
461             Requires<[HasV4T]>;
462 }
463
464 // multiclass for load instructions with base + register offset
465 // addressing mode
466 multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
467                              bit isPredNew> {
468   let PNewValue = !if(isPredNew, "new", "") in
469   def NAME : LDInst2<(outs RC:$dst),
470             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
471             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
472             ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
473             []>, Requires<[HasV4T]>;
474 }
475
476 multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
477   let PredSense = !if(PredNot, "false", "true") in {
478     defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
479     // Predicate new
480     defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
481   }
482 }
483
484 let neverHasSideEffects  = 1 in
485 multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
486   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
487     let isPredicable = 1 in
488     def NAME#_V4 : LDInst2<(outs RC:$dst),
489             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
490             "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
491             []>, Requires<[HasV4T]>;
492
493     let isPredicated = 1 in {
494       defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
495       defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
496     }
497   }
498 }
499
500 let addrMode = BaseRegOffset in {
501   defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, AddrModeRel;
502   defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, AddrModeRel;
503   defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
504   defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, AddrModeRel;
505   defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
506   defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, AddrModeRel;
507 }
508
509 // 'def pats' for load instructions with base + register offset and non-zero
510 // immediate value. Immediate value is used to left-shift the second
511 // register operand.
512 let AddedComplexity = 40 in {
513 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
514                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
515            (LDrib_indexed_shl_V4 IntRegs:$src1,
516             IntRegs:$src2, u2ImmPred:$offset)>,
517             Requires<[HasV4T]>;
518
519 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
520                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
521            (LDriub_indexed_shl_V4 IntRegs:$src1,
522             IntRegs:$src2, u2ImmPred:$offset)>,
523             Requires<[HasV4T]>;
524
525 def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
526                                 (shl IntRegs:$src2, u2ImmPred:$offset)))),
527            (LDriub_indexed_shl_V4 IntRegs:$src1,
528             IntRegs:$src2, u2ImmPred:$offset)>,
529             Requires<[HasV4T]>;
530
531 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
532                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
533            (LDrih_indexed_shl_V4 IntRegs:$src1,
534             IntRegs:$src2, u2ImmPred:$offset)>,
535             Requires<[HasV4T]>;
536
537 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
538                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
539            (LDriuh_indexed_shl_V4 IntRegs:$src1,
540             IntRegs:$src2, u2ImmPred:$offset)>,
541             Requires<[HasV4T]>;
542
543 def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
544                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
545            (LDriuh_indexed_shl_V4 IntRegs:$src1,
546             IntRegs:$src2, u2ImmPred:$offset)>,
547             Requires<[HasV4T]>;
548
549 def : Pat <(i32 (load (add IntRegs:$src1,
550                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
551            (LDriw_indexed_shl_V4 IntRegs:$src1,
552             IntRegs:$src2, u2ImmPred:$offset)>,
553             Requires<[HasV4T]>;
554
555 def : Pat <(i64 (load (add IntRegs:$src1,
556                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
557            (LDrid_indexed_shl_V4 IntRegs:$src1,
558             IntRegs:$src2, u2ImmPred:$offset)>,
559             Requires<[HasV4T]>;
560 }
561
562
563 // 'def pats' for load instruction base + register offset and
564 // zero immediate value.
565 let AddedComplexity = 10 in {
566 def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))),
567            (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
568             Requires<[HasV4T]>;
569
570 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
571            (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
572             Requires<[HasV4T]>;
573
574 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
575            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
576             Requires<[HasV4T]>;
577
578 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))),
579            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
580             Requires<[HasV4T]>;
581
582 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
583            (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
584             Requires<[HasV4T]>;
585
586 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
587            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
588             Requires<[HasV4T]>;
589
590 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))),
591            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
592             Requires<[HasV4T]>;
593
594 def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
595            (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
596             Requires<[HasV4T]>;
597 }
598
599 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
600 def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
601             (ins globaladdress:$global),
602             "$dst=memd(#$global)",
603             []>,
604             Requires<[HasV4T]>;
605
606 // if (Pv) Rtt=memd(##global)
607 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
608 validSubTargets = HasV4SubT in {
609 def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
610             (ins PredRegs:$src1, globaladdress:$global),
611             "if ($src1) $dst=memd(##$global)",
612             []>,
613             Requires<[HasV4T]>;
614
615
616 // if (!Pv) Rtt=memd(##global)
617 def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
618             (ins PredRegs:$src1, globaladdress:$global),
619             "if (!$src1) $dst=memd(##$global)",
620             []>,
621             Requires<[HasV4T]>;
622
623 // if (Pv) Rtt=memd(##global)
624 def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
625             (ins PredRegs:$src1, globaladdress:$global),
626             "if ($src1.new) $dst=memd(##$global)",
627             []>,
628             Requires<[HasV4T]>;
629
630
631 // if (!Pv) Rtt=memd(##global)
632 def LDd_GP_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
633             (ins PredRegs:$src1, globaladdress:$global),
634             "if (!$src1.new) $dst=memd(##$global)",
635             []>,
636             Requires<[HasV4T]>;
637 }
638
639 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
640 def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
641             (ins globaladdress:$global),
642             "$dst=memb(#$global)",
643             []>,
644             Requires<[HasV4T]>;
645
646 // if (Pv) Rt=memb(##global)
647 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
648 validSubTargets = HasV4SubT in {
649 def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
650             (ins PredRegs:$src1, globaladdress:$global),
651             "if ($src1) $dst=memb(##$global)",
652             []>,
653             Requires<[HasV4T]>;
654
655 // if (!Pv) Rt=memb(##global)
656 def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
657             (ins PredRegs:$src1, globaladdress:$global),
658             "if (!$src1) $dst=memb(##$global)",
659             []>,
660             Requires<[HasV4T]>;
661
662 // if (Pv) Rt=memb(##global)
663 def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
664             (ins PredRegs:$src1, globaladdress:$global),
665             "if ($src1.new) $dst=memb(##$global)",
666             []>,
667             Requires<[HasV4T]>;
668
669 // if (!Pv) Rt=memb(##global)
670 def LDb_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
671             (ins PredRegs:$src1, globaladdress:$global),
672             "if (!$src1.new) $dst=memb(##$global)",
673             []>,
674             Requires<[HasV4T]>;
675 }
676
677 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
678 def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
679             (ins globaladdress:$global),
680             "$dst=memub(#$global)",
681             []>,
682             Requires<[HasV4T]>;
683
684 // if (Pv) Rt=memub(##global)
685 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
686 validSubTargets = HasV4SubT in {
687 def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
688             (ins PredRegs:$src1, globaladdress:$global),
689             "if ($src1) $dst=memub(##$global)",
690             []>,
691             Requires<[HasV4T]>;
692
693
694 // if (!Pv) Rt=memub(##global)
695 def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
696             (ins PredRegs:$src1, globaladdress:$global),
697             "if (!$src1) $dst=memub(##$global)",
698             []>,
699             Requires<[HasV4T]>;
700
701 // if (Pv) Rt=memub(##global)
702 def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
703             (ins PredRegs:$src1, globaladdress:$global),
704             "if ($src1.new) $dst=memub(##$global)",
705             []>,
706             Requires<[HasV4T]>;
707
708
709 // if (!Pv) Rt=memub(##global)
710 def LDub_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
711             (ins PredRegs:$src1, globaladdress:$global),
712             "if (!$src1.new) $dst=memub(##$global)",
713             []>,
714             Requires<[HasV4T]>;
715 }
716
717 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
718 def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
719             (ins globaladdress:$global),
720             "$dst=memh(#$global)",
721             []>,
722             Requires<[HasV4T]>;
723
724 // if (Pv) Rt=memh(##global)
725 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
726 validSubTargets = HasV4SubT in {
727 def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
728             (ins PredRegs:$src1, globaladdress:$global),
729             "if ($src1) $dst=memh(##$global)",
730             []>,
731             Requires<[HasV4T]>;
732
733 // if (!Pv) Rt=memh(##global)
734 def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
735             (ins PredRegs:$src1, globaladdress:$global),
736             "if (!$src1) $dst=memh(##$global)",
737             []>,
738             Requires<[HasV4T]>;
739
740 // if (Pv) Rt=memh(##global)
741 def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
742             (ins PredRegs:$src1, globaladdress:$global),
743             "if ($src1.new) $dst=memh(##$global)",
744             []>,
745             Requires<[HasV4T]>;
746
747 // if (!Pv) Rt=memh(##global)
748 def LDh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
749             (ins PredRegs:$src1, globaladdress:$global),
750             "if (!$src1.new) $dst=memh(##$global)",
751             []>,
752             Requires<[HasV4T]>;
753 }
754
755 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
756 def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
757             (ins globaladdress:$global),
758             "$dst=memuh(#$global)",
759             []>,
760             Requires<[HasV4T]>;
761
762 // if (Pv) Rt=memuh(##global)
763 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
764 validSubTargets = HasV4SubT in {
765 def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
766             (ins PredRegs:$src1, globaladdress:$global),
767             "if ($src1) $dst=memuh(##$global)",
768             []>,
769             Requires<[HasV4T]>;
770
771 // if (!Pv) Rt=memuh(##global)
772 def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
773             (ins PredRegs:$src1, globaladdress:$global),
774             "if (!$src1) $dst=memuh(##$global)",
775             []>,
776             Requires<[HasV4T]>;
777
778 // if (Pv) Rt=memuh(##global)
779 def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
780             (ins PredRegs:$src1, globaladdress:$global),
781             "if ($src1.new) $dst=memuh(##$global)",
782             []>,
783             Requires<[HasV4T]>;
784
785 // if (!Pv) Rt=memuh(##global)
786 def LDuh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
787             (ins PredRegs:$src1, globaladdress:$global),
788             "if (!$src1.new) $dst=memuh(##$global)",
789             []>,
790             Requires<[HasV4T]>;
791 }
792
793 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
794 def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
795             (ins globaladdress:$global),
796             "$dst=memw(#$global)",
797             []>,
798             Requires<[HasV4T]>;
799
800 // if (Pv) Rt=memw(##global)
801 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
802 validSubTargets = HasV4SubT in {
803 def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
804             (ins PredRegs:$src1, globaladdress:$global),
805             "if ($src1) $dst=memw(##$global)",
806             []>,
807             Requires<[HasV4T]>;
808
809
810 // if (!Pv) Rt=memw(##global)
811 def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
812             (ins PredRegs:$src1, globaladdress:$global),
813             "if (!$src1) $dst=memw(##$global)",
814             []>,
815             Requires<[HasV4T]>;
816
817 // if (Pv) Rt=memw(##global)
818 def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
819             (ins PredRegs:$src1, globaladdress:$global),
820             "if ($src1.new) $dst=memw(##$global)",
821             []>,
822             Requires<[HasV4T]>;
823
824
825 // if (!Pv) Rt=memw(##global)
826 def LDw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
827             (ins PredRegs:$src1, globaladdress:$global),
828             "if (!$src1.new) $dst=memw(##$global)",
829             []>,
830             Requires<[HasV4T]>;
831 }
832
833
834 def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
835            (i64 (LDd_GP_V4 tglobaladdr:$global))>,
836             Requires<[HasV4T]>;
837
838 def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
839            (i32 (LDw_GP_V4 tglobaladdr:$global))>,
840             Requires<[HasV4T]>;
841
842 def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
843            (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
844             Requires<[HasV4T]>;
845
846 def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
847            (i32 (LDub_GP_V4 tglobaladdr:$global))>,
848             Requires<[HasV4T]>;
849
850 // Map from load(globaladdress) -> memw(#foo + 0)
851 let AddedComplexity = 100 in
852 def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
853            (i64 (LDd_GP_V4 tglobaladdr:$global))>,
854             Requires<[HasV4T]>;
855
856 // Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
857 let AddedComplexity = 100 in
858 def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
859            (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>,
860            Requires<[HasV4T]>;
861
862 // When the Interprocedural Global Variable optimizer realizes that a certain
863 // global variable takes only two constant values, it shrinks the global to
864 // a boolean. Catch those loads here in the following 3 patterns.
865 let AddedComplexity = 100 in
866 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
867            (i32 (LDb_GP_V4 tglobaladdr:$global))>,
868             Requires<[HasV4T]>;
869
870 let AddedComplexity = 100 in
871 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
872            (i32 (LDb_GP_V4 tglobaladdr:$global))>,
873             Requires<[HasV4T]>;
874
875 // Map from load(globaladdress) -> memb(#foo)
876 let AddedComplexity = 100 in
877 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
878            (i32 (LDb_GP_V4 tglobaladdr:$global))>,
879             Requires<[HasV4T]>;
880
881 // Map from load(globaladdress) -> memb(#foo)
882 let AddedComplexity = 100 in
883 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
884            (i32 (LDb_GP_V4 tglobaladdr:$global))>,
885             Requires<[HasV4T]>;
886
887 let AddedComplexity = 100 in
888 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
889            (i32 (LDub_GP_V4 tglobaladdr:$global))>,
890             Requires<[HasV4T]>;
891
892 // Map from load(globaladdress) -> memub(#foo)
893 let AddedComplexity = 100 in
894 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
895            (i32 (LDub_GP_V4 tglobaladdr:$global))>,
896             Requires<[HasV4T]>;
897
898 // Map from load(globaladdress) -> memh(#foo)
899 let AddedComplexity = 100 in
900 def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
901            (i32 (LDh_GP_V4 tglobaladdr:$global))>,
902             Requires<[HasV4T]>;
903
904 // Map from load(globaladdress) -> memh(#foo)
905 let AddedComplexity = 100 in
906 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
907            (i32 (LDh_GP_V4 tglobaladdr:$global))>,
908             Requires<[HasV4T]>;
909
910 // Map from load(globaladdress) -> memuh(#foo)
911 let AddedComplexity = 100 in
912 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
913            (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
914             Requires<[HasV4T]>;
915
916 // Map from load(globaladdress) -> memw(#foo)
917 let AddedComplexity = 100 in
918 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
919            (i32 (LDw_GP_V4 tglobaladdr:$global))>,
920             Requires<[HasV4T]>;
921
922 // zext i1->i64
923 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
924       (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
925       Requires<[HasV4T]>;
926
927 // zext i32->i64
928 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
929       (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>,
930       Requires<[HasV4T]>;
931 // zext i8->i64
932 def:  Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
933       (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
934       Requires<[HasV4T]>;
935
936 let AddedComplexity = 20 in
937 def:  Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
938                                 s11_0ExtPred:$offset))),
939       (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
940                                   s11_0ExtPred:$offset)))>,
941       Requires<[HasV4T]>;
942
943 // zext i1->i64
944 def:  Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
945       (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
946       Requires<[HasV4T]>;
947
948 let AddedComplexity = 20 in
949 def:  Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
950                                 s11_0ExtPred:$offset))),
951       (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
952                                   s11_0ExtPred:$offset)))>,
953       Requires<[HasV4T]>;
954
955 // zext i16->i64
956 def:  Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
957       (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
958       Requires<[HasV4T]>;
959
960 let AddedComplexity = 20 in
961 def:  Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
962                                   s11_1ExtPred:$offset))),
963       (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
964                                   s11_1ExtPred:$offset)))>,
965       Requires<[HasV4T]>;
966
967 // anyext i16->i64
968 def:  Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
969       (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
970       Requires<[HasV4T]>;
971
972 let AddedComplexity = 20 in
973 def:  Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
974                                   s11_1ExtPred:$offset))),
975       (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
976                                   s11_1ExtPred:$offset)))>,
977       Requires<[HasV4T]>;
978
979 // zext i32->i64
980 def:  Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
981       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
982       Requires<[HasV4T]>;
983
984 let AddedComplexity = 100 in
985 def:  Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
986       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
987                                   s11_2ExtPred:$offset)))>,
988       Requires<[HasV4T]>;
989
990 // anyext i32->i64
991 def:  Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
992       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
993       Requires<[HasV4T]>;
994
995 let AddedComplexity = 100 in
996 def:  Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
997       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
998                                   s11_2ExtPred:$offset)))>,
999       Requires<[HasV4T]>;
1000
1001
1002
1003 //===----------------------------------------------------------------------===//
1004 // LD -
1005 //===----------------------------------------------------------------------===//
1006
1007 //===----------------------------------------------------------------------===//
1008 // ST +
1009 //===----------------------------------------------------------------------===//
1010 ///
1011 /// Assumptions::: ****** DO NOT IGNORE ********
1012 /// 1. Make sure that in post increment store, the zero'th operand is always the
1013 ///    post increment operand.
1014 /// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
1015 ///    last operand.
1016 ///
1017
1018 // memd(Re=#U)=Rtt
1019 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1020 def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1021             (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
1022             "memd($dst1=##$src2) = $src1",
1023             []>,
1024             Requires<[HasV4T]>;
1025
1026 // memb(Re=#U)=Rs
1027 def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1028             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1029             "memb($dst1=##$src2) = $src1",
1030             []>,
1031             Requires<[HasV4T]>;
1032
1033 // memh(Re=#U)=Rs
1034 def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1035             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1036             "memh($dst1=##$src2) = $src1",
1037             []>,
1038             Requires<[HasV4T]>;
1039
1040 // memw(Re=#U)=Rs
1041 def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1042             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1043             "memw($dst1=##$src2) = $src1",
1044             []>,
1045             Requires<[HasV4T]>;
1046 }
1047
1048 // memd(Re=#U)=Rtt
1049 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1050 def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1051             (ins DoubleRegs:$src1, globaladdressExt:$src2),
1052             "memd($dst1=##$src2) = $src1",
1053             []>,
1054             Requires<[HasV4T]>;
1055
1056 // memb(Re=#U)=Rs
1057 def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1058             (ins IntRegs:$src1, globaladdressExt:$src2),
1059             "memb($dst1=##$src2) = $src1",
1060             []>,
1061             Requires<[HasV4T]>;
1062
1063 // memh(Re=#U)=Rs
1064 def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1065             (ins IntRegs:$src1, globaladdressExt:$src2),
1066             "memh($dst1=##$src2) = $src1",
1067             []>,
1068             Requires<[HasV4T]>;
1069
1070 // memw(Re=#U)=Rs
1071 def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1072             (ins IntRegs:$src1, globaladdressExt:$src2),
1073             "memw($dst1=##$src2) = $src1",
1074             []>,
1075             Requires<[HasV4T]>;
1076 }
1077
1078 // multiclass for store instructions with base + register offset addressing
1079 // mode
1080 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1081                              bit isPredNew> {
1082   let PNewValue = !if(isPredNew, "new", "") in
1083   def NAME : STInst2<(outs),
1084             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1085                  RC:$src5),
1086             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1087             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
1088             []>,
1089             Requires<[HasV4T]>;
1090 }
1091
1092 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1093   let PredSense = !if(PredNot, "false", "true") in {
1094     defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
1095     // Predicate new
1096     defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
1097   }
1098 }
1099
1100 let isNVStorable = 1 in
1101 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
1102   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1103     let isPredicable = 1 in
1104     def NAME#_V4 : STInst2<(outs),
1105             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1106             mnemonic#"($src1+$src2<<#$src3) = $src4",
1107             []>,
1108             Requires<[HasV4T]>;
1109
1110     let isPredicated = 1 in {
1111       defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
1112       defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
1113     }
1114   }
1115 }
1116
1117 // multiclass for new-value store instructions with base + register offset
1118 // addressing mode.
1119 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1120                              bit isPredNew> {
1121   let PNewValue = !if(isPredNew, "new", "") in
1122   def NAME#_nv_V4 : NVInst_V4<(outs),
1123             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1124                  RC:$src5),
1125             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1126             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
1127             []>,
1128             Requires<[HasV4T]>;
1129 }
1130
1131 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1132   let PredSense = !if(PredNot, "false", "true") in {
1133     defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
1134     // Predicate new
1135     defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
1136   }
1137 }
1138
1139 let mayStore = 1, isNVStore = 1 in
1140 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
1141   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1142     let isPredicable = 1 in
1143     def NAME#_nv_V4 : NVInst_V4<(outs),
1144             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1145             mnemonic#"($src1+$src2<<#$src3) = $src4.new",
1146             []>,
1147             Requires<[HasV4T]>;
1148
1149     let isPredicated = 1 in {
1150       defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
1151       defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
1152     }
1153   }
1154 }
1155
1156 let addrMode = BaseRegOffset, neverHasSideEffects = 1,
1157 validSubTargets = HasV4SubT in {
1158   defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
1159                           ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
1160
1161   defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
1162                           ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
1163
1164   defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
1165                           ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
1166
1167   let isNVStorable = 0 in
1168   defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
1169 }
1170
1171 let Predicates = [HasV4T], AddedComplexity = 10 in {
1172 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
1173                        (add IntRegs:$src1, (shl IntRegs:$src2,
1174                                                 u2ImmPred:$src3))),
1175           (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1176                                 u2ImmPred:$src3, IntRegs:$src4)>;
1177
1178 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
1179                         (add IntRegs:$src1, (shl IntRegs:$src2,
1180                                                  u2ImmPred:$src3))),
1181           (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1182                                 u2ImmPred:$src3, IntRegs:$src4)>;
1183
1184 def : Pat<(store (i32 IntRegs:$src4),
1185                  (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1186           (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1187                                 u2ImmPred:$src3, IntRegs:$src4)>;
1188
1189 def : Pat<(store (i64 DoubleRegs:$src4),
1190                 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1191           (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1192                                 u2ImmPred:$src3, DoubleRegs:$src4)>;
1193 }
1194
1195 // memd(Ru<<#u2+#U6)=Rtt
1196 let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
1197 validSubTargets = HasV4SubT in
1198 def STrid_shl_V4 : STInst<(outs),
1199             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
1200             "memd($src1<<#$src2+#$src3) = $src4",
1201             [(store (i64 DoubleRegs:$src4),
1202                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1203                          u0AlwaysExtPred:$src3))]>,
1204             Requires<[HasV4T]>;
1205
1206 // memd(Rx++#s4:3)=Rtt
1207 // memd(Rx++#s4:3:circ(Mu))=Rtt
1208 // memd(Rx++I:circ(Mu))=Rtt
1209 // memd(Rx++Mu)=Rtt
1210 // memd(Rx++Mu:brev)=Rtt
1211 // memd(gp+#u16:3)=Rtt
1212
1213 // Store doubleword conditionally.
1214 // if ([!]Pv[.new]) memd(#u6)=Rtt
1215 // TODO: needs to be implemented.
1216
1217 //===----------------------------------------------------------------------===//
1218 // multiclass for store instructions with base + immediate offset
1219 // addressing mode and immediate stored value.
1220 // mem[bhw](Rx++#s4:3)=#s8
1221 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
1222 //===----------------------------------------------------------------------===//
1223 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
1224                         bit isPredNew> {
1225   let PNewValue = !if(isPredNew, "new", "") in
1226   def NAME : STInst2<(outs),
1227             (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
1228             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1229             ") ")#mnemonic#"($src2+#$src3) = #$src4",
1230             []>,
1231             Requires<[HasV4T]>;
1232 }
1233
1234 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
1235   let PredSense = !if(PredNot, "false", "true") in {
1236     defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
1237     // Predicate new
1238     defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
1239   }
1240 }
1241
1242 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
1243 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
1244   let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
1245     let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
1246     def NAME#_V4 : STInst2<(outs),
1247             (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
1248             mnemonic#"($src1+#$src2) = #$src3",
1249             []>,
1250             Requires<[HasV4T]>;
1251
1252     let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
1253       defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
1254       defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
1255     }
1256   }
1257 }
1258
1259 let addrMode = BaseImmOffset, InputType = "imm",
1260     validSubTargets = HasV4SubT in {
1261   defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
1262   defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
1263   defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
1264 }
1265
1266 let Predicates = [HasV4T], AddedComplexity = 10 in {
1267 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
1268             (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
1269
1270 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
1271                                               u6_1ImmPred:$src2)),
1272             (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
1273
1274 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
1275             (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
1276 }
1277
1278 let AddedComplexity = 6 in
1279 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1280            (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1281            Requires<[HasV4T]>;
1282
1283 // memb(Ru<<#u2+#U6)=Rt
1284 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1285 validSubTargets = HasV4SubT in
1286 def STrib_shl_V4 : STInst<(outs),
1287             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1288             "memb($src1<<#$src2+#$src3) = $src4",
1289             [(truncstorei8 (i32 IntRegs:$src4),
1290                            (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1291                                 u0AlwaysExtPred:$src3))]>,
1292             Requires<[HasV4T]>;
1293
1294 // memb(Rx++#s4:0:circ(Mu))=Rt
1295 // memb(Rx++I:circ(Mu))=Rt
1296 // memb(Rx++Mu)=Rt
1297 // memb(Rx++Mu:brev)=Rt
1298 // memb(gp+#u16:0)=Rt
1299
1300
1301 // Store halfword.
1302 // TODO: needs to be implemented
1303 // memh(Re=#U6)=Rt.H
1304 // memh(Rs+#s11:1)=Rt.H
1305 let AddedComplexity = 6 in
1306 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1307            (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1308            Requires<[HasV4T]>;
1309
1310 // memh(Rs+Ru<<#u2)=Rt.H
1311 // TODO: needs to be implemented.
1312
1313 // memh(Ru<<#u2+#U6)=Rt.H
1314 // memh(Ru<<#u2+#U6)=Rt
1315 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1316 validSubTargets = HasV4SubT in
1317 def STrih_shl_V4 : STInst<(outs),
1318             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1319             "memh($src1<<#$src2+#$src3) = $src4",
1320             [(truncstorei16 (i32 IntRegs:$src4),
1321                             (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1322                                  u0AlwaysExtPred:$src3))]>,
1323             Requires<[HasV4T]>;
1324
1325 // memh(Rx++#s4:1:circ(Mu))=Rt.H
1326 // memh(Rx++#s4:1:circ(Mu))=Rt
1327 // memh(Rx++I:circ(Mu))=Rt.H
1328 // memh(Rx++I:circ(Mu))=Rt
1329 // memh(Rx++Mu)=Rt.H
1330 // memh(Rx++Mu)=Rt
1331 // memh(Rx++Mu:brev)=Rt.H
1332 // memh(Rx++Mu:brev)=Rt
1333 // memh(gp+#u16:1)=Rt
1334 // if ([!]Pv[.new]) memh(#u6)=Rt.H
1335 // if ([!]Pv[.new]) memh(#u6)=Rt
1336
1337
1338 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
1339 // TODO: needs to be implemented.
1340
1341 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
1342 // TODO: Needs to be implemented.
1343
1344 // Store word.
1345 // memw(Re=#U6)=Rt
1346 // TODO: Needs to be implemented.
1347
1348 // Store predicate:
1349 let neverHasSideEffects = 1 in
1350 def STriw_pred_V4 : STInst2<(outs),
1351             (ins MEMri:$addr, PredRegs:$src1),
1352             "Error; should not emit",
1353             []>,
1354             Requires<[HasV4T]>;
1355
1356 let AddedComplexity = 6 in
1357 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
1358            (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1359            Requires<[HasV4T]>;
1360
1361 // memw(Ru<<#u2+#U6)=Rt
1362 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1363 validSubTargets = HasV4SubT in
1364 def STriw_shl_V4 : STInst<(outs),
1365             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1366             "memw($src1<<#$src2+#$src3) = $src4",
1367             [(store (i32 IntRegs:$src4),
1368                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1369                               u0AlwaysExtPred:$src3))]>,
1370             Requires<[HasV4T]>;
1371
1372 // memw(Rx++#s4:2)=Rt
1373 // memw(Rx++#s4:2:circ(Mu))=Rt
1374 // memw(Rx++I:circ(Mu))=Rt
1375 // memw(Rx++Mu)=Rt
1376 // memw(Rx++Mu:brev)=Rt
1377 // memw(gp+#u16:2)=Rt
1378
1379
1380 // memd(#global)=Rtt
1381 let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1,
1382 validSubTargets = HasV4SubT in
1383 def STd_GP_V4 : STInst2<(outs),
1384             (ins globaladdress:$global, DoubleRegs:$src),
1385             "memd(#$global) = $src",
1386             []>,
1387             Requires<[HasV4T]>;
1388
1389 // if (Pv) memd(##global) = Rtt
1390 let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1,
1391 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1392 def STd_GP_cPt_V4 : STInst2<(outs),
1393             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1394             "if ($src1) memd(##$global) = $src2",
1395             []>,
1396             Requires<[HasV4T]>;
1397
1398 // if (!Pv) memd(##global) = Rtt
1399 def STd_GP_cNotPt_V4 : STInst2<(outs),
1400             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1401             "if (!$src1) memd(##$global) = $src2",
1402             []>,
1403               Requires<[HasV4T]>;
1404
1405 // if (Pv) memd(##global) = Rtt
1406 def STd_GP_cdnPt_V4 : STInst2<(outs),
1407             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1408             "if ($src1.new) memd(##$global) = $src2",
1409             []>,
1410               Requires<[HasV4T]>;
1411
1412 // if (!Pv) memd(##global) = Rtt
1413 def STd_GP_cdnNotPt_V4 : STInst2<(outs),
1414             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1415             "if (!$src1.new) memd(##$global) = $src2",
1416             []>,
1417             Requires<[HasV4T]>;
1418 }
1419
1420 // memb(#global)=Rt
1421 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1422 validSubTargets = HasV4SubT in
1423 def STb_GP_V4 : STInst2<(outs),
1424             (ins globaladdress:$global, IntRegs:$src),
1425             "memb(#$global) = $src",
1426             []>,
1427             Requires<[HasV4T]>;
1428
1429 // if (Pv) memb(##global) = Rt
1430 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1431 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1432 def STb_GP_cPt_V4 : STInst2<(outs),
1433             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1434             "if ($src1) memb(##$global) = $src2",
1435               []>,
1436               Requires<[HasV4T]>;
1437
1438 // if (!Pv) memb(##global) = Rt
1439 def STb_GP_cNotPt_V4 : STInst2<(outs),
1440             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1441             "if (!$src1) memb(##$global) = $src2",
1442               []>,
1443               Requires<[HasV4T]>;
1444
1445 // if (Pv) memb(##global) = Rt
1446 def STb_GP_cdnPt_V4 : STInst2<(outs),
1447             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1448             "if ($src1.new) memb(##$global) = $src2",
1449               []>,
1450               Requires<[HasV4T]>;
1451
1452 // if (!Pv) memb(##global) = Rt
1453 def STb_GP_cdnNotPt_V4 : STInst2<(outs),
1454             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1455             "if (!$src1.new) memb(##$global) = $src2",
1456               []>,
1457               Requires<[HasV4T]>;
1458 }
1459
1460 // memh(#global)=Rt
1461 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1462 validSubTargets = HasV4SubT in
1463 def STh_GP_V4 : STInst2<(outs),
1464             (ins globaladdress:$global, IntRegs:$src),
1465             "memh(#$global) = $src",
1466             []>,
1467             Requires<[HasV4T]>;
1468
1469 // if (Pv) memh(##global) = Rt
1470 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1471 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1472 def STh_GP_cPt_V4 : STInst2<(outs),
1473             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1474             "if ($src1) memh(##$global) = $src2",
1475               []>,
1476               Requires<[HasV4T]>;
1477
1478 // if (!Pv) memh(##global) = Rt
1479 def STh_GP_cNotPt_V4 : STInst2<(outs),
1480             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1481             "if (!$src1) memh(##$global) = $src2",
1482               []>,
1483               Requires<[HasV4T]>;
1484
1485 // if (Pv) memh(##global) = Rt
1486 def STh_GP_cdnPt_V4 : STInst2<(outs),
1487             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1488             "if ($src1.new) memh(##$global) = $src2",
1489               []>,
1490               Requires<[HasV4T]>;
1491
1492 // if (!Pv) memh(##global) = Rt
1493 def STh_GP_cdnNotPt_V4 : STInst2<(outs),
1494             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1495             "if (!$src1.new) memh(##$global) = $src2",
1496               []>,
1497               Requires<[HasV4T]>;
1498 }
1499
1500 // memw(#global)=Rt
1501 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1502 validSubTargets = HasV4SubT in
1503 def STw_GP_V4 : STInst2<(outs),
1504             (ins globaladdress:$global, IntRegs:$src),
1505             "memw(#$global) = $src",
1506               []>,
1507               Requires<[HasV4T]>;
1508
1509 // if (Pv) memw(##global) = Rt
1510 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1511 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1512 def STw_GP_cPt_V4 : STInst2<(outs),
1513             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1514             "if ($src1) memw(##$global) = $src2",
1515               []>,
1516               Requires<[HasV4T]>;
1517
1518 // if (!Pv) memw(##global) = Rt
1519 def STw_GP_cNotPt_V4 : STInst2<(outs),
1520             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1521             "if (!$src1) memw(##$global) = $src2",
1522               []>,
1523               Requires<[HasV4T]>;
1524
1525 // if (Pv) memw(##global) = Rt
1526 def STw_GP_cdnPt_V4 : STInst2<(outs),
1527             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1528             "if ($src1.new) memw(##$global) = $src2",
1529               []>,
1530               Requires<[HasV4T]>;
1531
1532 // if (!Pv) memw(##global) = Rt
1533 def STw_GP_cdnNotPt_V4 : STInst2<(outs),
1534             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1535             "if (!$src1.new) memw(##$global) = $src2",
1536             []>,
1537               Requires<[HasV4T]>;
1538 }
1539
1540 // 64 bit atomic store
1541 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
1542                             (i64 DoubleRegs:$src1)),
1543            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1544            Requires<[HasV4T]>;
1545
1546 // Map from store(globaladdress) -> memd(#foo)
1547 let AddedComplexity = 100 in
1548 def : Pat <(store (i64 DoubleRegs:$src1),
1549                   (HexagonCONST32_GP tglobaladdr:$global)),
1550            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1551            Requires<[HasV4T]>;
1552
1553 // 8 bit atomic store
1554 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
1555                             (i32 IntRegs:$src1)),
1556             (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1557               Requires<[HasV4T]>;
1558
1559 // Map from store(globaladdress) -> memb(#foo)
1560 let AddedComplexity = 100 in
1561 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
1562           (HexagonCONST32_GP tglobaladdr:$global)),
1563           (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1564           Requires<[HasV4T]>;
1565
1566 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
1567 //       to "r0 = 1; memw(#foo) = r0"
1568 let AddedComplexity = 100 in
1569 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
1570           (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
1571           Requires<[HasV4T]>;
1572
1573 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
1574                            (i32 IntRegs:$src1)),
1575           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1576           Requires<[HasV4T]>;
1577
1578 // Map from store(globaladdress) -> memh(#foo)
1579 let AddedComplexity = 100 in
1580 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
1581                          (HexagonCONST32_GP tglobaladdr:$global)),
1582           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1583           Requires<[HasV4T]>;
1584
1585 // 32 bit atomic store
1586 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
1587                            (i32 IntRegs:$src1)),
1588           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1589           Requires<[HasV4T]>;
1590
1591 // Map from store(globaladdress) -> memw(#foo)
1592 let AddedComplexity = 100 in
1593 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
1594           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1595           Requires<[HasV4T]>;
1596
1597 //===----------------------------------------------------------------------===
1598 // ST -
1599 //===----------------------------------------------------------------------===
1600
1601
1602 //===----------------------------------------------------------------------===//
1603 // NV/ST +
1604 //===----------------------------------------------------------------------===//
1605
1606 // multiclass for new-value store instructions with base + immediate offset.
1607 //
1608 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
1609                             Operand predImmOp, bit isNot, bit isPredNew> {
1610   let PNewValue = !if(isPredNew, "new", "") in
1611   def NAME#_nv_V4 : NVInst_V4<(outs),
1612             (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1613             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1614             ") ")#mnemonic#"($src2+#$src3) = $src4.new",
1615             []>,
1616             Requires<[HasV4T]>;
1617 }
1618
1619 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
1620                            bit PredNot> {
1621   let PredSense = !if(PredNot, "false", "true") in {
1622     defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
1623     // Predicate new
1624     defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
1625   }
1626 }
1627
1628 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
1629 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
1630                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1631                    bits<5> PredImmBits> {
1632
1633   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1634     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1635     isPredicable = 1 in
1636     def NAME#_nv_V4 : NVInst_V4<(outs),
1637             (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1638             mnemonic#"($src1+#$src2) = $src3.new",
1639             []>,
1640             Requires<[HasV4T]>;
1641
1642     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1643     isPredicated = 1 in {
1644       defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
1645       defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
1646     }
1647   }
1648 }
1649
1650 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
1651   defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
1652                                  u6_0Ext, 11, 6>, AddrModeRel;
1653   defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
1654                                  u6_1Ext, 12, 7>, AddrModeRel;
1655   defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
1656                                  u6_2Ext, 13, 8>, AddrModeRel;
1657 }
1658
1659 // multiclass for new-value store instructions with base + immediate offset.
1660 // and MEMri operand.
1661 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1662                           bit isPredNew> {
1663   let PNewValue = !if(isPredNew, "new", "") in
1664   def NAME#_nv_V4 : NVInst_V4<(outs),
1665             (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1666             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1667             ") ")#mnemonic#"($addr) = $src2.new",
1668             []>,
1669             Requires<[HasV4T]>;
1670 }
1671
1672 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1673   let PredSense = !if(PredNot, "false", "true") in {
1674     defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
1675
1676     // Predicate new
1677     defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
1678   }
1679 }
1680
1681 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
1682 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
1683                     bits<5> ImmBits, bits<5> PredImmBits> {
1684
1685   let CextOpcode = CextOp, BaseOpcode = CextOp in {
1686     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1687          isPredicable = 1 in
1688     def NAME#_nv_V4 : NVInst_V4<(outs),
1689             (ins MEMri:$addr, RC:$src),
1690             mnemonic#"($addr) = $src.new",
1691             []>,
1692             Requires<[HasV4T]>;
1693
1694     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1695         neverHasSideEffects = 1, isPredicated = 1 in {
1696       defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
1697       defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
1698     }
1699   }
1700 }
1701
1702 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1703 mayStore = 1 in {
1704   defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1705   defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1706   defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1707 }
1708
1709 // memb(Ru<<#u2+#U6)=Nt.new
1710 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1711 isNVStore = 1, validSubTargets = HasV4SubT in
1712 def STrib_shl_nv_V4 : NVInst_V4<(outs),
1713             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1714             "memb($src1<<#$src2+#$src3) = $src4.new",
1715             []>,
1716             Requires<[HasV4T]>;
1717
1718 //===----------------------------------------------------------------------===//
1719 // Post increment store
1720 // mem[bhwd](Rx++#s4:[0123])=Nt.new
1721 //===----------------------------------------------------------------------===//
1722
1723 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
1724                             bit isNot, bit isPredNew> {
1725   let PNewValue = !if(isPredNew, "new", "") in
1726   def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1727             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1728             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1729             ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1730             [],
1731             "$src2 = $dst">,
1732             Requires<[HasV4T]>;
1733 }
1734
1735 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
1736                            Operand ImmOp, bit PredNot> {
1737   let PredSense = !if(PredNot, "false", "true") in {
1738     defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
1739     // Predicate new
1740     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1741     defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
1742   }
1743 }
1744
1745 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
1746 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
1747                       Operand ImmOp> {
1748
1749   let BaseOpcode = "POST_"#BaseOp in {
1750     let isPredicable = 1 in
1751     def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1752                 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1753                 mnemonic#"($src1++#$offset) = $src2.new",
1754                 [],
1755                 "$src1 = $dst">,
1756                 Requires<[HasV4T]>;
1757
1758     let isPredicated = 1 in {
1759       defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
1760       defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
1761     }
1762   }
1763 }
1764
1765 let validSubTargets = HasV4SubT in {
1766 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1767 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1768 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1769 }
1770
1771 // memb(Rx++#s4:0:circ(Mu))=Nt.new
1772 // memb(Rx++I:circ(Mu))=Nt.new
1773 // memb(Rx++Mu)=Nt.new
1774 // memb(Rx++Mu:brev)=Nt.new
1775
1776 // memb(#global)=Nt.new
1777 let mayStore = 1, neverHasSideEffects = 1 in
1778 def STb_GP_nv_V4 : NVInst_V4<(outs),
1779             (ins globaladdress:$global, IntRegs:$src),
1780             "memb(#$global) = $src.new",
1781             []>,
1782             Requires<[HasV4T]>;
1783
1784 // memh(Ru<<#u2+#U6)=Nt.new
1785 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1786 isNVStore = 1, validSubTargets = HasV4SubT in
1787 def STrih_shl_nv_V4 : NVInst_V4<(outs),
1788             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1789             "memh($src1<<#$src2+#$src3) = $src4.new",
1790             []>,
1791             Requires<[HasV4T]>;
1792
1793 // memh(Rx++#s4:1:circ(Mu))=Nt.new
1794 // memh(Rx++I:circ(Mu))=Nt.new
1795 // memh(Rx++Mu)=Nt.new
1796 // memh(Rx++Mu:brev)=Nt.new
1797
1798 // memh(#global)=Nt.new
1799 let mayStore = 1, neverHasSideEffects = 1 in
1800 def STh_GP_nv_V4 : NVInst_V4<(outs),
1801             (ins globaladdress:$global, IntRegs:$src),
1802             "memh(#$global) = $src.new",
1803             []>,
1804             Requires<[HasV4T]>;
1805
1806 // memw(Ru<<#u2+#U6)=Nt.new
1807 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1808 isNVStore = 1, validSubTargets = HasV4SubT in
1809 def STriw_shl_nv_V4 : NVInst_V4<(outs),
1810             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1811             "memw($src1<<#$src2+#$src3) = $src4.new",
1812             []>,
1813             Requires<[HasV4T]>;
1814
1815 // memw(Rx++#s4:2:circ(Mu))=Nt.new
1816 // memw(Rx++I:circ(Mu))=Nt.new
1817 // memw(Rx++Mu)=Nt.new
1818 // memw(Rx++Mu:brev)=Nt.new
1819 // memw(gp+#u16:2)=Nt.new
1820
1821 let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
1822 validSubTargets = HasV4SubT in
1823 def STw_GP_nv_V4 : NVInst_V4<(outs),
1824             (ins globaladdress:$global, IntRegs:$src),
1825             "memw(#$global) = $src.new",
1826             []>,
1827             Requires<[HasV4T]>;
1828
1829 // if (Pv) memb(##global) = Rt
1830 let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
1831 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1832 def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
1833             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1834             "if ($src1) memb(##$global) = $src2.new",
1835             []>,
1836             Requires<[HasV4T]>;
1837
1838 // if (!Pv) memb(##global) = Rt
1839 def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1840             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1841             "if (!$src1) memb(##$global) = $src2.new",
1842             []>,
1843             Requires<[HasV4T]>;
1844
1845 // if (Pv) memb(##global) = Rt
1846 def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1847             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1848             "if ($src1.new) memb(##$global) = $src2.new",
1849             []>,
1850             Requires<[HasV4T]>;
1851
1852 // if (!Pv) memb(##global) = Rt
1853 def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1854             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1855             "if (!$src1.new) memb(##$global) = $src2.new",
1856             []>,
1857             Requires<[HasV4T]>;
1858
1859 // if (Pv) memh(##global) = Rt
1860 def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
1861             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1862             "if ($src1) memh(##$global) = $src2.new",
1863             []>,
1864             Requires<[HasV4T]>;
1865
1866 // if (!Pv) memh(##global) = Rt
1867 def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1868             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1869             "if (!$src1) memh(##$global) = $src2.new",
1870             []>,
1871             Requires<[HasV4T]>;
1872
1873 // if (Pv) memh(##global) = Rt
1874 def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1875             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1876             "if ($src1.new) memh(##$global) = $src2.new",
1877             []>,
1878             Requires<[HasV4T]>;
1879
1880 // if (!Pv) memh(##global) = Rt
1881 def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1882             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1883             "if (!$src1.new) memh(##$global) = $src2.new",
1884             []>,
1885             Requires<[HasV4T]>;
1886
1887 // if (Pv) memw(##global) = Rt
1888 def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
1889             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1890             "if ($src1) memw(##$global) = $src2.new",
1891             []>,
1892             Requires<[HasV4T]>;
1893
1894 // if (!Pv) memw(##global) = Rt
1895 def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1896             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1897             "if (!$src1) memw(##$global) = $src2.new",
1898             []>,
1899             Requires<[HasV4T]>;
1900
1901 // if (Pv) memw(##global) = Rt
1902 def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1903             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1904             "if ($src1.new) memw(##$global) = $src2.new",
1905             []>,
1906             Requires<[HasV4T]>;
1907
1908 // if (!Pv) memw(##global) = Rt
1909 def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1910             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1911             "if (!$src1.new) memw(##$global) = $src2.new",
1912             []>,
1913             Requires<[HasV4T]>;
1914 }
1915
1916 //===----------------------------------------------------------------------===//
1917 // NV/ST -
1918 //===----------------------------------------------------------------------===//
1919
1920 //===----------------------------------------------------------------------===//
1921 // NV/J +
1922 //===----------------------------------------------------------------------===//
1923
1924 multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
1925   def _ie_nv_V4 : NVInst_V4<(outs),
1926             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1927             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1928             !strconcat("($src1.new, $src2)) jump:",
1929             !strconcat(TakenStr, " $offset"))))),
1930             []>,
1931             Requires<[HasV4T]>;
1932
1933   def _nv_V4 : NVInst_V4<(outs),
1934             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1935             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1936             !strconcat("($src1.new, $src2)) jump:",
1937             !strconcat(TakenStr, " $offset"))))),
1938             []>,
1939             Requires<[HasV4T]>;
1940 }
1941
1942 multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
1943                                                    string TakenStr> {
1944   def _ie_nv_V4 : NVInst_V4<(outs),
1945             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1946             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1947             !strconcat("($src1, $src2.new)) jump:",
1948             !strconcat(TakenStr, " $offset"))))),
1949             []>,
1950             Requires<[HasV4T]>;
1951
1952   def _nv_V4 : NVInst_V4<(outs),
1953             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1954             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1955             !strconcat("($src1, $src2.new)) jump:",
1956             !strconcat(TakenStr, " $offset"))))),
1957             []>,
1958             Requires<[HasV4T]>;
1959 }
1960
1961 multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
1962   def _ie_nv_V4 : NVInst_V4<(outs),
1963             (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1964             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1965             !strconcat("($src1.new, #$src2)) jump:",
1966             !strconcat(TakenStr, " $offset"))))),
1967             []>,
1968             Requires<[HasV4T]>;
1969
1970   def _nv_V4 : NVInst_V4<(outs),
1971             (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1972             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1973             !strconcat("($src1.new, #$src2)) jump:",
1974             !strconcat(TakenStr, " $offset"))))),
1975             []>,
1976             Requires<[HasV4T]>;
1977 }
1978
1979 multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
1980   def _ie_nv_V4 : NVInst_V4<(outs),
1981             (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1982             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1983             !strconcat("($src1.new, #$src2)) jump:",
1984             !strconcat(TakenStr, " $offset"))))),
1985             []>,
1986             Requires<[HasV4T]>;
1987
1988   def _nv_V4 : NVInst_V4<(outs),
1989             (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1990             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1991             !strconcat("($src1.new, #$src2)) jump:",
1992             !strconcat(TakenStr, " $offset"))))),
1993             []>,
1994             Requires<[HasV4T]>;
1995 }
1996
1997 multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
1998                                                 string TakenStr> {
1999   def _ie_nv_V4 : NVInst_V4<(outs),
2000             (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2001             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2002             !strconcat("($src1.new, #$src2)) jump:",
2003             !strconcat(TakenStr, " $offset"))))),
2004             []>,
2005             Requires<[HasV4T]>;
2006
2007   def _nv_V4 : NVInst_V4<(outs),
2008             (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2009             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2010             !strconcat("($src1.new, #$src2)) jump:",
2011             !strconcat(TakenStr, " $offset"))))),
2012             []>,
2013             Requires<[HasV4T]>;
2014 }
2015
2016 // Multiclass for regular dot new of Ist operand register.
2017 multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> {
2018   defm Pt  : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
2019   defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
2020 }
2021
2022 // Multiclass for dot new of 2nd operand register.
2023 multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
2024   defm Pt  : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
2025   defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
2026 }
2027
2028 // Multiclass for 2nd operand immediate, including -1.
2029 multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
2030   defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2031   defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2032   defm Ptneg  : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
2033   defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
2034 }
2035
2036 // Multiclass for 2nd operand immediate, excluding -1.
2037 multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
2038   defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2039   defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2040 }
2041
2042 // Multiclass for tstbit, where 2nd operand is always #0.
2043 multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
2044   defm Pt     : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
2045   defm Pnt    : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
2046 }
2047
2048 // Multiclass for GT.
2049 multiclass NVJ_type_rr_ri<string OpcStr> {
2050   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2051   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2052   defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2053   defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
2054   defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
2055   defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
2056 }
2057
2058 // Multiclass for EQ.
2059 multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> {
2060   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2061   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2062   defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
2063   defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
2064 }
2065
2066 // Multiclass for GTU.
2067 multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> {
2068   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2069   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2070   defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2071   defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
2072   defm riNot   : NVJ_type_br_pred_imm_only<"!", OpcStr>;
2073   defm ri      : NVJ_type_br_pred_imm_only<"",  OpcStr>;
2074 }
2075
2076 // Multiclass for tstbit.
2077 multiclass NVJ_type_r0<string OpcStr> {
2078   defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
2079   defm r0    : NVJ_type_br_pred_tstbit<"",  OpcStr>;
2080  }
2081
2082 // Base Multiclass for New Value Jump.
2083 multiclass NVJ_type {
2084   defm GT     : NVJ_type_rr_ri<"cmp.gt">;
2085   defm EQ     : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
2086   defm GTU    : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
2087   defm TSTBIT : NVJ_type_r0<"tstbit">;
2088 }
2089
2090 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
2091   defm JMP_ : NVJ_type;
2092 }
2093
2094 //===----------------------------------------------------------------------===//
2095 // NV/J -
2096 //===----------------------------------------------------------------------===//
2097
2098 //===----------------------------------------------------------------------===//
2099 // XTYPE/ALU +
2100 //===----------------------------------------------------------------------===//
2101
2102 //  Add and accumulate.
2103 //  Rd=add(Rs,add(Ru,#s6))
2104 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
2105 validSubTargets = HasV4SubT in
2106 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
2107           (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
2108           "$dst = add($src1, add($src2, #$src3))",
2109           [(set (i32 IntRegs:$dst),
2110            (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
2111                                           s6_16ExtPred:$src3)))]>,
2112           Requires<[HasV4T]>;
2113
2114 //  Rd=add(Rs,sub(#s6,Ru))
2115 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2116 validSubTargets = HasV4SubT in
2117 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
2118           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2119           "$dst = add($src1, sub(#$src2, $src3))",
2120           [(set (i32 IntRegs:$dst),
2121            (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
2122                                           (i32 IntRegs:$src3))))]>,
2123           Requires<[HasV4T]>;
2124
2125 // Generates the same instruction as ADDr_SUBri_V4 but matches different
2126 // pattern.
2127 //  Rd=add(Rs,sub(#s6,Ru))
2128 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2129 validSubTargets = HasV4SubT in
2130 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
2131           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2132           "$dst = add($src1, sub(#$src2, $src3))",
2133           [(set (i32 IntRegs:$dst),
2134                 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
2135                      (i32 IntRegs:$src3)))]>,
2136           Requires<[HasV4T]>;
2137
2138
2139 //  Add or subtract doublewords with carry.
2140 //TODO:
2141 //  Rdd=add(Rss,Rtt,Px):carry
2142 //TODO:
2143 //  Rdd=sub(Rss,Rtt,Px):carry
2144
2145
2146 //  Logical doublewords.
2147 //  Rdd=and(Rtt,~Rss)
2148 let validSubTargets = HasV4SubT in
2149 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2150           (ins DoubleRegs:$src1, DoubleRegs:$src2),
2151           "$dst = and($src1, ~$src2)",
2152           [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
2153                                       (not (i64 DoubleRegs:$src2))))]>,
2154           Requires<[HasV4T]>;
2155
2156 //  Rdd=or(Rtt,~Rss)
2157 let validSubTargets = HasV4SubT in
2158 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2159           (ins DoubleRegs:$src1, DoubleRegs:$src2),
2160           "$dst = or($src1, ~$src2)",
2161           [(set (i64 DoubleRegs:$dst),
2162            (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
2163           Requires<[HasV4T]>;
2164
2165
2166 //  Logical-logical doublewords.
2167 //  Rxx^=xor(Rss,Rtt)
2168 let validSubTargets = HasV4SubT in
2169 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
2170           (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
2171           "$dst ^= xor($src2, $src3)",
2172           [(set (i64 DoubleRegs:$dst),
2173            (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
2174                                              (i64 DoubleRegs:$src3))))],
2175           "$src1 = $dst">,
2176           Requires<[HasV4T]>;
2177
2178
2179 // Logical-logical words.
2180 // Rx=or(Ru,and(Rx,#s10))
2181 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2182 validSubTargets = HasV4SubT in
2183 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
2184             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2185             "$dst = or($src1, and($src2, #$src3))",
2186             [(set (i32 IntRegs:$dst),
2187                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2188                                                 s10ExtPred:$src3)))],
2189             "$src2 = $dst">,
2190             Requires<[HasV4T]>;
2191
2192 // Rx[&|^]=and(Rs,Rt)
2193 // Rx&=and(Rs,Rt)
2194 let validSubTargets = HasV4SubT in
2195 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2196             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2197             "$dst &= and($src2, $src3)",
2198             [(set (i32 IntRegs:$dst),
2199                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2200                                                  (i32 IntRegs:$src3))))],
2201             "$src1 = $dst">,
2202             Requires<[HasV4T]>;
2203
2204 // Rx|=and(Rs,Rt)
2205 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
2206 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2207             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2208             "$dst |= and($src2, $src3)",
2209             [(set (i32 IntRegs:$dst),
2210                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2211                                                 (i32 IntRegs:$src3))))],
2212             "$src1 = $dst">,
2213             Requires<[HasV4T]>, ImmRegRel;
2214
2215 // Rx^=and(Rs,Rt)
2216 let validSubTargets = HasV4SubT in
2217 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2218             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2219             "$dst ^= and($src2, $src3)",
2220             [(set (i32 IntRegs:$dst),
2221              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2222                                             (i32 IntRegs:$src3))))],
2223             "$src1 = $dst">,
2224             Requires<[HasV4T]>;
2225
2226 // Rx[&|^]=and(Rs,~Rt)
2227 // Rx&=and(Rs,~Rt)
2228 let validSubTargets = HasV4SubT in
2229 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2230             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2231             "$dst &= and($src2, ~$src3)",
2232             [(set (i32 IntRegs:$dst),
2233                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2234                                                  (not (i32 IntRegs:$src3)))))],
2235             "$src1 = $dst">,
2236             Requires<[HasV4T]>;
2237
2238 // Rx|=and(Rs,~Rt)
2239 let validSubTargets = HasV4SubT in
2240 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2241             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2242             "$dst |= and($src2, ~$src3)",
2243             [(set (i32 IntRegs:$dst),
2244              (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2245                                            (not (i32 IntRegs:$src3)))))],
2246             "$src1 = $dst">,
2247             Requires<[HasV4T]>;
2248
2249 // Rx^=and(Rs,~Rt)
2250 let validSubTargets = HasV4SubT in
2251 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2252             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2253             "$dst ^= and($src2, ~$src3)",
2254             [(set (i32 IntRegs:$dst),
2255              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2256                                             (not (i32 IntRegs:$src3)))))],
2257             "$src1 = $dst">,
2258             Requires<[HasV4T]>;
2259
2260 // Rx[&|^]=or(Rs,Rt)
2261 // Rx&=or(Rs,Rt)
2262 let validSubTargets = HasV4SubT in
2263 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2264             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2265             "$dst &= or($src2, $src3)",
2266             [(set (i32 IntRegs:$dst),
2267                   (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2268                                                 (i32 IntRegs:$src3))))],
2269             "$src1 = $dst">,
2270             Requires<[HasV4T]>;
2271
2272 // Rx|=or(Rs,Rt)
2273 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
2274 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2275             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2276             "$dst |= or($src2, $src3)",
2277             [(set (i32 IntRegs:$dst),
2278                   (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2279                                                (i32 IntRegs:$src3))))],
2280             "$src1 = $dst">,
2281             Requires<[HasV4T]>, ImmRegRel;
2282
2283 // Rx^=or(Rs,Rt)
2284 let validSubTargets = HasV4SubT in
2285 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2286             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2287             "$dst ^= or($src2, $src3)",
2288             [(set (i32 IntRegs:$dst),
2289              (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2290                                            (i32 IntRegs:$src3))))],
2291             "$src1 = $dst">,
2292             Requires<[HasV4T]>;
2293
2294 // Rx[&|^]=xor(Rs,Rt)
2295 // Rx&=xor(Rs,Rt)
2296 let validSubTargets = HasV4SubT in
2297 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2298             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2299             "$dst &= xor($src2, $src3)",
2300             [(set (i32 IntRegs:$dst),
2301                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2302                                                  (i32 IntRegs:$src3))))],
2303             "$src1 = $dst">,
2304             Requires<[HasV4T]>;
2305
2306 // Rx|=xor(Rs,Rt)
2307 let validSubTargets = HasV4SubT in
2308 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2309             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2310             "$dst |= xor($src2, $src3)",
2311             [(set (i32 IntRegs:$dst),
2312                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2313                                                  (i32 IntRegs:$src3))))],
2314             "$src1 = $dst">,
2315             Requires<[HasV4T]>;
2316
2317 // Rx^=xor(Rs,Rt)
2318 let validSubTargets = HasV4SubT in
2319 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2320             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2321             "$dst ^= xor($src2, $src3)",
2322             [(set (i32 IntRegs:$dst),
2323              (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2324                                             (i32 IntRegs:$src3))))],
2325             "$src1 = $dst">,
2326             Requires<[HasV4T]>;
2327
2328 // Rx|=and(Rs,#s10)
2329 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2330 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
2331 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
2332             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2333             "$dst |= and($src2, #$src3)",
2334             [(set (i32 IntRegs:$dst),
2335                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2336                                                 s10ExtPred:$src3)))],
2337             "$src1 = $dst">,
2338             Requires<[HasV4T]>, ImmRegRel;
2339
2340 // Rx|=or(Rs,#s10)
2341 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2342 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
2343 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
2344             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2345             "$dst |= or($src2, #$src3)",
2346             [(set (i32 IntRegs:$dst),
2347                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2348                                                 s10ExtPred:$src3)))],
2349             "$src1 = $dst">,
2350             Requires<[HasV4T]>, ImmRegRel;
2351
2352
2353 //    Modulo wrap
2354 //        Rd=modwrap(Rs,Rt)
2355 //    Round
2356 //        Rd=cround(Rs,#u5)
2357 //        Rd=cround(Rs,Rt)
2358 //        Rd=round(Rs,#u5)[:sat]
2359 //        Rd=round(Rs,Rt)[:sat]
2360 //    Vector reduce add unsigned halfwords
2361 //        Rd=vraddh(Rss,Rtt)
2362 //    Vector add bytes
2363 //        Rdd=vaddb(Rss,Rtt)
2364 //    Vector conditional negate
2365 //        Rdd=vcnegh(Rss,Rt)
2366 //        Rxx+=vrcnegh(Rss,Rt)
2367 //    Vector maximum bytes
2368 //        Rdd=vmaxb(Rtt,Rss)
2369 //    Vector reduce maximum halfwords
2370 //        Rxx=vrmaxh(Rss,Ru)
2371 //        Rxx=vrmaxuh(Rss,Ru)
2372 //    Vector reduce maximum words
2373 //        Rxx=vrmaxuw(Rss,Ru)
2374 //        Rxx=vrmaxw(Rss,Ru)
2375 //    Vector minimum bytes
2376 //        Rdd=vminb(Rtt,Rss)
2377 //    Vector reduce minimum halfwords
2378 //        Rxx=vrminh(Rss,Ru)
2379 //        Rxx=vrminuh(Rss,Ru)
2380 //    Vector reduce minimum words
2381 //        Rxx=vrminuw(Rss,Ru)
2382 //        Rxx=vrminw(Rss,Ru)
2383 //    Vector subtract bytes
2384 //        Rdd=vsubb(Rss,Rtt)
2385
2386 //===----------------------------------------------------------------------===//
2387 // XTYPE/ALU -
2388 //===----------------------------------------------------------------------===//
2389
2390
2391 //===----------------------------------------------------------------------===//
2392 // XTYPE/MPY +
2393 //===----------------------------------------------------------------------===//
2394
2395 // Multiply and user lower result.
2396 // Rd=add(#u6,mpyi(Rs,#U6))
2397 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2398 validSubTargets = HasV4SubT in
2399 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
2400             (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
2401             "$dst = add(#$src1, mpyi($src2, #$src3))",
2402             [(set (i32 IntRegs:$dst),
2403                   (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2404                        u6ExtPred:$src1))]>,
2405             Requires<[HasV4T]>;
2406
2407 // Rd=add(##,mpyi(Rs,#U6))
2408 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2409                      (HexagonCONST32 tglobaladdr:$src1)),
2410            (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
2411                                u6ImmPred:$src3))>;
2412
2413 // Rd=add(#u6,mpyi(Rs,Rt))
2414 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2415 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2416 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
2417             (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
2418             "$dst = add(#$src1, mpyi($src2, $src3))",
2419             [(set (i32 IntRegs:$dst),
2420                   (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2421                        u6ExtPred:$src1))]>,
2422             Requires<[HasV4T]>, ImmRegRel;
2423
2424 // Rd=add(##,mpyi(Rs,Rt))
2425 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2426                      (HexagonCONST32 tglobaladdr:$src1)),
2427            (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
2428                                IntRegs:$src3))>;
2429
2430 // Rd=add(Ru,mpyi(#u6:2,Rs))
2431 let validSubTargets = HasV4SubT in
2432 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
2433             (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
2434             "$dst = add($src1, mpyi(#$src2, $src3))",
2435             [(set (i32 IntRegs:$dst),
2436              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
2437                                             u6_2ImmPred:$src2)))]>,
2438             Requires<[HasV4T]>;
2439
2440 // Rd=add(Ru,mpyi(Rs,#u6))
2441 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
2442 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2443 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
2444             (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
2445             "$dst = add($src1, mpyi($src2, #$src3))",
2446             [(set (i32 IntRegs:$dst),
2447                   (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2448                                                  u6ExtPred:$src3)))]>,
2449             Requires<[HasV4T]>, ImmRegRel;
2450
2451 // Rx=add(Ru,mpyi(Rx,Rs))
2452 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
2453 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
2454             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
2455             "$dst = add($src1, mpyi($src2, $src3))",
2456             [(set (i32 IntRegs:$dst),
2457              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2458                                             (i32 IntRegs:$src3))))],
2459             "$src2 = $dst">,
2460             Requires<[HasV4T]>, ImmRegRel;
2461
2462
2463 // Polynomial multiply words
2464 // Rdd=pmpyw(Rs,Rt)
2465 // Rxx^=pmpyw(Rs,Rt)
2466
2467 // Vector reduce multiply word by signed half (32x16)
2468 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
2469 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2470 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
2471 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
2472
2473 // Multiply and use upper result
2474 // Rd=mpy(Rs,Rt.H):<<1:sat
2475 // Rd=mpy(Rs,Rt.L):<<1:sat
2476 // Rd=mpy(Rs,Rt):<<1
2477 // Rd=mpy(Rs,Rt):<<1:sat
2478 // Rd=mpysu(Rs,Rt)
2479 // Rx+=mpy(Rs,Rt):<<1:sat
2480 // Rx-=mpy(Rs,Rt):<<1:sat
2481
2482 // Vector multiply bytes
2483 // Rdd=vmpybsu(Rs,Rt)
2484 // Rdd=vmpybu(Rs,Rt)
2485 // Rxx+=vmpybsu(Rs,Rt)
2486 // Rxx+=vmpybu(Rs,Rt)
2487
2488 // Vector polynomial multiply halfwords
2489 // Rdd=vpmpyh(Rs,Rt)
2490 // Rxx^=vpmpyh(Rs,Rt)
2491
2492 //===----------------------------------------------------------------------===//
2493 // XTYPE/MPY -
2494 //===----------------------------------------------------------------------===//
2495
2496
2497 //===----------------------------------------------------------------------===//
2498 // XTYPE/SHIFT +
2499 //===----------------------------------------------------------------------===//
2500
2501 // Shift by immediate and accumulate.
2502 // Rx=add(#u8,asl(Rx,#U5))
2503 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2504 validSubTargets = HasV4SubT in
2505 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2506             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2507             "$dst = add(#$src1, asl($src2, #$src3))",
2508             [(set (i32 IntRegs:$dst),
2509                   (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2510                        u8ExtPred:$src1))],
2511             "$src2 = $dst">,
2512             Requires<[HasV4T]>;
2513
2514 // Rx=add(#u8,lsr(Rx,#U5))
2515 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2516 validSubTargets = HasV4SubT in
2517 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2518             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2519             "$dst = add(#$src1, lsr($src2, #$src3))",
2520             [(set (i32 IntRegs:$dst),
2521                   (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2522                        u8ExtPred:$src1))],
2523             "$src2 = $dst">,
2524             Requires<[HasV4T]>;
2525
2526 // Rx=sub(#u8,asl(Rx,#U5))
2527 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2528 validSubTargets = HasV4SubT in
2529 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2530             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2531             "$dst = sub(#$src1, asl($src2, #$src3))",
2532             [(set (i32 IntRegs:$dst),
2533                   (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2534                        u8ExtPred:$src1))],
2535             "$src2 = $dst">,
2536             Requires<[HasV4T]>;
2537
2538 // Rx=sub(#u8,lsr(Rx,#U5))
2539 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2540 validSubTargets = HasV4SubT in
2541 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2542             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2543             "$dst = sub(#$src1, lsr($src2, #$src3))",
2544             [(set (i32 IntRegs:$dst),
2545                   (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2546                        u8ExtPred:$src1))],
2547             "$src2 = $dst">,
2548             Requires<[HasV4T]>;
2549
2550
2551 //Shift by immediate and logical.
2552 //Rx=and(#u8,asl(Rx,#U5))
2553 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2554 validSubTargets = HasV4SubT in
2555 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2556             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2557             "$dst = and(#$src1, asl($src2, #$src3))",
2558             [(set (i32 IntRegs:$dst),
2559                   (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2560                        u8ExtPred:$src1))],
2561             "$src2 = $dst">,
2562             Requires<[HasV4T]>;
2563
2564 //Rx=and(#u8,lsr(Rx,#U5))
2565 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2566 validSubTargets = HasV4SubT in
2567 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2568             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2569             "$dst = and(#$src1, lsr($src2, #$src3))",
2570             [(set (i32 IntRegs:$dst),
2571                   (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2572                        u8ExtPred:$src1))],
2573             "$src2 = $dst">,
2574             Requires<[HasV4T]>;
2575
2576 //Rx=or(#u8,asl(Rx,#U5))
2577 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2578 AddedComplexity = 30, validSubTargets = HasV4SubT in
2579 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2580             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2581             "$dst = or(#$src1, asl($src2, #$src3))",
2582             [(set (i32 IntRegs:$dst),
2583                   (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2584                       u8ExtPred:$src1))],
2585             "$src2 = $dst">,
2586             Requires<[HasV4T]>;
2587
2588 //Rx=or(#u8,lsr(Rx,#U5))
2589 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2590 AddedComplexity = 30, validSubTargets = HasV4SubT in
2591 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2592             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2593             "$dst = or(#$src1, lsr($src2, #$src3))",
2594             [(set (i32 IntRegs:$dst),
2595                   (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2596                       u8ExtPred:$src1))],
2597             "$src2 = $dst">,
2598             Requires<[HasV4T]>;
2599
2600
2601 //Shift by register.
2602 //Rd=lsl(#s6,Rt)
2603 let validSubTargets = HasV4SubT in {
2604 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
2605             "$dst = lsl(#$src1, $src2)",
2606             [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
2607                                            (i32 IntRegs:$src2)))]>,
2608             Requires<[HasV4T]>;
2609
2610
2611 //Shift by register and logical.
2612 //Rxx^=asl(Rss,Rt)
2613 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2614             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2615             "$dst ^= asl($src2, $src3)",
2616             [(set (i64 DoubleRegs:$dst),
2617                   (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
2618                                                     (i32 IntRegs:$src3))))],
2619             "$src1 = $dst">,
2620             Requires<[HasV4T]>;
2621
2622 //Rxx^=asr(Rss,Rt)
2623 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2624             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2625             "$dst ^= asr($src2, $src3)",
2626             [(set (i64 DoubleRegs:$dst),
2627                   (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
2628                                                     (i32 IntRegs:$src3))))],
2629             "$src1 = $dst">,
2630             Requires<[HasV4T]>;
2631
2632 //Rxx^=lsl(Rss,Rt)
2633 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2634             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2635             "$dst ^= lsl($src2, $src3)",
2636             [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
2637                                               (shl (i64 DoubleRegs:$src2),
2638                                                    (i32 IntRegs:$src3))))],
2639             "$src1 = $dst">,
2640             Requires<[HasV4T]>;
2641
2642 //Rxx^=lsr(Rss,Rt)
2643 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2644             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2645             "$dst ^= lsr($src2, $src3)",
2646             [(set (i64 DoubleRegs:$dst),
2647                   (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
2648                                                     (i32 IntRegs:$src3))))],
2649             "$src1 = $dst">,
2650             Requires<[HasV4T]>;
2651 }
2652
2653 //===----------------------------------------------------------------------===//
2654 // XTYPE/SHIFT -
2655 //===----------------------------------------------------------------------===//
2656
2657 //===----------------------------------------------------------------------===//
2658 // MEMOP: Word, Half, Byte
2659 //===----------------------------------------------------------------------===//
2660
2661 //===----------------------------------------------------------------------===//
2662 // MEMOP: Word
2663 //
2664 //  Implemented:
2665 //     MEMw_ADDi_indexed_V4  : memw(Rs+#u6:2)+=#U5
2666 //     MEMw_SUBi_indexed_V4  : memw(Rs+#u6:2)-=#U5
2667 //     MEMw_ADDr_indexed_V4  : memw(Rs+#u6:2)+=Rt
2668 //     MEMw_SUBr_indexed_V4  : memw(Rs+#u6:2)-=Rt
2669 //     MEMw_CLRr_indexed_V4  : memw(Rs+#u6:2)&=Rt
2670 //     MEMw_SETr_indexed_V4  : memw(Rs+#u6:2)|=Rt
2671 //     MEMw_ADDi_V4          : memw(Rs+#u6:2)+=#U5
2672 //     MEMw_SUBi_V4          : memw(Rs+#u6:2)-=#U5
2673 //     MEMw_ADDr_V4          : memw(Rs+#u6:2)+=Rt
2674 //     MEMw_SUBr_V4          : memw(Rs+#u6:2)-=Rt
2675 //     MEMw_CLRr_V4          : memw(Rs+#u6:2)&=Rt
2676 //     MEMw_SETr_V4          : memw(Rs+#u6:2)|=Rt
2677 //
2678 //   Not implemented:
2679 //     MEMw_CLRi_indexed_V4  : memw(Rs+#u6:2)=clrbit(#U5)
2680 //     MEMw_SETi_indexed_V4  : memw(Rs+#u6:2)=setbit(#U5)
2681 //     MEMw_CLRi_V4          : memw(Rs+#u6:2)=clrbit(#U5)
2682 //     MEMw_SETi_V4          : memw(Rs+#u6:2)=setbit(#U5)
2683 //===----------------------------------------------------------------------===//
2684
2685
2686
2687 // memw(Rs+#u6:2) += #U5
2688 let AddedComplexity = 30 in
2689 def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2690             (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
2691             "memw($base+#$offset) += #$addend",
2692             []>,
2693             Requires<[HasV4T, UseMEMOP]>;
2694
2695 // memw(Rs+#u6:2) -= #U5
2696 let AddedComplexity = 30 in
2697 def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2698             (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
2699             "memw($base+#$offset) -= #$subend",
2700             []>,
2701             Requires<[HasV4T, UseMEMOP]>;
2702
2703 // memw(Rs+#u6:2) += Rt
2704 let AddedComplexity = 30 in
2705 def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2706             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
2707             "memw($base+#$offset) += $addend",
2708             [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2709                          (i32 IntRegs:$addend)),
2710                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2711             Requires<[HasV4T, UseMEMOP]>;
2712
2713 // memw(Rs+#u6:2) -= Rt
2714 let AddedComplexity = 30 in
2715 def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2716             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
2717             "memw($base+#$offset) -= $subend",
2718             [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2719                          (i32 IntRegs:$subend)),
2720                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2721             Requires<[HasV4T, UseMEMOP]>;
2722
2723 // memw(Rs+#u6:2) &= Rt
2724 let AddedComplexity = 30 in
2725 def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2726             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
2727             "memw($base+#$offset) &= $andend",
2728             [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2729                          (i32 IntRegs:$andend)),
2730                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2731             Requires<[HasV4T, UseMEMOP]>;
2732
2733 // memw(Rs+#u6:2) |= Rt
2734 let AddedComplexity = 30 in
2735 def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2736             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
2737             "memw($base+#$offset) |= $orend",
2738             [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2739                         (i32 IntRegs:$orend)),
2740                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2741             Requires<[HasV4T, UseMEMOP]>;
2742
2743 // memw(Rs+#u6:2) += #U5
2744 let AddedComplexity = 30 in
2745 def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
2746             (ins MEMri:$addr, u5Imm:$addend),
2747             "memw($addr) += $addend",
2748             []>,
2749             Requires<[HasV4T, UseMEMOP]>;
2750
2751 // memw(Rs+#u6:2) -= #U5
2752 let AddedComplexity = 30 in
2753 def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
2754             (ins MEMri:$addr, u5Imm:$subend),
2755             "memw($addr) -= $subend",
2756             []>,
2757             Requires<[HasV4T, UseMEMOP]>;
2758
2759 // memw(Rs+#u6:2) += Rt
2760 let AddedComplexity = 30 in
2761 def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
2762             (ins MEMri:$addr, IntRegs:$addend),
2763             "memw($addr) += $addend",
2764             [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
2765                     ADDRriU6_2:$addr)]>,
2766             Requires<[HasV4T, UseMEMOP]>;
2767
2768 // memw(Rs+#u6:2) -= Rt
2769 let AddedComplexity = 30 in
2770 def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
2771             (ins MEMri:$addr, IntRegs:$subend),
2772             "memw($addr) -= $subend",
2773             [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
2774                     ADDRriU6_2:$addr)]>,
2775             Requires<[HasV4T, UseMEMOP]>;
2776
2777 // memw(Rs+#u6:2) &= Rt
2778 let AddedComplexity = 30 in
2779 def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
2780             (ins MEMri:$addr, IntRegs:$andend),
2781             "memw($addr) &= $andend",
2782             [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
2783                     ADDRriU6_2:$addr)]>,
2784             Requires<[HasV4T, UseMEMOP]>;
2785
2786 // memw(Rs+#u6:2) |= Rt
2787 let AddedComplexity = 30 in
2788 def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
2789             (ins MEMri:$addr, IntRegs:$orend),
2790             "memw($addr) |= $orend",
2791             [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
2792                     ADDRriU6_2:$addr)]>,
2793             Requires<[HasV4T, UseMEMOP]>;
2794
2795 //===----------------------------------------------------------------------===//
2796 // MEMOP: Halfword
2797 //
2798 //  Implemented:
2799 //     MEMh_ADDi_indexed_V4  : memw(Rs+#u6:2)+=#U5
2800 //     MEMh_SUBi_indexed_V4  : memw(Rs+#u6:2)-=#U5
2801 //     MEMh_ADDr_indexed_V4  : memw(Rs+#u6:2)+=Rt
2802 //     MEMh_SUBr_indexed_V4  : memw(Rs+#u6:2)-=Rt
2803 //     MEMh_CLRr_indexed_V4  : memw(Rs+#u6:2)&=Rt
2804 //     MEMh_SETr_indexed_V4  : memw(Rs+#u6:2)|=Rt
2805 //     MEMh_ADDi_V4          : memw(Rs+#u6:2)+=#U5
2806 //     MEMh_SUBi_V4          : memw(Rs+#u6:2)-=#U5
2807 //     MEMh_ADDr_V4          : memw(Rs+#u6:2)+=Rt
2808 //     MEMh_SUBr_V4          : memw(Rs+#u6:2)-=Rt
2809 //     MEMh_CLRr_V4          : memw(Rs+#u6:2)&=Rt
2810 //     MEMh_SETr_V4          : memw(Rs+#u6:2)|=Rt
2811 //
2812 //   Not implemented:
2813 //     MEMh_CLRi_indexed_V4  : memw(Rs+#u6:2)=clrbit(#U5)
2814 //     MEMh_SETi_indexed_V4  : memw(Rs+#u6:2)=setbit(#U5)
2815 //     MEMh_CLRi_V4          : memw(Rs+#u6:2)=clrbit(#U5)
2816 //     MEMh_SETi_V4          : memw(Rs+#u6:2)=setbit(#U5)
2817 //===----------------------------------------------------------------------===//
2818
2819
2820 // memh(Rs+#u6:1) += #U5
2821 let AddedComplexity = 30 in
2822 def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2823             (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
2824             "memh($base+#$offset) += $addend",
2825             []>,
2826             Requires<[HasV4T, UseMEMOP]>;
2827
2828 // memh(Rs+#u6:1) -= #U5
2829 let AddedComplexity = 30 in
2830 def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2831             (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
2832             "memh($base+#$offset) -= $subend",
2833             []>,
2834             Requires<[HasV4T, UseMEMOP]>;
2835
2836 // memh(Rs+#u6:1) += Rt
2837 let AddedComplexity = 30 in
2838 def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2839             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
2840             "memh($base+#$offset) += $addend",
2841             [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
2842                                                    u6_1ImmPred:$offset)),
2843                                  (i32 IntRegs:$addend)),
2844                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2845             Requires<[HasV4T, UseMEMOP]>;
2846
2847 // memh(Rs+#u6:1) -= Rt
2848 let AddedComplexity = 30 in
2849 def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2850             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
2851             "memh($base+#$offset) -= $subend",
2852             [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
2853                                                    u6_1ImmPred:$offset)),
2854                                  (i32 IntRegs:$subend)),
2855                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2856             Requires<[HasV4T, UseMEMOP]>;
2857
2858 // memh(Rs+#u6:1) &= Rt
2859 let AddedComplexity = 30 in
2860 def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2861             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
2862             "memh($base+#$offset) += $andend",
2863             [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
2864                                                    u6_1ImmPred:$offset)),
2865                                  (i32 IntRegs:$andend)),
2866                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2867             Requires<[HasV4T, UseMEMOP]>;
2868
2869 // memh(Rs+#u6:1) |= Rt
2870 let AddedComplexity = 30 in
2871 def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2872             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
2873             "memh($base+#$offset) |= $orend",
2874             [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
2875                                               u6_1ImmPred:$offset)),
2876                              (i32 IntRegs:$orend)),
2877                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2878             Requires<[HasV4T, UseMEMOP]>;
2879
2880 // memh(Rs+#u6:1) += #U5
2881 let AddedComplexity = 30 in
2882 def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
2883             (ins MEMri:$addr, u5Imm:$addend),
2884             "memh($addr) += $addend",
2885             []>,
2886             Requires<[HasV4T, UseMEMOP]>;
2887
2888 // memh(Rs+#u6:1) -= #U5
2889 let AddedComplexity = 30 in
2890 def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
2891             (ins MEMri:$addr, u5Imm:$subend),
2892             "memh($addr) -= $subend",
2893             []>,
2894             Requires<[HasV4T, UseMEMOP]>;
2895
2896 // memh(Rs+#u6:1) += Rt
2897 let AddedComplexity = 30 in
2898 def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
2899             (ins MEMri:$addr, IntRegs:$addend),
2900             "memh($addr) += $addend",
2901             [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
2902                                  (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
2903             Requires<[HasV4T, UseMEMOP]>;
2904
2905 // memh(Rs+#u6:1) -= Rt
2906 let AddedComplexity = 30 in
2907 def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
2908             (ins MEMri:$addr, IntRegs:$subend),
2909             "memh($addr) -= $subend",
2910             [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
2911                                  (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
2912             Requires<[HasV4T, UseMEMOP]>;
2913
2914 // memh(Rs+#u6:1) &= Rt
2915 let AddedComplexity = 30 in
2916 def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
2917             (ins MEMri:$addr, IntRegs:$andend),
2918             "memh($addr) &= $andend",
2919             [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
2920                                  (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
2921             Requires<[HasV4T, UseMEMOP]>;
2922
2923 // memh(Rs+#u6:1) |= Rt
2924 let AddedComplexity = 30 in
2925 def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
2926             (ins MEMri:$addr, IntRegs:$orend),
2927             "memh($addr) |= $orend",
2928             [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
2929                                 (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
2930             Requires<[HasV4T, UseMEMOP]>;
2931
2932
2933 //===----------------------------------------------------------------------===//
2934 // MEMOP: Byte
2935 //
2936 //  Implemented:
2937 //     MEMb_ADDi_indexed_V4  : memb(Rs+#u6:0)+=#U5
2938 //     MEMb_SUBi_indexed_V4  : memb(Rs+#u6:0)-=#U5
2939 //     MEMb_ADDr_indexed_V4  : memb(Rs+#u6:0)+=Rt
2940 //     MEMb_SUBr_indexed_V4  : memb(Rs+#u6:0)-=Rt
2941 //     MEMb_CLRr_indexed_V4  : memb(Rs+#u6:0)&=Rt
2942 //     MEMb_SETr_indexed_V4  : memb(Rs+#u6:0)|=Rt
2943 //     MEMb_ADDi_V4          : memb(Rs+#u6:0)+=#U5
2944 //     MEMb_SUBi_V4          : memb(Rs+#u6:0)-=#U5
2945 //     MEMb_ADDr_V4          : memb(Rs+#u6:0)+=Rt
2946 //     MEMb_SUBr_V4          : memb(Rs+#u6:0)-=Rt
2947 //     MEMb_CLRr_V4          : memb(Rs+#u6:0)&=Rt
2948 //     MEMb_SETr_V4          : memb(Rs+#u6:0)|=Rt
2949 //
2950 //   Not implemented:
2951 //     MEMb_CLRi_indexed_V4  : memb(Rs+#u6:0)=clrbit(#U5)
2952 //     MEMb_SETi_indexed_V4  : memb(Rs+#u6:0)=setbit(#U5)
2953 //     MEMb_CLRi_V4          : memb(Rs+#u6:0)=clrbit(#U5)
2954 //     MEMb_SETi_V4          : memb(Rs+#u6:0)=setbit(#U5)
2955 //===----------------------------------------------------------------------===//
2956
2957 // memb(Rs+#u6:0) += #U5
2958 let AddedComplexity = 30 in
2959 def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2960             (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
2961             "memb($base+#$offset) += $addend",
2962             []>,
2963             Requires<[HasV4T, UseMEMOP]>;
2964
2965 // memb(Rs+#u6:0) -= #U5
2966 let AddedComplexity = 30 in
2967 def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2968             (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
2969             "memb($base+#$offset) -= $subend",
2970             []>,
2971             Requires<[HasV4T, UseMEMOP]>;
2972
2973 // memb(Rs+#u6:0) += Rt
2974 let AddedComplexity = 30 in
2975 def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2976             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
2977             "memb($base+#$offset) += $addend",
2978             [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
2979                                                  u6_0ImmPred:$offset)),
2980                                 (i32 IntRegs:$addend)),
2981                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2982             Requires<[HasV4T, UseMEMOP]>;
2983
2984 // memb(Rs+#u6:0) -= Rt
2985 let AddedComplexity = 30 in
2986 def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2987             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
2988             "memb($base+#$offset) -= $subend",
2989             [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
2990                                                  u6_0ImmPred:$offset)),
2991                                 (i32 IntRegs:$subend)),
2992                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2993             Requires<[HasV4T, UseMEMOP]>;
2994
2995 // memb(Rs+#u6:0) &= Rt
2996 let AddedComplexity = 30 in
2997 def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2998             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
2999             "memb($base+#$offset) += $andend",
3000             [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
3001                                                  u6_0ImmPred:$offset)),
3002                                 (i32 IntRegs:$andend)),
3003                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3004             Requires<[HasV4T, UseMEMOP]>;
3005
3006 // memb(Rs+#u6:0) |= Rt
3007 let AddedComplexity = 30 in
3008 def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
3009             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
3010             "memb($base+#$offset) |= $orend",
3011             [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
3012                                                 u6_0ImmPred:$offset)),
3013                                (i32 IntRegs:$orend)),
3014                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3015             Requires<[HasV4T, UseMEMOP]>;
3016
3017 // memb(Rs+#u6:0) += #U5
3018 let AddedComplexity = 30 in
3019 def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
3020             (ins MEMri:$addr, u5Imm:$addend),
3021             "memb($addr) += $addend",
3022             []>,
3023             Requires<[HasV4T, UseMEMOP]>;
3024
3025 // memb(Rs+#u6:0) -= #U5
3026 let AddedComplexity = 30 in
3027 def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
3028             (ins MEMri:$addr, u5Imm:$subend),
3029             "memb($addr) -= $subend",
3030             []>,
3031             Requires<[HasV4T, UseMEMOP]>;
3032
3033 // memb(Rs+#u6:0) += Rt
3034 let AddedComplexity = 30 in
3035 def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
3036             (ins MEMri:$addr, IntRegs:$addend),
3037             "memb($addr) += $addend",
3038             [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
3039                                 (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
3040             Requires<[HasV4T, UseMEMOP]>;
3041
3042 // memb(Rs+#u6:0) -= Rt
3043 let AddedComplexity = 30 in
3044 def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
3045             (ins MEMri:$addr, IntRegs:$subend),
3046             "memb($addr) -= $subend",
3047             [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
3048                                 (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
3049             Requires<[HasV4T, UseMEMOP]>;
3050
3051 // memb(Rs+#u6:0) &= Rt
3052 let AddedComplexity = 30 in
3053 def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
3054             (ins MEMri:$addr, IntRegs:$andend),
3055             "memb($addr) &= $andend",
3056             [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
3057                                 (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
3058             Requires<[HasV4T, UseMEMOP]>;
3059
3060 // memb(Rs+#u6:0) |= Rt
3061 let AddedComplexity = 30 in
3062 def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
3063             (ins MEMri:$addr, IntRegs:$orend),
3064             "memb($addr) |= $orend",
3065             [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
3066                                (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
3067             Requires<[HasV4T, UseMEMOP]>;
3068
3069
3070 //===----------------------------------------------------------------------===//
3071 // XTYPE/PRED +
3072 //===----------------------------------------------------------------------===//
3073
3074 // Hexagon V4 only supports these flavors of byte/half compare instructions:
3075 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
3076 // hardware. However, compiler can still implement these patterns through
3077 // appropriate patterns combinations based on current implemented patterns.
3078 // The implemented patterns are: EQ/GT/GTU.
3079 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
3080
3081 // Following instruction is not being extended as it results into the
3082 // incorrect code for negative numbers.
3083 // Pd=cmpb.eq(Rs,#u8)
3084
3085 // p=!cmp.eq(r1,r2)
3086 let isCompare = 1, validSubTargets = HasV4SubT in
3087 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
3088                            (ins IntRegs:$src1, IntRegs:$src2),
3089       "$dst = !cmp.eq($src1, $src2)",
3090       [(set (i1 PredRegs:$dst),
3091             (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
3092       Requires<[HasV4T]>;
3093
3094 // p=!cmp.eq(r1,#s10)
3095 let isCompare = 1, validSubTargets = HasV4SubT in
3096 def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
3097                            (ins IntRegs:$src1, s10Ext:$src2),
3098       "$dst = !cmp.eq($src1, #$src2)",
3099       [(set (i1 PredRegs:$dst),
3100             (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
3101       Requires<[HasV4T]>;
3102
3103 // p=!cmp.gt(r1,r2)
3104 let isCompare = 1, validSubTargets = HasV4SubT in
3105 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
3106                            (ins IntRegs:$src1, IntRegs:$src2),
3107       "$dst = !cmp.gt($src1, $src2)",
3108       [(set (i1 PredRegs:$dst),
3109             (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3110       Requires<[HasV4T]>;
3111
3112 // p=!cmp.gt(r1,#s10)
3113 let isCompare = 1, validSubTargets = HasV4SubT in
3114 def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
3115                            (ins IntRegs:$src1, s10Ext:$src2),
3116       "$dst = !cmp.gt($src1, #$src2)",
3117       [(set (i1 PredRegs:$dst),
3118             (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
3119       Requires<[HasV4T]>;
3120
3121 // p=!cmp.gtu(r1,r2)
3122 let isCompare = 1, validSubTargets = HasV4SubT in
3123 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
3124                             (ins IntRegs:$src1, IntRegs:$src2),
3125       "$dst = !cmp.gtu($src1, $src2)",
3126       [(set (i1 PredRegs:$dst),
3127             (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3128       Requires<[HasV4T]>;
3129
3130 // p=!cmp.gtu(r1,#u9)
3131 let isCompare = 1, validSubTargets = HasV4SubT in
3132 def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
3133                             (ins IntRegs:$src1, u9Ext:$src2),
3134       "$dst = !cmp.gtu($src1, #$src2)",
3135       [(set (i1 PredRegs:$dst),
3136             (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
3137       Requires<[HasV4T]>;
3138
3139 let isCompare = 1, validSubTargets = HasV4SubT in
3140 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
3141             (ins IntRegs:$src1, u8Imm:$src2),
3142             "$dst = cmpb.eq($src1, #$src2)",
3143             [(set (i1 PredRegs:$dst),
3144                   (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
3145             Requires<[HasV4T]>;
3146
3147 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
3148                        bb:$offset),
3149       (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
3150                 bb:$offset)>,
3151       Requires<[HasV4T]>;
3152
3153 // Pd=cmpb.eq(Rs,Rt)
3154 let isCompare = 1, validSubTargets = HasV4SubT in
3155 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
3156             (ins IntRegs:$src1, IntRegs:$src2),
3157             "$dst = cmpb.eq($src1, $src2)",
3158             [(set (i1 PredRegs:$dst),
3159                   (seteq (and (xor (i32 IntRegs:$src1),
3160                                    (i32 IntRegs:$src2)), 255), 0))]>,
3161             Requires<[HasV4T]>;
3162
3163 // Pd=cmpb.eq(Rs,Rt)
3164 let isCompare = 1, validSubTargets = HasV4SubT in
3165 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
3166             (ins IntRegs:$src1, IntRegs:$src2),
3167             "$dst = cmpb.eq($src1, $src2)",
3168             [(set (i1 PredRegs:$dst),
3169                   (seteq (shl (i32 IntRegs:$src1), (i32 24)),
3170                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
3171             Requires<[HasV4T]>;
3172
3173 // Pd=cmpb.gt(Rs,Rt)
3174 let isCompare = 1, validSubTargets = HasV4SubT in
3175 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
3176             (ins IntRegs:$src1, IntRegs:$src2),
3177             "$dst = cmpb.gt($src1, $src2)",
3178             [(set (i1 PredRegs:$dst),
3179                   (setgt (shl (i32 IntRegs:$src1), (i32 24)),
3180                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
3181             Requires<[HasV4T]>;
3182
3183 // Pd=cmpb.gtu(Rs,#u7)
3184 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3185 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
3186 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
3187             (ins IntRegs:$src1, u7Ext:$src2),
3188             "$dst = cmpb.gtu($src1, #$src2)",
3189             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3190                                               u7ExtPred:$src2))]>,
3191             Requires<[HasV4T]>, ImmRegRel;
3192
3193 // SDNode for converting immediate C to C-1.
3194 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
3195    // Return the byte immediate const-1 as an SDNode.
3196    int32_t imm = N->getSExtValue();
3197    return XformU7ToU7M1Imm(imm);
3198 }]>;
3199
3200 // For the sequence
3201 //   zext( seteq ( and(Rs, 255), u8))
3202 // Generate
3203 //   Pd=cmpb.eq(Rs, #u8)
3204 //   if (Pd.new) Rd=#1
3205 //   if (!Pd.new) Rd=#0
3206 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
3207                                            u8ExtPred:$u8)))),
3208            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3209                                                  (u8ExtPred:$u8))),
3210                                 1, 0))>,
3211            Requires<[HasV4T]>;
3212
3213 // For the sequence
3214 //   zext( setne ( and(Rs, 255), u8))
3215 // Generate
3216 //   Pd=cmpb.eq(Rs, #u8)
3217 //   if (Pd.new) Rd=#0
3218 //   if (!Pd.new) Rd=#1
3219 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
3220                                            u8ExtPred:$u8)))),
3221            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3222                                                  (u8ExtPred:$u8))),
3223                                 0, 1))>,
3224            Requires<[HasV4T]>;
3225
3226 // For the sequence
3227 //   zext( seteq (Rs, and(Rt, 255)))
3228 // Generate
3229 //   Pd=cmpb.eq(Rs, Rt)
3230 //   if (Pd.new) Rd=#1
3231 //   if (!Pd.new) Rd=#0
3232 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
3233                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
3234            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3235                                                       (i32 IntRegs:$Rt))),
3236                                 1, 0))>,
3237            Requires<[HasV4T]>;
3238
3239 // For the sequence
3240 //   zext( setne (Rs, and(Rt, 255)))
3241 // Generate
3242 //   Pd=cmpb.eq(Rs, Rt)
3243 //   if (Pd.new) Rd=#0
3244 //   if (!Pd.new) Rd=#1
3245 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
3246                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
3247            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3248                                                       (i32 IntRegs:$Rt))),
3249                                 0, 1))>,
3250            Requires<[HasV4T]>;
3251
3252 // For the sequence
3253 //   zext( setugt ( and(Rs, 255), u8))
3254 // Generate
3255 //   Pd=cmpb.gtu(Rs, #u8)
3256 //   if (Pd.new) Rd=#1
3257 //   if (!Pd.new) Rd=#0
3258 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
3259                                             u8ExtPred:$u8)))),
3260            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3261                                                   (u8ExtPred:$u8))),
3262                                 1, 0))>,
3263            Requires<[HasV4T]>;
3264
3265 // For the sequence
3266 //   zext( setugt ( and(Rs, 254), u8))
3267 // Generate
3268 //   Pd=cmpb.gtu(Rs, #u8)
3269 //   if (Pd.new) Rd=#1
3270 //   if (!Pd.new) Rd=#0
3271 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
3272                                             u8ExtPred:$u8)))),
3273            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3274                                                   (u8ExtPred:$u8))),
3275                                 1, 0))>,
3276            Requires<[HasV4T]>;
3277
3278 // For the sequence
3279 //   zext( setult ( Rs, Rt))
3280 // Generate
3281 //   Pd=cmp.ltu(Rs, Rt)
3282 //   if (Pd.new) Rd=#1
3283 //   if (!Pd.new) Rd=#0
3284 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3285 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3286            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3287                                               (i32 IntRegs:$Rs))),
3288                                 1, 0))>,
3289            Requires<[HasV4T]>;
3290
3291 // For the sequence
3292 //   zext( setlt ( Rs, Rt))
3293 // Generate
3294 //   Pd=cmp.lt(Rs, Rt)
3295 //   if (Pd.new) Rd=#1
3296 //   if (!Pd.new) Rd=#0
3297 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3298 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3299            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3300                                              (i32 IntRegs:$Rs))),
3301                                 1, 0))>,
3302            Requires<[HasV4T]>;
3303
3304 // For the sequence
3305 //   zext( setugt ( Rs, Rt))
3306 // Generate
3307 //   Pd=cmp.gtu(Rs, Rt)
3308 //   if (Pd.new) Rd=#1
3309 //   if (!Pd.new) Rd=#0
3310 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3311            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3312                                               (i32 IntRegs:$Rt))),
3313                                 1, 0))>,
3314            Requires<[HasV4T]>;
3315
3316 // This pattern interefers with coremark performance, not implementing at this
3317 // time.
3318 // For the sequence
3319 //   zext( setgt ( Rs, Rt))
3320 // Generate
3321 //   Pd=cmp.gt(Rs, Rt)
3322 //   if (Pd.new) Rd=#1
3323 //   if (!Pd.new) Rd=#0
3324
3325 // For the sequence
3326 //   zext( setuge ( Rs, Rt))
3327 // Generate
3328 //   Pd=cmp.ltu(Rs, Rt)
3329 //   if (Pd.new) Rd=#0
3330 //   if (!Pd.new) Rd=#1
3331 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3332 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3333            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3334                                               (i32 IntRegs:$Rs))),
3335                                 0, 1))>,
3336            Requires<[HasV4T]>;
3337
3338 // For the sequence
3339 //   zext( setge ( Rs, Rt))
3340 // Generate
3341 //   Pd=cmp.lt(Rs, Rt)
3342 //   if (Pd.new) Rd=#0
3343 //   if (!Pd.new) Rd=#1
3344 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3345 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3346            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3347                                              (i32 IntRegs:$Rs))),
3348                                 0, 1))>,
3349            Requires<[HasV4T]>;
3350
3351 // For the sequence
3352 //   zext( setule ( Rs, Rt))
3353 // Generate
3354 //   Pd=cmp.gtu(Rs, Rt)
3355 //   if (Pd.new) Rd=#0
3356 //   if (!Pd.new) Rd=#1
3357 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3358            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3359                                               (i32 IntRegs:$Rt))),
3360                                 0, 1))>,
3361            Requires<[HasV4T]>;
3362
3363 // For the sequence
3364 //   zext( setle ( Rs, Rt))
3365 // Generate
3366 //   Pd=cmp.gt(Rs, Rt)
3367 //   if (Pd.new) Rd=#0
3368 //   if (!Pd.new) Rd=#1
3369 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3370            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
3371                                              (i32 IntRegs:$Rt))),
3372                                 0, 1))>,
3373            Requires<[HasV4T]>;
3374
3375 // For the sequence
3376 //   zext( setult ( and(Rs, 255), u8))
3377 // Use the isdigit transformation below
3378
3379 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
3380 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
3381 // The isdigit transformation relies on two 'clever' aspects:
3382 // 1) The data type is unsigned which allows us to eliminate a zero test after
3383 //    biasing the expression by 48. We are depending on the representation of
3384 //    the unsigned types, and semantics.
3385 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
3386 //
3387 // For the C code:
3388 //   retval = ((c>='0') & (c<='9')) ? 1 : 0;
3389 // The code is transformed upstream of llvm into
3390 //   retval = (c-48) < 10 ? 1 : 0;
3391 let AddedComplexity = 139 in
3392 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
3393                                   u7StrictPosImmPred:$src2)))),
3394   (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
3395                                  (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
3396                    0, 1))>,
3397                    Requires<[HasV4T]>;
3398
3399 // Pd=cmpb.gtu(Rs,Rt)
3400 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
3401 InputType = "reg" in
3402 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
3403             (ins IntRegs:$src1, IntRegs:$src2),
3404             "$dst = cmpb.gtu($src1, $src2)",
3405             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3406                                              (and (i32 IntRegs:$src2), 255)))]>,
3407             Requires<[HasV4T]>, ImmRegRel;
3408
3409 // Following instruction is not being extended as it results into the incorrect
3410 // code for negative numbers.
3411
3412 // Signed half compare(.eq) ri.
3413 // Pd=cmph.eq(Rs,#s8)
3414 let isCompare = 1, validSubTargets = HasV4SubT in
3415 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
3416             (ins IntRegs:$src1, s8Imm:$src2),
3417             "$dst = cmph.eq($src1, #$src2)",
3418             [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
3419                                              s8ImmPred:$src2))]>,
3420             Requires<[HasV4T]>;
3421
3422 // Signed half compare(.eq) rr.
3423 // Case 1: xor + and, then compare:
3424 //   r0=xor(r0,r1)
3425 //   r0=and(r0,#0xffff)
3426 //   p0=cmp.eq(r0,#0)
3427 // Pd=cmph.eq(Rs,Rt)
3428 let isCompare = 1, validSubTargets = HasV4SubT in
3429 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
3430             (ins IntRegs:$src1, IntRegs:$src2),
3431             "$dst = cmph.eq($src1, $src2)",
3432             [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
3433                                                        (i32 IntRegs:$src2)),
3434                                                   65535), 0))]>,
3435             Requires<[HasV4T]>;
3436
3437 // Signed half compare(.eq) rr.
3438 // Case 2: shift left 16 bits then compare:
3439 //   r0=asl(r0,16)
3440 //   r1=asl(r1,16)
3441 //   p0=cmp.eq(r0,r1)
3442 // Pd=cmph.eq(Rs,Rt)
3443 let isCompare = 1, validSubTargets = HasV4SubT in
3444 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
3445             (ins IntRegs:$src1, IntRegs:$src2),
3446             "$dst = cmph.eq($src1, $src2)",
3447             [(set (i1 PredRegs:$dst),
3448                   (seteq (shl (i32 IntRegs:$src1), (i32 16)),
3449                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
3450             Requires<[HasV4T]>;
3451
3452 /* Incorrect Pattern -- immediate should be right shifted before being
3453 used in the cmph.gt instruction.
3454 // Signed half compare(.gt) ri.
3455 // Pd=cmph.gt(Rs,#s8)
3456
3457 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
3458 isCompare = 1, validSubTargets = HasV4SubT in
3459 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
3460             (ins IntRegs:$src1, s8Ext:$src2),
3461             "$dst = cmph.gt($src1, #$src2)",
3462             [(set (i1 PredRegs:$dst),
3463                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3464                          s8ExtPred:$src2))]>,
3465             Requires<[HasV4T]>;
3466 */
3467
3468 // Signed half compare(.gt) rr.
3469 // Pd=cmph.gt(Rs,Rt)
3470 let isCompare = 1, validSubTargets = HasV4SubT in
3471 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
3472             (ins IntRegs:$src1, IntRegs:$src2),
3473             "$dst = cmph.gt($src1, $src2)",
3474             [(set (i1 PredRegs:$dst),
3475                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3476                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
3477             Requires<[HasV4T]>;
3478
3479 // Unsigned half compare rr (.gtu).
3480 // Pd=cmph.gtu(Rs,Rt)
3481 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3482 InputType = "reg" in
3483 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
3484             (ins IntRegs:$src1, IntRegs:$src2),
3485             "$dst = cmph.gtu($src1, $src2)",
3486             [(set (i1 PredRegs:$dst),
3487                   (setugt (and (i32 IntRegs:$src1), 65535),
3488                           (and (i32 IntRegs:$src2), 65535)))]>,
3489             Requires<[HasV4T]>, ImmRegRel;
3490
3491 // Unsigned half compare ri (.gtu).
3492 // Pd=cmph.gtu(Rs,#u7)
3493 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3494 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3495 InputType = "imm" in
3496 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
3497             (ins IntRegs:$src1, u7Ext:$src2),
3498             "$dst = cmph.gtu($src1, #$src2)",
3499             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
3500                                               u7ExtPred:$src2))]>,
3501             Requires<[HasV4T]>, ImmRegRel;
3502
3503 let validSubTargets = HasV4SubT in
3504 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
3505     "$dst = !tstbit($src1, $src2)",
3506     [(set (i1 PredRegs:$dst),
3507           (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
3508     Requires<[HasV4T]>;
3509
3510 let validSubTargets = HasV4SubT in
3511 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
3512     "$dst = !tstbit($src1, $src2)",
3513     [(set (i1 PredRegs:$dst),
3514           (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
3515     Requires<[HasV4T]>;
3516
3517 //===----------------------------------------------------------------------===//
3518 // XTYPE/PRED -
3519 //===----------------------------------------------------------------------===//
3520
3521 //Deallocate frame and return.
3522 //    dealloc_return
3523 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
3524   Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
3525   def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
3526             "dealloc_return",
3527             []>,
3528             Requires<[HasV4T]>;
3529 }
3530
3531 // Restore registers and dealloc return function call.
3532 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3533   Defs = [R29, R30, R31, PC] in {
3534   def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
3535                                    (ins calltarget:$dst),
3536              "jump $dst // Restore_and_dealloc_return",
3537              []>,
3538              Requires<[HasV4T]>;
3539 }
3540
3541 // Restore registers and dealloc frame before a tail call.
3542 let isCall = 1, isBarrier = 1,
3543   Defs = [R29, R30, R31, PC] in {
3544   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
3545                                            (ins calltarget:$dst),
3546              "call $dst // Restore_and_dealloc_before_tailcall",
3547              []>,
3548              Requires<[HasV4T]>;
3549 }
3550
3551 // Save registers function call.
3552 let isCall = 1, isBarrier = 1,
3553   Uses = [R29, R31] in {
3554   def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
3555                                (ins calltarget:$dst),
3556              "call $dst // Save_calle_saved_registers",
3557              []>,
3558              Requires<[HasV4T]>;
3559 }
3560
3561 //    if (Ps) dealloc_return
3562 let isReturn = 1, isTerminator = 1,
3563     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3564     isPredicated = 1 in {
3565   def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
3566                            (ins PredRegs:$src1, i32imm:$amt1),
3567             "if ($src1) dealloc_return",
3568             []>,
3569             Requires<[HasV4T]>;
3570 }
3571
3572 //    if (!Ps) dealloc_return
3573 let isReturn = 1, isTerminator = 1,
3574     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3575     isPredicated = 1 in {
3576   def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3577                                                      i32imm:$amt1),
3578             "if (!$src1) dealloc_return",
3579             []>,
3580             Requires<[HasV4T]>;
3581 }
3582
3583 //    if (Ps.new) dealloc_return:nt
3584 let isReturn = 1, isTerminator = 1,
3585     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3586     isPredicated = 1 in {
3587   def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3588                                                      i32imm:$amt1),
3589             "if ($src1.new) dealloc_return:nt",
3590             []>,
3591             Requires<[HasV4T]>;
3592 }
3593
3594 //    if (!Ps.new) dealloc_return:nt
3595 let isReturn = 1, isTerminator = 1,
3596     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3597     isPredicated = 1 in {
3598   def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3599                                                         i32imm:$amt1),
3600             "if (!$src1.new) dealloc_return:nt",
3601             []>,
3602             Requires<[HasV4T]>;
3603 }
3604
3605 //    if (Ps.new) dealloc_return:t
3606 let isReturn = 1, isTerminator = 1,
3607     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3608     isPredicated = 1 in {
3609   def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3610                                                     i32imm:$amt1),
3611             "if ($src1.new) dealloc_return:t",
3612             []>,
3613             Requires<[HasV4T]>;
3614 }
3615
3616 //    if (!Ps.new) dealloc_return:nt
3617 let isReturn = 1, isTerminator = 1,
3618     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3619     isPredicated = 1 in {
3620   def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3621                                                        i32imm:$amt1),
3622             "if (!$src1.new) dealloc_return:t",
3623             []>,
3624             Requires<[HasV4T]>;
3625 }
3626
3627 // Load/Store with absolute addressing mode
3628 // memw(#u6)=Rt
3629
3630 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3631                            bit isPredNew> {
3632   let PNewValue = !if(isPredNew, "new", "") in
3633   def NAME#_V4 : STInst2<(outs),
3634             (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3635             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3636             ") ")#mnemonic#"(##$absaddr) = $src2",
3637             []>,
3638             Requires<[HasV4T]>;
3639 }
3640
3641 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3642   let PredSense = !if(PredNot, "false", "true") in {
3643     defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3644     // Predicate new
3645     defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3646   }
3647 }
3648
3649 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
3650 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3651   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3652     let opExtendable = 0, isPredicable = 1 in
3653     def NAME#_V4 : STInst2<(outs),
3654             (ins globaladdressExt:$absaddr, RC:$src),
3655             mnemonic#"(##$absaddr) = $src",
3656             []>,
3657             Requires<[HasV4T]>;
3658
3659     let opExtendable = 1, isPredicated = 1 in {
3660       defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
3661       defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
3662     }
3663   }
3664 }
3665
3666 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
3667                            bit isPredNew> {
3668   let PNewValue = !if(isPredNew, "new", "") in
3669   def NAME#_nv_V4 : NVInst_V4<(outs),
3670             (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3671             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3672             ") ")#mnemonic#"(##$absaddr) = $src2.new",
3673             []>,
3674             Requires<[HasV4T]>;
3675 }
3676
3677 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
3678   let PredSense = !if(PredNot, "false", "true") in {
3679     defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
3680     // Predicate new
3681     defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
3682   }
3683 }
3684
3685 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
3686 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
3687   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3688     let opExtendable = 0, isPredicable = 1 in
3689     def NAME#_nv_V4 : NVInst_V4<(outs),
3690             (ins globaladdressExt:$absaddr, RC:$src),
3691             mnemonic#"(##$absaddr) = $src.new",
3692             []>,
3693             Requires<[HasV4T]>;
3694
3695     let opExtendable = 1, isPredicated = 1 in {
3696       defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
3697       defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
3698     }
3699   }
3700 }
3701
3702 let addrMode = Absolute in {
3703     defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
3704                      ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
3705
3706     defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
3707                      ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
3708
3709     defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
3710                      ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
3711
3712   let isNVStorable = 0 in
3713     defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
3714 }
3715
3716 let Predicates = [HasV4T], AddedComplexity = 30 in {
3717 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
3718                         (HexagonCONST32 tglobaladdr:$absaddr)),
3719           (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3720
3721 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
3722                           (HexagonCONST32 tglobaladdr:$absaddr)),
3723           (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3724
3725 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
3726           (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3727
3728 def : Pat<(store (i64 DoubleRegs:$src1),
3729                  (HexagonCONST32 tglobaladdr:$absaddr)),
3730           (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
3731 }
3732
3733 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3734                            bit isPredNew> {
3735   let PNewValue = !if(isPredNew, "new", "") in
3736   def NAME : LDInst2<(outs RC:$dst),
3737             (ins PredRegs:$src1, globaladdressExt:$absaddr),
3738             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3739             ") ")#"$dst = "#mnemonic#"(##$absaddr)",
3740             []>,
3741             Requires<[HasV4T]>;
3742 }
3743
3744 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3745   let PredSense = !if(PredNot, "false", "true") in {
3746     defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3747     // Predicate new
3748     defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3749   }
3750 }
3751
3752 let isExtended = 1, neverHasSideEffects = 1 in
3753 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3754   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3755     let  opExtendable = 1, isPredicable = 1 in
3756     def NAME#_V4 : LDInst2<(outs RC:$dst),
3757             (ins globaladdressExt:$absaddr),
3758             "$dst = "#mnemonic#"(##$absaddr)",
3759             []>,
3760             Requires<[HasV4T]>;
3761
3762     let opExtendable = 2, isPredicated = 1 in {
3763       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3764       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3765     }
3766   }
3767 }
3768
3769 let addrMode = Absolute in {
3770     defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3771     defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
3772     defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3773     defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
3774     defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
3775     defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
3776 }
3777
3778 let Predicates = [HasV4T], AddedComplexity  = 30 in
3779 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3780           (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3781
3782 let Predicates = [HasV4T], AddedComplexity=30 in
3783 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3784           (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3785
3786 let Predicates = [HasV4T], AddedComplexity=30 in
3787 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3788           (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3789
3790 let Predicates = [HasV4T], AddedComplexity=30 in
3791 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3792           (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3793
3794 let Predicates = [HasV4T], AddedComplexity=30 in
3795 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3796           (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
3797
3798 // Transfer global address into a register
3799 let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
3800 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
3801            "$dst = ##$src1",
3802            [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3803            Requires<[HasV4T]>;
3804
3805 // Transfer a block address into a register
3806 def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
3807           (TFRI_V4 tblockaddress:$src1)>,
3808           Requires<[HasV4T]>;
3809
3810 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3811 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3812                            (ins PredRegs:$src1, globaladdress:$src2),
3813            "if($src1) $dst = ##$src2",
3814            []>,
3815            Requires<[HasV4T]>;
3816
3817 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3818 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3819                               (ins PredRegs:$src1, globaladdress:$src2),
3820            "if(!$src1) $dst = ##$src2",
3821            []>,
3822            Requires<[HasV4T]>;
3823
3824 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3825 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3826                              (ins PredRegs:$src1, globaladdress:$src2),
3827            "if($src1.new) $dst = ##$src2",
3828            []>,
3829            Requires<[HasV4T]>;
3830
3831 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3832 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3833                                 (ins PredRegs:$src1, globaladdress:$src2),
3834            "if(!$src1.new) $dst = ##$src2",
3835            []>,
3836            Requires<[HasV4T]>;
3837
3838 let AddedComplexity = 50, Predicates = [HasV4T] in
3839 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3840            (TFRI_V4 tglobaladdr:$src1)>;
3841
3842
3843 // Load - Indirect with long offset: These instructions take global address
3844 // as an operand
3845 let AddedComplexity = 10 in
3846 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3847             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3848             "$dst=memd($src1<<#$src2+##$offset)",
3849             [(set (i64 DoubleRegs:$dst),
3850                   (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3851                         (HexagonCONST32 tglobaladdr:$offset))))]>,
3852             Requires<[HasV4T]>;
3853
3854 let AddedComplexity = 10 in
3855 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3856   def _lo_V4 : LDInst<(outs IntRegs:$dst),
3857             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3858             !strconcat("$dst = ",
3859             !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3860             [(set IntRegs:$dst,
3861                   (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3862                           (HexagonCONST32 tglobaladdr:$offset)))))]>,
3863             Requires<[HasV4T]>;
3864 }
3865
3866 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3867 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3868 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3869 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3870 defm LDriw_ind : LD_indirect_lo<"memw", load>;
3871
3872 // Store - Indirect with long offset: These instructions take global address
3873 // as an operand
3874 let AddedComplexity = 10 in
3875 def STrid_ind_lo_V4 : STInst<(outs),
3876             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3877                  DoubleRegs:$src4),
3878             "memd($src1<<#$src2+#$src3) = $src4",
3879             [(store (i64 DoubleRegs:$src4),
3880                  (add (shl IntRegs:$src1, u2ImmPred:$src2),
3881                       (HexagonCONST32 tglobaladdr:$src3)))]>,
3882              Requires<[HasV4T]>;
3883
3884 let AddedComplexity = 10 in
3885 multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
3886   def _lo_V4 : STInst<(outs),
3887             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3888                  IntRegs:$src4),
3889             !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
3890             [(OpNode (i32 IntRegs:$src4),
3891                  (add (shl IntRegs:$src1, u2ImmPred:$src2),
3892                       (HexagonCONST32 tglobaladdr:$src3)))]>,
3893              Requires<[HasV4T]>;
3894 }
3895
3896 defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
3897 defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
3898 defm STriw_ind : ST_indirect_lo<"memw", store>;
3899
3900 // Store - absolute addressing mode: These instruction take constant
3901 // value as the extended operand.
3902 multiclass ST_absimm<string OpcStr> {
3903 let isExtended = 1, opExtendable = 0, isPredicable = 1,
3904 validSubTargets = HasV4SubT in
3905   def _abs_V4 : STInst2<(outs),
3906             (ins u0AlwaysExt:$src1, IntRegs:$src2),
3907             !strconcat(OpcStr, "(##$src1) = $src2"),
3908             []>,
3909             Requires<[HasV4T]>;
3910
3911 let isExtended = 1, opExtendable = 1, isPredicated = 1,
3912 validSubTargets = HasV4SubT in {
3913   def _abs_cPt_V4 : STInst2<(outs),
3914             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3915             !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3916             []>,
3917             Requires<[HasV4T]>;
3918
3919   def _abs_cNotPt_V4 : STInst2<(outs),
3920             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3921             !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3922             []>,
3923             Requires<[HasV4T]>;
3924
3925   def _abs_cdnPt_V4 : STInst2<(outs),
3926             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3927             !strconcat("if ($src1.new)",
3928             !strconcat(OpcStr, "(##$src2) = $src3")),
3929             []>,
3930             Requires<[HasV4T]>;
3931
3932   def _abs_cdnNotPt_V4 : STInst2<(outs),
3933             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3934             !strconcat("if (!$src1.new)",
3935             !strconcat(OpcStr, "(##$src2) = $src3")),
3936             []>,
3937             Requires<[HasV4T]>;
3938 }
3939
3940 let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
3941 validSubTargets = HasV4SubT in
3942   def _abs_nv_V4 : NVInst_V4<(outs),
3943             (ins u0AlwaysExt:$src1, IntRegs:$src2),
3944             !strconcat(OpcStr, "(##$src1) = $src2.new"),
3945             []>,
3946             Requires<[HasV4T]>;
3947
3948 let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
3949 isNVStore = 1, validSubTargets = HasV4SubT in {
3950   def _abs_cPt_nv_V4 : NVInst_V4<(outs),
3951             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3952             !strconcat("if ($src1)",
3953             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3954             []>,
3955             Requires<[HasV4T]>;
3956
3957   def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
3958             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3959             !strconcat("if (!$src1)",
3960             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3961             []>,
3962             Requires<[HasV4T]>;
3963
3964   def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
3965             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3966             !strconcat("if ($src1.new)",
3967             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3968             []>,
3969             Requires<[HasV4T]>;
3970
3971   def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
3972             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3973             !strconcat("if (!$src1.new)",
3974             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3975             []>,
3976             Requires<[HasV4T]>;
3977 }
3978 }
3979
3980 defm STrib_imm : ST_absimm<"memb">;
3981 defm STrih_imm : ST_absimm<"memh">;
3982 defm STriw_imm : ST_absimm<"memw">;
3983
3984 let Predicates = [HasV4T], AddedComplexity  = 30 in {
3985 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3986           (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3987
3988 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3989           (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3990
3991 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3992           (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3993 }
3994
3995 // Load - absolute addressing mode: These instruction take constant
3996 // value as the extended operand
3997
3998 multiclass LD_absimm<string OpcStr> {
3999 let isExtended = 1, opExtendable = 1, isPredicable = 1,
4000 validSubTargets = HasV4SubT in
4001   def _abs_V4 : LDInst2<(outs IntRegs:$dst),
4002             (ins u0AlwaysExt:$src),
4003             !strconcat("$dst = ",
4004             !strconcat(OpcStr, "(##$src)")),
4005             []>,
4006             Requires<[HasV4T]>;
4007
4008 let isExtended = 1, opExtendable = 2, isPredicated = 1,
4009 validSubTargets = HasV4SubT in {
4010   def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
4011             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4012             !strconcat("if ($src1) $dst = ",
4013             !strconcat(OpcStr, "(##$src2)")),
4014             []>,
4015             Requires<[HasV4T]>;
4016
4017   def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4018             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4019             !strconcat("if (!$src1) $dst = ",
4020             !strconcat(OpcStr, "(##$src2)")),
4021             []>,
4022             Requires<[HasV4T]>;
4023
4024   def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
4025             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4026             !strconcat("if ($src1.new) $dst = ",
4027             !strconcat(OpcStr, "(##$src2)")),
4028             []>,
4029             Requires<[HasV4T]>;
4030
4031   def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4032             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4033             !strconcat("if (!$src1.new) $dst = ",
4034             !strconcat(OpcStr, "(##$src2)")),
4035             []>,
4036             Requires<[HasV4T]>;
4037 }
4038 }
4039
4040 defm LDrib_imm  : LD_absimm<"memb">;
4041 defm LDriub_imm : LD_absimm<"memub">;
4042 defm LDrih_imm  : LD_absimm<"memh">;
4043 defm LDriuh_imm : LD_absimm<"memuh">;
4044 defm LDriw_imm  : LD_absimm<"memw">;
4045
4046 let Predicates = [HasV4T], AddedComplexity  = 30 in {
4047 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
4048           (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
4049
4050 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
4051           (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
4052
4053 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
4054           (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
4055
4056 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
4057           (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
4058
4059 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
4060           (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
4061 }
4062
4063 // Indexed store double word - global address.
4064 // memw(Rs+#u6:2)=#S8
4065 let AddedComplexity = 10 in
4066 def STriw_offset_ext_V4 : STInst<(outs),
4067             (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
4068             "memw($src1+#$src2) = ##$src3",
4069             [(store (HexagonCONST32 tglobaladdr:$src3),
4070                     (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
4071             Requires<[HasV4T]>;
4072
4073
4074 // Indexed store double word - global address.
4075 // memw(Rs+#u6:2)=#S8
4076 let AddedComplexity = 10 in
4077 def STrih_offset_ext_V4 : STInst<(outs),
4078             (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
4079             "memh($src1+#$src2) = ##$src3",
4080             [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
4081                     (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
4082             Requires<[HasV4T]>;
4083 // Map from store(globaladdress + x) -> memd(#foo + x)
4084 let AddedComplexity = 100 in
4085 def : Pat<(store (i64 DoubleRegs:$src1),
4086                  FoldGlobalAddrGP:$addr),
4087           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4088           Requires<[HasV4T]>;
4089
4090 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
4091                            (i64 DoubleRegs:$src1)),
4092           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4093           Requires<[HasV4T]>;
4094
4095 // Map from store(globaladdress + x) -> memb(#foo + x)
4096 let AddedComplexity = 100 in
4097 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4098           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4099             Requires<[HasV4T]>;
4100
4101 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4102           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4103             Requires<[HasV4T]>;
4104
4105 // Map from store(globaladdress + x) -> memh(#foo + x)
4106 let AddedComplexity = 100 in
4107 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4108           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4109             Requires<[HasV4T]>;
4110
4111 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4112           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4113             Requires<[HasV4T]>;
4114
4115 // Map from store(globaladdress + x) -> memw(#foo + x)
4116 let AddedComplexity = 100 in
4117 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4118           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4119            Requires<[HasV4T]>;
4120
4121 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4122           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4123             Requires<[HasV4T]>;
4124
4125 // Map from load(globaladdress + x) -> memd(#foo + x)
4126 let AddedComplexity = 100 in
4127 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
4128           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4129            Requires<[HasV4T]>;
4130
4131 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
4132           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4133            Requires<[HasV4T]>;
4134
4135 // Map from load(globaladdress + x) -> memb(#foo + x)
4136 let AddedComplexity = 100 in
4137 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
4138           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4139            Requires<[HasV4T]>;
4140
4141 // Map from load(globaladdress + x) -> memb(#foo + x)
4142 let AddedComplexity = 100 in
4143 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
4144           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4145            Requires<[HasV4T]>;
4146
4147 //let AddedComplexity = 100 in
4148 let AddedComplexity = 100 in
4149 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
4150           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4151            Requires<[HasV4T]>;
4152
4153 // Map from load(globaladdress + x) -> memh(#foo + x)
4154 let AddedComplexity = 100 in
4155 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
4156           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4157            Requires<[HasV4T]>;
4158
4159 // Map from load(globaladdress + x) -> memuh(#foo + x)
4160 let AddedComplexity = 100 in
4161 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
4162           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4163            Requires<[HasV4T]>;
4164
4165 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
4166           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4167            Requires<[HasV4T]>;
4168
4169 // Map from load(globaladdress + x) -> memub(#foo + x)
4170 let AddedComplexity = 100 in
4171 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
4172           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4173            Requires<[HasV4T]>;
4174
4175 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
4176           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4177            Requires<[HasV4T]>;
4178
4179 // Map from load(globaladdress + x) -> memw(#foo + x)
4180 let AddedComplexity = 100 in
4181 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
4182           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4183            Requires<[HasV4T]>;
4184
4185 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
4186           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4187            Requires<[HasV4T]>;
4188