Hexagon: Use multiclass for absolute addressing mode loads.
[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 i16->i64
944 def:  Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
945       (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
946       Requires<[HasV4T]>;
947
948 let AddedComplexity = 20 in
949 def:  Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
950                                   s11_1ExtPred:$offset))),
951       (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
952                                   s11_1ExtPred:$offset)))>,
953       Requires<[HasV4T]>;
954
955 // anyext i16->i64
956 def:  Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
957       (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
958       Requires<[HasV4T]>;
959
960 let AddedComplexity = 20 in
961 def:  Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
962                                   s11_1ExtPred:$offset))),
963       (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
964                                   s11_1ExtPred:$offset)))>,
965       Requires<[HasV4T]>;
966
967 // zext i32->i64
968 def:  Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
969       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
970       Requires<[HasV4T]>;
971
972 let AddedComplexity = 100 in
973 def:  Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
974       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
975                                   s11_2ExtPred:$offset)))>,
976       Requires<[HasV4T]>;
977
978 // anyext i32->i64
979 def:  Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
980       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
981       Requires<[HasV4T]>;
982
983 let AddedComplexity = 100 in
984 def:  Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
985       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
986                                   s11_2ExtPred:$offset)))>,
987       Requires<[HasV4T]>;
988
989
990
991 //===----------------------------------------------------------------------===//
992 // LD -
993 //===----------------------------------------------------------------------===//
994
995 //===----------------------------------------------------------------------===//
996 // ST +
997 //===----------------------------------------------------------------------===//
998 ///
999 /// Assumptions::: ****** DO NOT IGNORE ********
1000 /// 1. Make sure that in post increment store, the zero'th operand is always the
1001 ///    post increment operand.
1002 /// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
1003 ///    last operand.
1004 ///
1005
1006 // memd(Re=#U)=Rtt
1007 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1008 def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1009             (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
1010             "memd($dst1=##$src2) = $src1",
1011             []>,
1012             Requires<[HasV4T]>;
1013
1014 // memb(Re=#U)=Rs
1015 def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1016             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1017             "memb($dst1=##$src2) = $src1",
1018             []>,
1019             Requires<[HasV4T]>;
1020
1021 // memh(Re=#U)=Rs
1022 def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1023             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1024             "memh($dst1=##$src2) = $src1",
1025             []>,
1026             Requires<[HasV4T]>;
1027
1028 // memw(Re=#U)=Rs
1029 def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1030             (ins IntRegs:$src1, u0AlwaysExt:$src2),
1031             "memw($dst1=##$src2) = $src1",
1032             []>,
1033             Requires<[HasV4T]>;
1034 }
1035
1036 // memd(Re=#U)=Rtt
1037 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1038 def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1039             (ins DoubleRegs:$src1, globaladdressExt:$src2),
1040             "memd($dst1=##$src2) = $src1",
1041             []>,
1042             Requires<[HasV4T]>;
1043
1044 // memb(Re=#U)=Rs
1045 def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1046             (ins IntRegs:$src1, globaladdressExt:$src2),
1047             "memb($dst1=##$src2) = $src1",
1048             []>,
1049             Requires<[HasV4T]>;
1050
1051 // memh(Re=#U)=Rs
1052 def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1053             (ins IntRegs:$src1, globaladdressExt:$src2),
1054             "memh($dst1=##$src2) = $src1",
1055             []>,
1056             Requires<[HasV4T]>;
1057
1058 // memw(Re=#U)=Rs
1059 def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1060             (ins IntRegs:$src1, globaladdressExt:$src2),
1061             "memw($dst1=##$src2) = $src1",
1062             []>,
1063             Requires<[HasV4T]>;
1064 }
1065
1066 // multiclass for store instructions with base + register offset addressing
1067 // mode
1068 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1069                              bit isPredNew> {
1070   let PNewValue = !if(isPredNew, "new", "") in
1071   def NAME : STInst2<(outs),
1072             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1073                  RC:$src5),
1074             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1075             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
1076             []>,
1077             Requires<[HasV4T]>;
1078 }
1079
1080 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1081   let PredSense = !if(PredNot, "false", "true") in {
1082     defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
1083     // Predicate new
1084     defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
1085   }
1086 }
1087
1088 let isNVStorable = 1 in
1089 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
1090   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1091     let isPredicable = 1 in
1092     def NAME#_V4 : STInst2<(outs),
1093             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1094             mnemonic#"($src1+$src2<<#$src3) = $src4",
1095             []>,
1096             Requires<[HasV4T]>;
1097
1098     let isPredicated = 1 in {
1099       defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
1100       defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
1101     }
1102   }
1103 }
1104
1105 // multiclass for new-value store instructions with base + register offset
1106 // addressing mode.
1107 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1108                              bit isPredNew> {
1109   let PNewValue = !if(isPredNew, "new", "") in
1110   def NAME#_nv_V4 : NVInst_V4<(outs),
1111             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1112                  RC:$src5),
1113             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1114             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
1115             []>,
1116             Requires<[HasV4T]>;
1117 }
1118
1119 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1120   let PredSense = !if(PredNot, "false", "true") in {
1121     defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
1122     // Predicate new
1123     defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
1124   }
1125 }
1126
1127 let mayStore = 1, isNVStore = 1 in
1128 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
1129   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1130     let isPredicable = 1 in
1131     def NAME#_nv_V4 : NVInst_V4<(outs),
1132             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1133             mnemonic#"($src1+$src2<<#$src3) = $src4.new",
1134             []>,
1135             Requires<[HasV4T]>;
1136
1137     let isPredicated = 1 in {
1138       defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
1139       defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
1140     }
1141   }
1142 }
1143
1144 let addrMode = BaseRegOffset, neverHasSideEffects = 1,
1145 validSubTargets = HasV4SubT in {
1146   defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
1147                           ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
1148
1149   defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
1150                           ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
1151
1152   defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
1153                           ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
1154
1155   let isNVStorable = 0 in
1156   defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
1157 }
1158
1159 let Predicates = [HasV4T], AddedComplexity = 10 in {
1160 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
1161                        (add IntRegs:$src1, (shl IntRegs:$src2,
1162                                                 u2ImmPred:$src3))),
1163           (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1164                                 u2ImmPred:$src3, IntRegs:$src4)>;
1165
1166 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
1167                         (add IntRegs:$src1, (shl IntRegs:$src2,
1168                                                  u2ImmPred:$src3))),
1169           (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1170                                 u2ImmPred:$src3, IntRegs:$src4)>;
1171
1172 def : Pat<(store (i32 IntRegs:$src4),
1173                  (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1174           (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1175                                 u2ImmPred:$src3, IntRegs:$src4)>;
1176
1177 def : Pat<(store (i64 DoubleRegs:$src4),
1178                 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1179           (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1180                                 u2ImmPred:$src3, DoubleRegs:$src4)>;
1181 }
1182
1183 // memd(Ru<<#u2+#U6)=Rtt
1184 let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
1185 validSubTargets = HasV4SubT in
1186 def STrid_shl_V4 : STInst<(outs),
1187             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
1188             "memd($src1<<#$src2+#$src3) = $src4",
1189             [(store (i64 DoubleRegs:$src4),
1190                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1191                          u0AlwaysExtPred:$src3))]>,
1192             Requires<[HasV4T]>;
1193
1194 // memd(Rx++#s4:3)=Rtt
1195 // memd(Rx++#s4:3:circ(Mu))=Rtt
1196 // memd(Rx++I:circ(Mu))=Rtt
1197 // memd(Rx++Mu)=Rtt
1198 // memd(Rx++Mu:brev)=Rtt
1199 // memd(gp+#u16:3)=Rtt
1200
1201 // Store doubleword conditionally.
1202 // if ([!]Pv[.new]) memd(#u6)=Rtt
1203 // TODO: needs to be implemented.
1204
1205 //===----------------------------------------------------------------------===//
1206 // multiclass for store instructions with base + immediate offset
1207 // addressing mode and immediate stored value.
1208 // mem[bhw](Rx++#s4:3)=#s8
1209 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
1210 //===----------------------------------------------------------------------===//
1211 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
1212                         bit isPredNew> {
1213   let PNewValue = !if(isPredNew, "new", "") in
1214   def NAME : STInst2<(outs),
1215             (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
1216             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1217             ") ")#mnemonic#"($src2+#$src3) = #$src4",
1218             []>,
1219             Requires<[HasV4T]>;
1220 }
1221
1222 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
1223   let PredSense = !if(PredNot, "false", "true") in {
1224     defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
1225     // Predicate new
1226     defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
1227   }
1228 }
1229
1230 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
1231 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
1232   let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
1233     let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
1234     def NAME#_V4 : STInst2<(outs),
1235             (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
1236             mnemonic#"($src1+#$src2) = #$src3",
1237             []>,
1238             Requires<[HasV4T]>;
1239
1240     let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
1241       defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
1242       defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
1243     }
1244   }
1245 }
1246
1247 let addrMode = BaseImmOffset, InputType = "imm",
1248     validSubTargets = HasV4SubT in {
1249   defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
1250   defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
1251   defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
1252 }
1253
1254 let Predicates = [HasV4T], AddedComplexity = 10 in {
1255 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
1256             (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
1257
1258 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
1259                                               u6_1ImmPred:$src2)),
1260             (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
1261
1262 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
1263             (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
1264 }
1265
1266 let AddedComplexity = 6 in
1267 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1268            (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1269            Requires<[HasV4T]>;
1270
1271 // memb(Ru<<#u2+#U6)=Rt
1272 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1273 validSubTargets = HasV4SubT in
1274 def STrib_shl_V4 : STInst<(outs),
1275             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1276             "memb($src1<<#$src2+#$src3) = $src4",
1277             [(truncstorei8 (i32 IntRegs:$src4),
1278                            (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1279                                 u0AlwaysExtPred:$src3))]>,
1280             Requires<[HasV4T]>;
1281
1282 // memb(Rx++#s4:0:circ(Mu))=Rt
1283 // memb(Rx++I:circ(Mu))=Rt
1284 // memb(Rx++Mu)=Rt
1285 // memb(Rx++Mu:brev)=Rt
1286 // memb(gp+#u16:0)=Rt
1287
1288
1289 // Store halfword.
1290 // TODO: needs to be implemented
1291 // memh(Re=#U6)=Rt.H
1292 // memh(Rs+#s11:1)=Rt.H
1293 let AddedComplexity = 6 in
1294 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1295            (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1296            Requires<[HasV4T]>;
1297
1298 // memh(Rs+Ru<<#u2)=Rt.H
1299 // TODO: needs to be implemented.
1300
1301 // memh(Ru<<#u2+#U6)=Rt.H
1302 // memh(Ru<<#u2+#U6)=Rt
1303 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1304 validSubTargets = HasV4SubT in
1305 def STrih_shl_V4 : STInst<(outs),
1306             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1307             "memh($src1<<#$src2+#$src3) = $src4",
1308             [(truncstorei16 (i32 IntRegs:$src4),
1309                             (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1310                                  u0AlwaysExtPred:$src3))]>,
1311             Requires<[HasV4T]>;
1312
1313 // memh(Rx++#s4:1:circ(Mu))=Rt.H
1314 // memh(Rx++#s4:1:circ(Mu))=Rt
1315 // memh(Rx++I:circ(Mu))=Rt.H
1316 // memh(Rx++I:circ(Mu))=Rt
1317 // memh(Rx++Mu)=Rt.H
1318 // memh(Rx++Mu)=Rt
1319 // memh(Rx++Mu:brev)=Rt.H
1320 // memh(Rx++Mu:brev)=Rt
1321 // memh(gp+#u16:1)=Rt
1322 // if ([!]Pv[.new]) memh(#u6)=Rt.H
1323 // if ([!]Pv[.new]) memh(#u6)=Rt
1324
1325
1326 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
1327 // TODO: needs to be implemented.
1328
1329 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
1330 // TODO: Needs to be implemented.
1331
1332 // Store word.
1333 // memw(Re=#U6)=Rt
1334 // TODO: Needs to be implemented.
1335
1336 // Store predicate:
1337 let neverHasSideEffects = 1 in
1338 def STriw_pred_V4 : STInst2<(outs),
1339             (ins MEMri:$addr, PredRegs:$src1),
1340             "Error; should not emit",
1341             []>,
1342             Requires<[HasV4T]>;
1343
1344 let AddedComplexity = 6 in
1345 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
1346            (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1347            Requires<[HasV4T]>;
1348
1349 // memw(Ru<<#u2+#U6)=Rt
1350 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1351 validSubTargets = HasV4SubT in
1352 def STriw_shl_V4 : STInst<(outs),
1353             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1354             "memw($src1<<#$src2+#$src3) = $src4",
1355             [(store (i32 IntRegs:$src4),
1356                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1357                               u0AlwaysExtPred:$src3))]>,
1358             Requires<[HasV4T]>;
1359
1360 // memw(Rx++#s4:2)=Rt
1361 // memw(Rx++#s4:2:circ(Mu))=Rt
1362 // memw(Rx++I:circ(Mu))=Rt
1363 // memw(Rx++Mu)=Rt
1364 // memw(Rx++Mu:brev)=Rt
1365 // memw(gp+#u16:2)=Rt
1366
1367
1368 // memd(#global)=Rtt
1369 let isPredicable = 1, neverHasSideEffects = 1 in
1370 def STd_GP_V4 : STInst2<(outs),
1371             (ins globaladdress:$global, DoubleRegs:$src),
1372             "memd(#$global) = $src",
1373             []>,
1374             Requires<[HasV4T]>;
1375
1376 // if (Pv) memd(##global) = Rtt
1377 let neverHasSideEffects = 1, isPredicated = 1 in
1378 def STd_GP_cPt_V4 : STInst2<(outs),
1379             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1380             "if ($src1) memd(##$global) = $src2",
1381             []>,
1382             Requires<[HasV4T]>;
1383
1384 // if (!Pv) memd(##global) = Rtt
1385 let neverHasSideEffects = 1, isPredicated = 1 in
1386 def STd_GP_cNotPt_V4 : STInst2<(outs),
1387             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1388             "if (!$src1) memd(##$global) = $src2",
1389             []>,
1390               Requires<[HasV4T]>;
1391
1392 // if (Pv) memd(##global) = Rtt
1393 let neverHasSideEffects = 1, isPredicated = 1 in
1394 def STd_GP_cdnPt_V4 : STInst2<(outs),
1395             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1396             "if ($src1.new) memd(##$global) = $src2",
1397             []>,
1398               Requires<[HasV4T]>;
1399
1400 // if (!Pv) memd(##global) = Rtt
1401 let neverHasSideEffects = 1, isPredicated = 1 in
1402 def STd_GP_cdnNotPt_V4 : STInst2<(outs),
1403             (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1404             "if (!$src1.new) memd(##$global) = $src2",
1405             []>,
1406             Requires<[HasV4T]>;
1407
1408 // memb(#global)=Rt
1409 let isPredicable = 1, neverHasSideEffects = 1 in
1410 def STb_GP_V4 : STInst2<(outs),
1411             (ins globaladdress:$global, IntRegs:$src),
1412             "memb(#$global) = $src",
1413             []>,
1414             Requires<[HasV4T]>;
1415
1416 // if (Pv) memb(##global) = Rt
1417 let neverHasSideEffects = 1, isPredicated = 1 in
1418 def STb_GP_cPt_V4 : STInst2<(outs),
1419             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1420             "if ($src1) memb(##$global) = $src2",
1421               []>,
1422               Requires<[HasV4T]>;
1423
1424 // if (!Pv) memb(##global) = Rt
1425 let neverHasSideEffects = 1, isPredicated = 1 in
1426 def STb_GP_cNotPt_V4 : STInst2<(outs),
1427             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1428             "if (!$src1) memb(##$global) = $src2",
1429               []>,
1430               Requires<[HasV4T]>;
1431
1432 // if (Pv) memb(##global) = Rt
1433 let neverHasSideEffects = 1, isPredicated = 1 in
1434 def STb_GP_cdnPt_V4 : STInst2<(outs),
1435             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1436             "if ($src1.new) memb(##$global) = $src2",
1437               []>,
1438               Requires<[HasV4T]>;
1439
1440 // if (!Pv) memb(##global) = Rt
1441 let neverHasSideEffects = 1, isPredicated = 1 in
1442 def STb_GP_cdnNotPt_V4 : STInst2<(outs),
1443             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1444             "if (!$src1.new) memb(##$global) = $src2",
1445               []>,
1446               Requires<[HasV4T]>;
1447
1448 // memh(#global)=Rt
1449 let isPredicable = 1, neverHasSideEffects = 1 in
1450 def STh_GP_V4 : STInst2<(outs),
1451             (ins globaladdress:$global, IntRegs:$src),
1452             "memh(#$global) = $src",
1453             []>,
1454             Requires<[HasV4T]>;
1455
1456 // if (Pv) memh(##global) = Rt
1457 let neverHasSideEffects = 1, isPredicated = 1 in
1458 def STh_GP_cPt_V4 : STInst2<(outs),
1459             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1460             "if ($src1) memh(##$global) = $src2",
1461               []>,
1462               Requires<[HasV4T]>;
1463
1464 // if (!Pv) memh(##global) = Rt
1465 let neverHasSideEffects = 1, isPredicated = 1 in
1466 def STh_GP_cNotPt_V4 : STInst2<(outs),
1467             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1468             "if (!$src1) memh(##$global) = $src2",
1469               []>,
1470               Requires<[HasV4T]>;
1471
1472 // if (Pv) memh(##global) = Rt
1473 let neverHasSideEffects = 1, isPredicated = 1 in
1474 def STh_GP_cdnPt_V4 : STInst2<(outs),
1475             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1476             "if ($src1.new) memh(##$global) = $src2",
1477               []>,
1478               Requires<[HasV4T]>;
1479
1480 // if (!Pv) memh(##global) = Rt
1481 let neverHasSideEffects = 1, isPredicated = 1 in
1482 def STh_GP_cdnNotPt_V4 : STInst2<(outs),
1483             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1484             "if (!$src1.new) memh(##$global) = $src2",
1485               []>,
1486               Requires<[HasV4T]>;
1487
1488 // memw(#global)=Rt
1489 let isPredicable = 1, neverHasSideEffects = 1 in
1490 def STw_GP_V4 : STInst2<(outs),
1491             (ins globaladdress:$global, IntRegs:$src),
1492             "memw(#$global) = $src",
1493               []>,
1494               Requires<[HasV4T]>;
1495
1496 // if (Pv) memw(##global) = Rt
1497 let neverHasSideEffects = 1, isPredicated = 1 in
1498 def STw_GP_cPt_V4 : STInst2<(outs),
1499             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1500             "if ($src1) memw(##$global) = $src2",
1501               []>,
1502               Requires<[HasV4T]>;
1503
1504 // if (!Pv) memw(##global) = Rt
1505 let neverHasSideEffects = 1, isPredicated = 1 in
1506 def STw_GP_cNotPt_V4 : STInst2<(outs),
1507             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1508             "if (!$src1) memw(##$global) = $src2",
1509               []>,
1510               Requires<[HasV4T]>;
1511
1512 // if (Pv) memw(##global) = Rt
1513 let neverHasSideEffects = 1, isPredicated = 1 in
1514 def STw_GP_cdnPt_V4 : STInst2<(outs),
1515             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1516             "if ($src1.new) memw(##$global) = $src2",
1517               []>,
1518               Requires<[HasV4T]>;
1519
1520 // if (!Pv) memw(##global) = Rt
1521 let neverHasSideEffects = 1, isPredicated = 1 in
1522 def STw_GP_cdnNotPt_V4 : STInst2<(outs),
1523             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1524             "if (!$src1.new) memw(##$global) = $src2",
1525             []>,
1526               Requires<[HasV4T]>;
1527
1528 // 64 bit atomic store
1529 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
1530                             (i64 DoubleRegs:$src1)),
1531            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1532            Requires<[HasV4T]>;
1533
1534 // Map from store(globaladdress) -> memd(#foo)
1535 let AddedComplexity = 100 in
1536 def : Pat <(store (i64 DoubleRegs:$src1),
1537                   (HexagonCONST32_GP tglobaladdr:$global)),
1538            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1539            Requires<[HasV4T]>;
1540
1541 // 8 bit atomic store
1542 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
1543                             (i32 IntRegs:$src1)),
1544             (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1545               Requires<[HasV4T]>;
1546
1547 // Map from store(globaladdress) -> memb(#foo)
1548 let AddedComplexity = 100 in
1549 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
1550           (HexagonCONST32_GP tglobaladdr:$global)),
1551           (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1552           Requires<[HasV4T]>;
1553
1554 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
1555 //       to "r0 = 1; memw(#foo) = r0"
1556 let AddedComplexity = 100 in
1557 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
1558           (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
1559           Requires<[HasV4T]>;
1560
1561 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
1562                            (i32 IntRegs:$src1)),
1563           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1564           Requires<[HasV4T]>;
1565
1566 // Map from store(globaladdress) -> memh(#foo)
1567 let AddedComplexity = 100 in
1568 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
1569                          (HexagonCONST32_GP tglobaladdr:$global)),
1570           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1571           Requires<[HasV4T]>;
1572
1573 // 32 bit atomic store
1574 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
1575                            (i32 IntRegs:$src1)),
1576           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1577           Requires<[HasV4T]>;
1578
1579 // Map from store(globaladdress) -> memw(#foo)
1580 let AddedComplexity = 100 in
1581 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
1582           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1583           Requires<[HasV4T]>;
1584
1585 //===----------------------------------------------------------------------===
1586 // ST -
1587 //===----------------------------------------------------------------------===
1588
1589
1590 //===----------------------------------------------------------------------===//
1591 // NV/ST +
1592 //===----------------------------------------------------------------------===//
1593
1594 // multiclass for new-value store instructions with base + immediate offset.
1595 //
1596 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
1597                             Operand predImmOp, bit isNot, bit isPredNew> {
1598   let PNewValue = !if(isPredNew, "new", "") in
1599   def NAME#_nv_V4 : NVInst_V4<(outs),
1600             (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1601             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1602             ") ")#mnemonic#"($src2+#$src3) = $src4.new",
1603             []>,
1604             Requires<[HasV4T]>;
1605 }
1606
1607 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
1608                            bit PredNot> {
1609   let PredSense = !if(PredNot, "false", "true") in {
1610     defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
1611     // Predicate new
1612     defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
1613   }
1614 }
1615
1616 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
1617 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
1618                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1619                    bits<5> PredImmBits> {
1620
1621   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1622     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1623     isPredicable = 1 in
1624     def NAME#_nv_V4 : NVInst_V4<(outs),
1625             (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1626             mnemonic#"($src1+#$src2) = $src3.new",
1627             []>,
1628             Requires<[HasV4T]>;
1629
1630     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1631     isPredicated = 1 in {
1632       defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
1633       defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
1634     }
1635   }
1636 }
1637
1638 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
1639   defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
1640                                  u6_0Ext, 11, 6>, AddrModeRel;
1641   defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
1642                                  u6_1Ext, 12, 7>, AddrModeRel;
1643   defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
1644                                  u6_2Ext, 13, 8>, AddrModeRel;
1645 }
1646
1647 // multiclass for new-value store instructions with base + immediate offset.
1648 // and MEMri operand.
1649 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1650                           bit isPredNew> {
1651   let PNewValue = !if(isPredNew, "new", "") in
1652   def NAME#_nv_V4 : NVInst_V4<(outs),
1653             (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1654             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1655             ") ")#mnemonic#"($addr) = $src2.new",
1656             []>,
1657             Requires<[HasV4T]>;
1658 }
1659
1660 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1661   let PredSense = !if(PredNot, "false", "true") in {
1662     defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
1663
1664     // Predicate new
1665     defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
1666   }
1667 }
1668
1669 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
1670 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
1671                     bits<5> ImmBits, bits<5> PredImmBits> {
1672
1673   let CextOpcode = CextOp, BaseOpcode = CextOp in {
1674     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1675          isPredicable = 1 in
1676     def NAME#_nv_V4 : NVInst_V4<(outs),
1677             (ins MEMri:$addr, RC:$src),
1678             mnemonic#"($addr) = $src.new",
1679             []>,
1680             Requires<[HasV4T]>;
1681
1682     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1683         neverHasSideEffects = 1, isPredicated = 1 in {
1684       defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
1685       defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
1686     }
1687   }
1688 }
1689
1690 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1691 mayStore = 1 in {
1692   defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1693   defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1694   defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1695 }
1696
1697 // memb(Ru<<#u2+#U6)=Nt.new
1698 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1699 isNVStore = 1, validSubTargets = HasV4SubT in
1700 def STrib_shl_nv_V4 : NVInst_V4<(outs),
1701             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1702             "memb($src1<<#$src2+#$src3) = $src4.new",
1703             []>,
1704             Requires<[HasV4T]>;
1705
1706 //===----------------------------------------------------------------------===//
1707 // Post increment store
1708 // mem[bhwd](Rx++#s4:[0123])=Nt.new
1709 //===----------------------------------------------------------------------===//
1710
1711 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
1712                             bit isNot, bit isPredNew> {
1713   let PNewValue = !if(isPredNew, "new", "") in
1714   def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1715             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1716             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1717             ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1718             [],
1719             "$src2 = $dst">,
1720             Requires<[HasV4T]>;
1721 }
1722
1723 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
1724                            Operand ImmOp, bit PredNot> {
1725   let PredSense = !if(PredNot, "false", "true") in {
1726     defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
1727     // Predicate new
1728     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1729     defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
1730   }
1731 }
1732
1733 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
1734 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
1735                       Operand ImmOp> {
1736
1737   let BaseOpcode = "POST_"#BaseOp in {
1738     let isPredicable = 1 in
1739     def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1740                 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1741                 mnemonic#"($src1++#$offset) = $src2.new",
1742                 [],
1743                 "$src1 = $dst">,
1744                 Requires<[HasV4T]>;
1745
1746     let isPredicated = 1 in {
1747       defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
1748       defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
1749     }
1750   }
1751 }
1752
1753 let validSubTargets = HasV4SubT in {
1754 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1755 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1756 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1757 }
1758
1759 // memb(Rx++#s4:0:circ(Mu))=Nt.new
1760 // memb(Rx++I:circ(Mu))=Nt.new
1761 // memb(Rx++Mu)=Nt.new
1762 // memb(Rx++Mu:brev)=Nt.new
1763
1764 // memb(#global)=Nt.new
1765 let mayStore = 1, neverHasSideEffects = 1 in
1766 def STb_GP_nv_V4 : NVInst_V4<(outs),
1767             (ins globaladdress:$global, IntRegs:$src),
1768             "memb(#$global) = $src.new",
1769             []>,
1770             Requires<[HasV4T]>;
1771
1772 // memh(Ru<<#u2+#U6)=Nt.new
1773 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1774 isNVStore = 1, validSubTargets = HasV4SubT in
1775 def STrih_shl_nv_V4 : NVInst_V4<(outs),
1776             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1777             "memh($src1<<#$src2+#$src3) = $src4.new",
1778             []>,
1779             Requires<[HasV4T]>;
1780
1781 // memh(Rx++#s4:1:circ(Mu))=Nt.new
1782 // memh(Rx++I:circ(Mu))=Nt.new
1783 // memh(Rx++Mu)=Nt.new
1784 // memh(Rx++Mu:brev)=Nt.new
1785
1786 // memh(#global)=Nt.new
1787 let mayStore = 1, neverHasSideEffects = 1 in
1788 def STh_GP_nv_V4 : NVInst_V4<(outs),
1789             (ins globaladdress:$global, IntRegs:$src),
1790             "memh(#$global) = $src.new",
1791             []>,
1792             Requires<[HasV4T]>;
1793
1794 // memw(Ru<<#u2+#U6)=Nt.new
1795 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1796 isNVStore = 1, validSubTargets = HasV4SubT in
1797 def STriw_shl_nv_V4 : NVInst_V4<(outs),
1798             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1799             "memw($src1<<#$src2+#$src3) = $src4.new",
1800             []>,
1801             Requires<[HasV4T]>;
1802
1803 // memw(Rx++#s4:2:circ(Mu))=Nt.new
1804 // memw(Rx++I:circ(Mu))=Nt.new
1805 // memw(Rx++Mu)=Nt.new
1806 // memw(Rx++Mu:brev)=Nt.new
1807 // memw(gp+#u16:2)=Nt.new
1808
1809 let mayStore = 1, neverHasSideEffects = 1 in
1810 def STw_GP_nv_V4 : NVInst_V4<(outs),
1811             (ins globaladdress:$global, IntRegs:$src),
1812             "memw(#$global) = $src.new",
1813             []>,
1814             Requires<[HasV4T]>;
1815
1816 // if (Pv) memb(##global) = Rt
1817 let mayStore = 1, neverHasSideEffects = 1 in
1818 def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
1819             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1820             "if ($src1) memb(##$global) = $src2.new",
1821             []>,
1822             Requires<[HasV4T]>;
1823
1824 // if (!Pv) memb(##global) = Rt
1825 let mayStore = 1, neverHasSideEffects = 1 in
1826 def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1827             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1828             "if (!$src1) memb(##$global) = $src2.new",
1829             []>,
1830             Requires<[HasV4T]>;
1831
1832 // if (Pv) memb(##global) = Rt
1833 let mayStore = 1, neverHasSideEffects = 1 in
1834 def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1835             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1836             "if ($src1.new) memb(##$global) = $src2.new",
1837             []>,
1838             Requires<[HasV4T]>;
1839
1840 // if (!Pv) memb(##global) = Rt
1841 let mayStore = 1, neverHasSideEffects = 1 in
1842 def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1843             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1844             "if (!$src1.new) memb(##$global) = $src2.new",
1845             []>,
1846             Requires<[HasV4T]>;
1847
1848 // if (Pv) memh(##global) = Rt
1849 let mayStore = 1, neverHasSideEffects = 1 in
1850 def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
1851             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1852             "if ($src1) memh(##$global) = $src2.new",
1853             []>,
1854             Requires<[HasV4T]>;
1855
1856 // if (!Pv) memh(##global) = Rt
1857 let mayStore = 1, neverHasSideEffects = 1 in
1858 def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1859             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1860             "if (!$src1) memh(##$global) = $src2.new",
1861             []>,
1862             Requires<[HasV4T]>;
1863
1864 // if (Pv) memh(##global) = Rt
1865 let mayStore = 1, neverHasSideEffects = 1 in
1866 def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1867             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1868             "if ($src1.new) memh(##$global) = $src2.new",
1869             []>,
1870             Requires<[HasV4T]>;
1871
1872 // if (!Pv) memh(##global) = Rt
1873 let mayStore = 1, neverHasSideEffects = 1 in
1874 def STh_GP_cdnNotPt_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) memw(##global) = Rt
1881 let mayStore = 1, neverHasSideEffects = 1 in
1882 def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
1883             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1884             "if ($src1) memw(##$global) = $src2.new",
1885             []>,
1886             Requires<[HasV4T]>;
1887
1888 // if (!Pv) memw(##global) = Rt
1889 let mayStore = 1, neverHasSideEffects = 1 in
1890 def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1891             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1892             "if (!$src1) memw(##$global) = $src2.new",
1893             []>,
1894             Requires<[HasV4T]>;
1895
1896 // if (Pv) memw(##global) = Rt
1897 let mayStore = 1, neverHasSideEffects = 1 in
1898 def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1899             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1900             "if ($src1.new) memw(##$global) = $src2.new",
1901             []>,
1902             Requires<[HasV4T]>;
1903
1904 // if (!Pv) memw(##global) = Rt
1905 let mayStore = 1, neverHasSideEffects = 1 in
1906 def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1907             (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1908             "if (!$src1.new) memw(##$global) = $src2.new",
1909             []>,
1910             Requires<[HasV4T]>;
1911
1912 //===----------------------------------------------------------------------===//
1913 // NV/ST -
1914 //===----------------------------------------------------------------------===//
1915
1916 //===----------------------------------------------------------------------===//
1917 // NV/J +
1918 //===----------------------------------------------------------------------===//
1919
1920 multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
1921   def _ie_nv_V4 : NVInst_V4<(outs),
1922             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1923             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1924             !strconcat("($src1.new, $src2)) jump:",
1925             !strconcat(TakenStr, " $offset"))))),
1926             []>,
1927             Requires<[HasV4T]>;
1928
1929   def _nv_V4 : NVInst_V4<(outs),
1930             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1931             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1932             !strconcat("($src1.new, $src2)) jump:",
1933             !strconcat(TakenStr, " $offset"))))),
1934             []>,
1935             Requires<[HasV4T]>;
1936 }
1937
1938 multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
1939                                                    string TakenStr> {
1940   def _ie_nv_V4 : NVInst_V4<(outs),
1941             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1942             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1943             !strconcat("($src1, $src2.new)) jump:",
1944             !strconcat(TakenStr, " $offset"))))),
1945             []>,
1946             Requires<[HasV4T]>;
1947
1948   def _nv_V4 : NVInst_V4<(outs),
1949             (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1950             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1951             !strconcat("($src1, $src2.new)) jump:",
1952             !strconcat(TakenStr, " $offset"))))),
1953             []>,
1954             Requires<[HasV4T]>;
1955 }
1956
1957 multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
1958   def _ie_nv_V4 : NVInst_V4<(outs),
1959             (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1960             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1961             !strconcat("($src1.new, #$src2)) jump:",
1962             !strconcat(TakenStr, " $offset"))))),
1963             []>,
1964             Requires<[HasV4T]>;
1965
1966   def _nv_V4 : NVInst_V4<(outs),
1967             (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1968             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1969             !strconcat("($src1.new, #$src2)) jump:",
1970             !strconcat(TakenStr, " $offset"))))),
1971             []>,
1972             Requires<[HasV4T]>;
1973 }
1974
1975 multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
1976   def _ie_nv_V4 : NVInst_V4<(outs),
1977             (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1978             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1979             !strconcat("($src1.new, #$src2)) jump:",
1980             !strconcat(TakenStr, " $offset"))))),
1981             []>,
1982             Requires<[HasV4T]>;
1983
1984   def _nv_V4 : NVInst_V4<(outs),
1985             (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1986             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1987             !strconcat("($src1.new, #$src2)) jump:",
1988             !strconcat(TakenStr, " $offset"))))),
1989             []>,
1990             Requires<[HasV4T]>;
1991 }
1992
1993 multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
1994                                                 string TakenStr> {
1995   def _ie_nv_V4 : NVInst_V4<(outs),
1996             (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
1997             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1998             !strconcat("($src1.new, #$src2)) jump:",
1999             !strconcat(TakenStr, " $offset"))))),
2000             []>,
2001             Requires<[HasV4T]>;
2002
2003   def _nv_V4 : NVInst_V4<(outs),
2004             (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2005             !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2006             !strconcat("($src1.new, #$src2)) jump:",
2007             !strconcat(TakenStr, " $offset"))))),
2008             []>,
2009             Requires<[HasV4T]>;
2010 }
2011
2012 // Multiclass for regular dot new of Ist operand register.
2013 multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> {
2014   defm Pt  : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
2015   defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
2016 }
2017
2018 // Multiclass for dot new of 2nd operand register.
2019 multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
2020   defm Pt  : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
2021   defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
2022 }
2023
2024 // Multiclass for 2nd operand immediate, including -1.
2025 multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
2026   defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2027   defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2028   defm Ptneg  : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
2029   defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
2030 }
2031
2032 // Multiclass for 2nd operand immediate, excluding -1.
2033 multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
2034   defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2035   defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2036 }
2037
2038 // Multiclass for tstbit, where 2nd operand is always #0.
2039 multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
2040   defm Pt     : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
2041   defm Pnt    : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
2042 }
2043
2044 // Multiclass for GT.
2045 multiclass NVJ_type_rr_ri<string OpcStr> {
2046   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2047   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2048   defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2049   defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
2050   defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
2051   defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
2052 }
2053
2054 // Multiclass for EQ.
2055 multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> {
2056   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2057   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2058   defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
2059   defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
2060 }
2061
2062 // Multiclass for GTU.
2063 multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> {
2064   defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
2065   defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
2066   defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2067   defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
2068   defm riNot   : NVJ_type_br_pred_imm_only<"!", OpcStr>;
2069   defm ri      : NVJ_type_br_pred_imm_only<"",  OpcStr>;
2070 }
2071
2072 // Multiclass for tstbit.
2073 multiclass NVJ_type_r0<string OpcStr> {
2074   defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
2075   defm r0    : NVJ_type_br_pred_tstbit<"",  OpcStr>;
2076  }
2077
2078 // Base Multiclass for New Value Jump.
2079 multiclass NVJ_type {
2080   defm GT     : NVJ_type_rr_ri<"cmp.gt">;
2081   defm EQ     : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
2082   defm GTU    : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
2083   defm TSTBIT : NVJ_type_r0<"tstbit">;
2084 }
2085
2086 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
2087   defm JMP_ : NVJ_type;
2088 }
2089
2090 //===----------------------------------------------------------------------===//
2091 // NV/J -
2092 //===----------------------------------------------------------------------===//
2093
2094 //===----------------------------------------------------------------------===//
2095 // XTYPE/ALU +
2096 //===----------------------------------------------------------------------===//
2097
2098 //  Add and accumulate.
2099 //  Rd=add(Rs,add(Ru,#s6))
2100 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
2101 validSubTargets = HasV4SubT in
2102 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
2103           (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
2104           "$dst = add($src1, add($src2, #$src3))",
2105           [(set (i32 IntRegs:$dst),
2106            (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
2107                                           s6_16ExtPred:$src3)))]>,
2108           Requires<[HasV4T]>;
2109
2110 //  Rd=add(Rs,sub(#s6,Ru))
2111 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2112 validSubTargets = HasV4SubT in
2113 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
2114           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2115           "$dst = add($src1, sub(#$src2, $src3))",
2116           [(set (i32 IntRegs:$dst),
2117            (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
2118                                           (i32 IntRegs:$src3))))]>,
2119           Requires<[HasV4T]>;
2120
2121 // Generates the same instruction as ADDr_SUBri_V4 but matches different
2122 // pattern.
2123 //  Rd=add(Rs,sub(#s6,Ru))
2124 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2125 validSubTargets = HasV4SubT in
2126 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
2127           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2128           "$dst = add($src1, sub(#$src2, $src3))",
2129           [(set (i32 IntRegs:$dst),
2130                 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
2131                      (i32 IntRegs:$src3)))]>,
2132           Requires<[HasV4T]>;
2133
2134
2135 //  Add or subtract doublewords with carry.
2136 //TODO:
2137 //  Rdd=add(Rss,Rtt,Px):carry
2138 //TODO:
2139 //  Rdd=sub(Rss,Rtt,Px):carry
2140
2141
2142 //  Logical doublewords.
2143 //  Rdd=and(Rtt,~Rss)
2144 let validSubTargets = HasV4SubT in
2145 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2146           (ins DoubleRegs:$src1, DoubleRegs:$src2),
2147           "$dst = and($src1, ~$src2)",
2148           [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
2149                                       (not (i64 DoubleRegs:$src2))))]>,
2150           Requires<[HasV4T]>;
2151
2152 //  Rdd=or(Rtt,~Rss)
2153 let validSubTargets = HasV4SubT in
2154 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2155           (ins DoubleRegs:$src1, DoubleRegs:$src2),
2156           "$dst = or($src1, ~$src2)",
2157           [(set (i64 DoubleRegs:$dst),
2158            (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
2159           Requires<[HasV4T]>;
2160
2161
2162 //  Logical-logical doublewords.
2163 //  Rxx^=xor(Rss,Rtt)
2164 let validSubTargets = HasV4SubT in
2165 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
2166           (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
2167           "$dst ^= xor($src2, $src3)",
2168           [(set (i64 DoubleRegs:$dst),
2169            (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
2170                                              (i64 DoubleRegs:$src3))))],
2171           "$src1 = $dst">,
2172           Requires<[HasV4T]>;
2173
2174
2175 // Logical-logical words.
2176 // Rx=or(Ru,and(Rx,#s10))
2177 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2178 validSubTargets = HasV4SubT in
2179 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
2180             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2181             "$dst = or($src1, and($src2, #$src3))",
2182             [(set (i32 IntRegs:$dst),
2183                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2184                                                 s10ExtPred:$src3)))],
2185             "$src2 = $dst">,
2186             Requires<[HasV4T]>;
2187
2188 // Rx[&|^]=and(Rs,Rt)
2189 // Rx&=and(Rs,Rt)
2190 let validSubTargets = HasV4SubT in
2191 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2192             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2193             "$dst &= and($src2, $src3)",
2194             [(set (i32 IntRegs:$dst),
2195                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2196                                                  (i32 IntRegs:$src3))))],
2197             "$src1 = $dst">,
2198             Requires<[HasV4T]>;
2199
2200 // Rx|=and(Rs,Rt)
2201 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
2202 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2203             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2204             "$dst |= and($src2, $src3)",
2205             [(set (i32 IntRegs:$dst),
2206                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2207                                                 (i32 IntRegs:$src3))))],
2208             "$src1 = $dst">,
2209             Requires<[HasV4T]>, ImmRegRel;
2210
2211 // Rx^=and(Rs,Rt)
2212 let validSubTargets = HasV4SubT in
2213 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2214             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2215             "$dst ^= and($src2, $src3)",
2216             [(set (i32 IntRegs:$dst),
2217              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2218                                             (i32 IntRegs:$src3))))],
2219             "$src1 = $dst">,
2220             Requires<[HasV4T]>;
2221
2222 // Rx[&|^]=and(Rs,~Rt)
2223 // Rx&=and(Rs,~Rt)
2224 let validSubTargets = HasV4SubT in
2225 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2226             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2227             "$dst &= and($src2, ~$src3)",
2228             [(set (i32 IntRegs:$dst),
2229                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2230                                                  (not (i32 IntRegs:$src3)))))],
2231             "$src1 = $dst">,
2232             Requires<[HasV4T]>;
2233
2234 // Rx|=and(Rs,~Rt)
2235 let validSubTargets = HasV4SubT in
2236 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2237             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2238             "$dst |= and($src2, ~$src3)",
2239             [(set (i32 IntRegs:$dst),
2240              (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2241                                            (not (i32 IntRegs:$src3)))))],
2242             "$src1 = $dst">,
2243             Requires<[HasV4T]>;
2244
2245 // Rx^=and(Rs,~Rt)
2246 let validSubTargets = HasV4SubT in
2247 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2248             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2249             "$dst ^= and($src2, ~$src3)",
2250             [(set (i32 IntRegs:$dst),
2251              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2252                                             (not (i32 IntRegs:$src3)))))],
2253             "$src1 = $dst">,
2254             Requires<[HasV4T]>;
2255
2256 // Rx[&|^]=or(Rs,Rt)
2257 // Rx&=or(Rs,Rt)
2258 let validSubTargets = HasV4SubT in
2259 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2260             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2261             "$dst &= or($src2, $src3)",
2262             [(set (i32 IntRegs:$dst),
2263                   (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2264                                                 (i32 IntRegs:$src3))))],
2265             "$src1 = $dst">,
2266             Requires<[HasV4T]>;
2267
2268 // Rx|=or(Rs,Rt)
2269 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
2270 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2271             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2272             "$dst |= or($src2, $src3)",
2273             [(set (i32 IntRegs:$dst),
2274                   (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2275                                                (i32 IntRegs:$src3))))],
2276             "$src1 = $dst">,
2277             Requires<[HasV4T]>, ImmRegRel;
2278
2279 // Rx^=or(Rs,Rt)
2280 let validSubTargets = HasV4SubT in
2281 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2282             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2283             "$dst ^= or($src2, $src3)",
2284             [(set (i32 IntRegs:$dst),
2285              (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2286                                            (i32 IntRegs:$src3))))],
2287             "$src1 = $dst">,
2288             Requires<[HasV4T]>;
2289
2290 // Rx[&|^]=xor(Rs,Rt)
2291 // Rx&=xor(Rs,Rt)
2292 let validSubTargets = HasV4SubT in
2293 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2294             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2295             "$dst &= xor($src2, $src3)",
2296             [(set (i32 IntRegs:$dst),
2297                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2298                                                  (i32 IntRegs:$src3))))],
2299             "$src1 = $dst">,
2300             Requires<[HasV4T]>;
2301
2302 // Rx|=xor(Rs,Rt)
2303 let validSubTargets = HasV4SubT in
2304 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2305             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2306             "$dst |= xor($src2, $src3)",
2307             [(set (i32 IntRegs:$dst),
2308                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2309                                                  (i32 IntRegs:$src3))))],
2310             "$src1 = $dst">,
2311             Requires<[HasV4T]>;
2312
2313 // Rx^=xor(Rs,Rt)
2314 let validSubTargets = HasV4SubT in
2315 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2316             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2317             "$dst ^= xor($src2, $src3)",
2318             [(set (i32 IntRegs:$dst),
2319              (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2320                                             (i32 IntRegs:$src3))))],
2321             "$src1 = $dst">,
2322             Requires<[HasV4T]>;
2323
2324 // Rx|=and(Rs,#s10)
2325 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2326 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
2327 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
2328             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2329             "$dst |= and($src2, #$src3)",
2330             [(set (i32 IntRegs:$dst),
2331                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2332                                                 s10ExtPred:$src3)))],
2333             "$src1 = $dst">,
2334             Requires<[HasV4T]>, ImmRegRel;
2335
2336 // Rx|=or(Rs,#s10)
2337 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2338 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
2339 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
2340             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2341             "$dst |= or($src2, #$src3)",
2342             [(set (i32 IntRegs:$dst),
2343                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2344                                                 s10ExtPred:$src3)))],
2345             "$src1 = $dst">,
2346             Requires<[HasV4T]>, ImmRegRel;
2347
2348
2349 //    Modulo wrap
2350 //        Rd=modwrap(Rs,Rt)
2351 //    Round
2352 //        Rd=cround(Rs,#u5)
2353 //        Rd=cround(Rs,Rt)
2354 //        Rd=round(Rs,#u5)[:sat]
2355 //        Rd=round(Rs,Rt)[:sat]
2356 //    Vector reduce add unsigned halfwords
2357 //        Rd=vraddh(Rss,Rtt)
2358 //    Vector add bytes
2359 //        Rdd=vaddb(Rss,Rtt)
2360 //    Vector conditional negate
2361 //        Rdd=vcnegh(Rss,Rt)
2362 //        Rxx+=vrcnegh(Rss,Rt)
2363 //    Vector maximum bytes
2364 //        Rdd=vmaxb(Rtt,Rss)
2365 //    Vector reduce maximum halfwords
2366 //        Rxx=vrmaxh(Rss,Ru)
2367 //        Rxx=vrmaxuh(Rss,Ru)
2368 //    Vector reduce maximum words
2369 //        Rxx=vrmaxuw(Rss,Ru)
2370 //        Rxx=vrmaxw(Rss,Ru)
2371 //    Vector minimum bytes
2372 //        Rdd=vminb(Rtt,Rss)
2373 //    Vector reduce minimum halfwords
2374 //        Rxx=vrminh(Rss,Ru)
2375 //        Rxx=vrminuh(Rss,Ru)
2376 //    Vector reduce minimum words
2377 //        Rxx=vrminuw(Rss,Ru)
2378 //        Rxx=vrminw(Rss,Ru)
2379 //    Vector subtract bytes
2380 //        Rdd=vsubb(Rss,Rtt)
2381
2382 //===----------------------------------------------------------------------===//
2383 // XTYPE/ALU -
2384 //===----------------------------------------------------------------------===//
2385
2386
2387 //===----------------------------------------------------------------------===//
2388 // XTYPE/MPY +
2389 //===----------------------------------------------------------------------===//
2390
2391 // Multiply and user lower result.
2392 // Rd=add(#u6,mpyi(Rs,#U6))
2393 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2394 validSubTargets = HasV4SubT in
2395 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
2396             (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
2397             "$dst = add(#$src1, mpyi($src2, #$src3))",
2398             [(set (i32 IntRegs:$dst),
2399                   (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2400                        u6ExtPred:$src1))]>,
2401             Requires<[HasV4T]>;
2402
2403 // Rd=add(##,mpyi(Rs,#U6))
2404 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2405                      (HexagonCONST32 tglobaladdr:$src1)),
2406            (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
2407                                u6ImmPred:$src3))>;
2408
2409 // Rd=add(#u6,mpyi(Rs,Rt))
2410 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2411 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2412 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
2413             (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
2414             "$dst = add(#$src1, mpyi($src2, $src3))",
2415             [(set (i32 IntRegs:$dst),
2416                   (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2417                        u6ExtPred:$src1))]>,
2418             Requires<[HasV4T]>, ImmRegRel;
2419
2420 // Rd=add(##,mpyi(Rs,Rt))
2421 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2422                      (HexagonCONST32 tglobaladdr:$src1)),
2423            (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
2424                                IntRegs:$src3))>;
2425
2426 // Rd=add(Ru,mpyi(#u6:2,Rs))
2427 let validSubTargets = HasV4SubT in
2428 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
2429             (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
2430             "$dst = add($src1, mpyi(#$src2, $src3))",
2431             [(set (i32 IntRegs:$dst),
2432              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
2433                                             u6_2ImmPred:$src2)))]>,
2434             Requires<[HasV4T]>;
2435
2436 // Rd=add(Ru,mpyi(Rs,#u6))
2437 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
2438 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2439 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
2440             (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
2441             "$dst = add($src1, mpyi($src2, #$src3))",
2442             [(set (i32 IntRegs:$dst),
2443                   (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2444                                                  u6ExtPred:$src3)))]>,
2445             Requires<[HasV4T]>, ImmRegRel;
2446
2447 // Rx=add(Ru,mpyi(Rx,Rs))
2448 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
2449 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
2450             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
2451             "$dst = add($src1, mpyi($src2, $src3))",
2452             [(set (i32 IntRegs:$dst),
2453              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2454                                             (i32 IntRegs:$src3))))],
2455             "$src2 = $dst">,
2456             Requires<[HasV4T]>, ImmRegRel;
2457
2458
2459 // Polynomial multiply words
2460 // Rdd=pmpyw(Rs,Rt)
2461 // Rxx^=pmpyw(Rs,Rt)
2462
2463 // Vector reduce multiply word by signed half (32x16)
2464 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
2465 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2466 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
2467 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
2468
2469 // Multiply and use upper result
2470 // Rd=mpy(Rs,Rt.H):<<1:sat
2471 // Rd=mpy(Rs,Rt.L):<<1:sat
2472 // Rd=mpy(Rs,Rt):<<1
2473 // Rd=mpy(Rs,Rt):<<1:sat
2474 // Rd=mpysu(Rs,Rt)
2475 // Rx+=mpy(Rs,Rt):<<1:sat
2476 // Rx-=mpy(Rs,Rt):<<1:sat
2477
2478 // Vector multiply bytes
2479 // Rdd=vmpybsu(Rs,Rt)
2480 // Rdd=vmpybu(Rs,Rt)
2481 // Rxx+=vmpybsu(Rs,Rt)
2482 // Rxx+=vmpybu(Rs,Rt)
2483
2484 // Vector polynomial multiply halfwords
2485 // Rdd=vpmpyh(Rs,Rt)
2486 // Rxx^=vpmpyh(Rs,Rt)
2487
2488 //===----------------------------------------------------------------------===//
2489 // XTYPE/MPY -
2490 //===----------------------------------------------------------------------===//
2491
2492
2493 //===----------------------------------------------------------------------===//
2494 // XTYPE/SHIFT +
2495 //===----------------------------------------------------------------------===//
2496
2497 // Shift by immediate and accumulate.
2498 // Rx=add(#u8,asl(Rx,#U5))
2499 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2500 validSubTargets = HasV4SubT in
2501 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2502             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2503             "$dst = add(#$src1, asl($src2, #$src3))",
2504             [(set (i32 IntRegs:$dst),
2505                   (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2506                        u8ExtPred:$src1))],
2507             "$src2 = $dst">,
2508             Requires<[HasV4T]>;
2509
2510 // Rx=add(#u8,lsr(Rx,#U5))
2511 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2512 validSubTargets = HasV4SubT in
2513 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2514             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2515             "$dst = add(#$src1, lsr($src2, #$src3))",
2516             [(set (i32 IntRegs:$dst),
2517                   (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2518                        u8ExtPred:$src1))],
2519             "$src2 = $dst">,
2520             Requires<[HasV4T]>;
2521
2522 // Rx=sub(#u8,asl(Rx,#U5))
2523 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2524 validSubTargets = HasV4SubT in
2525 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2526             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2527             "$dst = sub(#$src1, asl($src2, #$src3))",
2528             [(set (i32 IntRegs:$dst),
2529                   (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2530                        u8ExtPred:$src1))],
2531             "$src2 = $dst">,
2532             Requires<[HasV4T]>;
2533
2534 // Rx=sub(#u8,lsr(Rx,#U5))
2535 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2536 validSubTargets = HasV4SubT in
2537 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2538             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2539             "$dst = sub(#$src1, lsr($src2, #$src3))",
2540             [(set (i32 IntRegs:$dst),
2541                   (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2542                        u8ExtPred:$src1))],
2543             "$src2 = $dst">,
2544             Requires<[HasV4T]>;
2545
2546
2547 //Shift by immediate and logical.
2548 //Rx=and(#u8,asl(Rx,#U5))
2549 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2550 validSubTargets = HasV4SubT in
2551 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2552             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2553             "$dst = and(#$src1, asl($src2, #$src3))",
2554             [(set (i32 IntRegs:$dst),
2555                   (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2556                        u8ExtPred:$src1))],
2557             "$src2 = $dst">,
2558             Requires<[HasV4T]>;
2559
2560 //Rx=and(#u8,lsr(Rx,#U5))
2561 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2562 validSubTargets = HasV4SubT in
2563 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2564             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2565             "$dst = and(#$src1, lsr($src2, #$src3))",
2566             [(set (i32 IntRegs:$dst),
2567                   (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2568                        u8ExtPred:$src1))],
2569             "$src2 = $dst">,
2570             Requires<[HasV4T]>;
2571
2572 //Rx=or(#u8,asl(Rx,#U5))
2573 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2574 AddedComplexity = 30, validSubTargets = HasV4SubT in
2575 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2576             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2577             "$dst = or(#$src1, asl($src2, #$src3))",
2578             [(set (i32 IntRegs:$dst),
2579                   (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2580                       u8ExtPred:$src1))],
2581             "$src2 = $dst">,
2582             Requires<[HasV4T]>;
2583
2584 //Rx=or(#u8,lsr(Rx,#U5))
2585 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2586 AddedComplexity = 30, validSubTargets = HasV4SubT in
2587 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2588             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2589             "$dst = or(#$src1, lsr($src2, #$src3))",
2590             [(set (i32 IntRegs:$dst),
2591                   (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2592                       u8ExtPred:$src1))],
2593             "$src2 = $dst">,
2594             Requires<[HasV4T]>;
2595
2596
2597 //Shift by register.
2598 //Rd=lsl(#s6,Rt)
2599 let validSubTargets = HasV4SubT in {
2600 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
2601             "$dst = lsl(#$src1, $src2)",
2602             [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
2603                                            (i32 IntRegs:$src2)))]>,
2604             Requires<[HasV4T]>;
2605
2606
2607 //Shift by register and logical.
2608 //Rxx^=asl(Rss,Rt)
2609 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2610             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2611             "$dst ^= asl($src2, $src3)",
2612             [(set (i64 DoubleRegs:$dst),
2613                   (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
2614                                                     (i32 IntRegs:$src3))))],
2615             "$src1 = $dst">,
2616             Requires<[HasV4T]>;
2617
2618 //Rxx^=asr(Rss,Rt)
2619 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2620             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2621             "$dst ^= asr($src2, $src3)",
2622             [(set (i64 DoubleRegs:$dst),
2623                   (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
2624                                                     (i32 IntRegs:$src3))))],
2625             "$src1 = $dst">,
2626             Requires<[HasV4T]>;
2627
2628 //Rxx^=lsl(Rss,Rt)
2629 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2630             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2631             "$dst ^= lsl($src2, $src3)",
2632             [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
2633                                               (shl (i64 DoubleRegs:$src2),
2634                                                    (i32 IntRegs:$src3))))],
2635             "$src1 = $dst">,
2636             Requires<[HasV4T]>;
2637
2638 //Rxx^=lsr(Rss,Rt)
2639 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2640             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2641             "$dst ^= lsr($src2, $src3)",
2642             [(set (i64 DoubleRegs:$dst),
2643                   (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
2644                                                     (i32 IntRegs:$src3))))],
2645             "$src1 = $dst">,
2646             Requires<[HasV4T]>;
2647 }
2648
2649 //===----------------------------------------------------------------------===//
2650 // XTYPE/SHIFT -
2651 //===----------------------------------------------------------------------===//
2652
2653 //===----------------------------------------------------------------------===//
2654 // MEMOP: Word, Half, Byte
2655 //===----------------------------------------------------------------------===//
2656
2657 //===----------------------------------------------------------------------===//
2658 // MEMOP: Word
2659 //
2660 //  Implemented:
2661 //     MEMw_ADDi_indexed_V4  : memw(Rs+#u6:2)+=#U5
2662 //     MEMw_SUBi_indexed_V4  : memw(Rs+#u6:2)-=#U5
2663 //     MEMw_ADDr_indexed_V4  : memw(Rs+#u6:2)+=Rt
2664 //     MEMw_SUBr_indexed_V4  : memw(Rs+#u6:2)-=Rt
2665 //     MEMw_CLRr_indexed_V4  : memw(Rs+#u6:2)&=Rt
2666 //     MEMw_SETr_indexed_V4  : memw(Rs+#u6:2)|=Rt
2667 //     MEMw_ADDi_V4          : memw(Rs+#u6:2)+=#U5
2668 //     MEMw_SUBi_V4          : memw(Rs+#u6:2)-=#U5
2669 //     MEMw_ADDr_V4          : memw(Rs+#u6:2)+=Rt
2670 //     MEMw_SUBr_V4          : memw(Rs+#u6:2)-=Rt
2671 //     MEMw_CLRr_V4          : memw(Rs+#u6:2)&=Rt
2672 //     MEMw_SETr_V4          : memw(Rs+#u6:2)|=Rt
2673 //
2674 //   Not implemented:
2675 //     MEMw_CLRi_indexed_V4  : memw(Rs+#u6:2)=clrbit(#U5)
2676 //     MEMw_SETi_indexed_V4  : memw(Rs+#u6:2)=setbit(#U5)
2677 //     MEMw_CLRi_V4          : memw(Rs+#u6:2)=clrbit(#U5)
2678 //     MEMw_SETi_V4          : memw(Rs+#u6:2)=setbit(#U5)
2679 //===----------------------------------------------------------------------===//
2680
2681
2682
2683 // memw(Rs+#u6:2) += #U5
2684 let AddedComplexity = 30 in
2685 def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2686             (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
2687             "memw($base+#$offset) += #$addend",
2688             []>,
2689             Requires<[HasV4T, UseMEMOP]>;
2690
2691 // memw(Rs+#u6:2) -= #U5
2692 let AddedComplexity = 30 in
2693 def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2694             (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
2695             "memw($base+#$offset) -= #$subend",
2696             []>,
2697             Requires<[HasV4T, UseMEMOP]>;
2698
2699 // memw(Rs+#u6:2) += Rt
2700 let AddedComplexity = 30 in
2701 def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2702             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
2703             "memw($base+#$offset) += $addend",
2704             [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2705                          (i32 IntRegs:$addend)),
2706                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2707             Requires<[HasV4T, UseMEMOP]>;
2708
2709 // memw(Rs+#u6:2) -= Rt
2710 let AddedComplexity = 30 in
2711 def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2712             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
2713             "memw($base+#$offset) -= $subend",
2714             [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2715                          (i32 IntRegs:$subend)),
2716                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2717             Requires<[HasV4T, UseMEMOP]>;
2718
2719 // memw(Rs+#u6:2) &= Rt
2720 let AddedComplexity = 30 in
2721 def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2722             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
2723             "memw($base+#$offset) &= $andend",
2724             [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2725                          (i32 IntRegs:$andend)),
2726                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2727             Requires<[HasV4T, UseMEMOP]>;
2728
2729 // memw(Rs+#u6:2) |= Rt
2730 let AddedComplexity = 30 in
2731 def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2732             (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
2733             "memw($base+#$offset) |= $orend",
2734             [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2735                         (i32 IntRegs:$orend)),
2736                     (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2737             Requires<[HasV4T, UseMEMOP]>;
2738
2739 // memw(Rs+#u6:2) += #U5
2740 let AddedComplexity = 30 in
2741 def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
2742             (ins MEMri:$addr, u5Imm:$addend),
2743             "memw($addr) += $addend",
2744             []>,
2745             Requires<[HasV4T, UseMEMOP]>;
2746
2747 // memw(Rs+#u6:2) -= #U5
2748 let AddedComplexity = 30 in
2749 def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
2750             (ins MEMri:$addr, u5Imm:$subend),
2751             "memw($addr) -= $subend",
2752             []>,
2753             Requires<[HasV4T, UseMEMOP]>;
2754
2755 // memw(Rs+#u6:2) += Rt
2756 let AddedComplexity = 30 in
2757 def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
2758             (ins MEMri:$addr, IntRegs:$addend),
2759             "memw($addr) += $addend",
2760             [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
2761                     ADDRriU6_2:$addr)]>,
2762             Requires<[HasV4T, UseMEMOP]>;
2763
2764 // memw(Rs+#u6:2) -= Rt
2765 let AddedComplexity = 30 in
2766 def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
2767             (ins MEMri:$addr, IntRegs:$subend),
2768             "memw($addr) -= $subend",
2769             [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
2770                     ADDRriU6_2:$addr)]>,
2771             Requires<[HasV4T, UseMEMOP]>;
2772
2773 // memw(Rs+#u6:2) &= Rt
2774 let AddedComplexity = 30 in
2775 def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
2776             (ins MEMri:$addr, IntRegs:$andend),
2777             "memw($addr) &= $andend",
2778             [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
2779                     ADDRriU6_2:$addr)]>,
2780             Requires<[HasV4T, UseMEMOP]>;
2781
2782 // memw(Rs+#u6:2) |= Rt
2783 let AddedComplexity = 30 in
2784 def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
2785             (ins MEMri:$addr, IntRegs:$orend),
2786             "memw($addr) |= $orend",
2787             [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
2788                     ADDRriU6_2:$addr)]>,
2789             Requires<[HasV4T, UseMEMOP]>;
2790
2791 //===----------------------------------------------------------------------===//
2792 // MEMOP: Halfword
2793 //
2794 //  Implemented:
2795 //     MEMh_ADDi_indexed_V4  : memw(Rs+#u6:2)+=#U5
2796 //     MEMh_SUBi_indexed_V4  : memw(Rs+#u6:2)-=#U5
2797 //     MEMh_ADDr_indexed_V4  : memw(Rs+#u6:2)+=Rt
2798 //     MEMh_SUBr_indexed_V4  : memw(Rs+#u6:2)-=Rt
2799 //     MEMh_CLRr_indexed_V4  : memw(Rs+#u6:2)&=Rt
2800 //     MEMh_SETr_indexed_V4  : memw(Rs+#u6:2)|=Rt
2801 //     MEMh_ADDi_V4          : memw(Rs+#u6:2)+=#U5
2802 //     MEMh_SUBi_V4          : memw(Rs+#u6:2)-=#U5
2803 //     MEMh_ADDr_V4          : memw(Rs+#u6:2)+=Rt
2804 //     MEMh_SUBr_V4          : memw(Rs+#u6:2)-=Rt
2805 //     MEMh_CLRr_V4          : memw(Rs+#u6:2)&=Rt
2806 //     MEMh_SETr_V4          : memw(Rs+#u6:2)|=Rt
2807 //
2808 //   Not implemented:
2809 //     MEMh_CLRi_indexed_V4  : memw(Rs+#u6:2)=clrbit(#U5)
2810 //     MEMh_SETi_indexed_V4  : memw(Rs+#u6:2)=setbit(#U5)
2811 //     MEMh_CLRi_V4          : memw(Rs+#u6:2)=clrbit(#U5)
2812 //     MEMh_SETi_V4          : memw(Rs+#u6:2)=setbit(#U5)
2813 //===----------------------------------------------------------------------===//
2814
2815
2816 // memh(Rs+#u6:1) += #U5
2817 let AddedComplexity = 30 in
2818 def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2819             (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
2820             "memh($base+#$offset) += $addend",
2821             []>,
2822             Requires<[HasV4T, UseMEMOP]>;
2823
2824 // memh(Rs+#u6:1) -= #U5
2825 let AddedComplexity = 30 in
2826 def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2827             (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
2828             "memh($base+#$offset) -= $subend",
2829             []>,
2830             Requires<[HasV4T, UseMEMOP]>;
2831
2832 // memh(Rs+#u6:1) += Rt
2833 let AddedComplexity = 30 in
2834 def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2835             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
2836             "memh($base+#$offset) += $addend",
2837             [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
2838                                                    u6_1ImmPred:$offset)),
2839                                  (i32 IntRegs:$addend)),
2840                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2841             Requires<[HasV4T, UseMEMOP]>;
2842
2843 // memh(Rs+#u6:1) -= Rt
2844 let AddedComplexity = 30 in
2845 def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2846             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
2847             "memh($base+#$offset) -= $subend",
2848             [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
2849                                                    u6_1ImmPred:$offset)),
2850                                  (i32 IntRegs:$subend)),
2851                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2852             Requires<[HasV4T, UseMEMOP]>;
2853
2854 // memh(Rs+#u6:1) &= Rt
2855 let AddedComplexity = 30 in
2856 def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2857             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
2858             "memh($base+#$offset) += $andend",
2859             [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
2860                                                    u6_1ImmPred:$offset)),
2861                                  (i32 IntRegs:$andend)),
2862                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2863             Requires<[HasV4T, UseMEMOP]>;
2864
2865 // memh(Rs+#u6:1) |= Rt
2866 let AddedComplexity = 30 in
2867 def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2868             (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
2869             "memh($base+#$offset) |= $orend",
2870             [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
2871                                               u6_1ImmPred:$offset)),
2872                              (i32 IntRegs:$orend)),
2873                             (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2874             Requires<[HasV4T, UseMEMOP]>;
2875
2876 // memh(Rs+#u6:1) += #U5
2877 let AddedComplexity = 30 in
2878 def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
2879             (ins MEMri:$addr, u5Imm:$addend),
2880             "memh($addr) += $addend",
2881             []>,
2882             Requires<[HasV4T, UseMEMOP]>;
2883
2884 // memh(Rs+#u6:1) -= #U5
2885 let AddedComplexity = 30 in
2886 def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
2887             (ins MEMri:$addr, u5Imm:$subend),
2888             "memh($addr) -= $subend",
2889             []>,
2890             Requires<[HasV4T, UseMEMOP]>;
2891
2892 // memh(Rs+#u6:1) += Rt
2893 let AddedComplexity = 30 in
2894 def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
2895             (ins MEMri:$addr, IntRegs:$addend),
2896             "memh($addr) += $addend",
2897             [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
2898                                  (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
2899             Requires<[HasV4T, UseMEMOP]>;
2900
2901 // memh(Rs+#u6:1) -= Rt
2902 let AddedComplexity = 30 in
2903 def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
2904             (ins MEMri:$addr, IntRegs:$subend),
2905             "memh($addr) -= $subend",
2906             [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
2907                                  (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
2908             Requires<[HasV4T, UseMEMOP]>;
2909
2910 // memh(Rs+#u6:1) &= Rt
2911 let AddedComplexity = 30 in
2912 def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
2913             (ins MEMri:$addr, IntRegs:$andend),
2914             "memh($addr) &= $andend",
2915             [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
2916                                  (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
2917             Requires<[HasV4T, UseMEMOP]>;
2918
2919 // memh(Rs+#u6:1) |= Rt
2920 let AddedComplexity = 30 in
2921 def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
2922             (ins MEMri:$addr, IntRegs:$orend),
2923             "memh($addr) |= $orend",
2924             [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
2925                                 (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
2926             Requires<[HasV4T, UseMEMOP]>;
2927
2928
2929 //===----------------------------------------------------------------------===//
2930 // MEMOP: Byte
2931 //
2932 //  Implemented:
2933 //     MEMb_ADDi_indexed_V4  : memb(Rs+#u6:0)+=#U5
2934 //     MEMb_SUBi_indexed_V4  : memb(Rs+#u6:0)-=#U5
2935 //     MEMb_ADDr_indexed_V4  : memb(Rs+#u6:0)+=Rt
2936 //     MEMb_SUBr_indexed_V4  : memb(Rs+#u6:0)-=Rt
2937 //     MEMb_CLRr_indexed_V4  : memb(Rs+#u6:0)&=Rt
2938 //     MEMb_SETr_indexed_V4  : memb(Rs+#u6:0)|=Rt
2939 //     MEMb_ADDi_V4          : memb(Rs+#u6:0)+=#U5
2940 //     MEMb_SUBi_V4          : memb(Rs+#u6:0)-=#U5
2941 //     MEMb_ADDr_V4          : memb(Rs+#u6:0)+=Rt
2942 //     MEMb_SUBr_V4          : memb(Rs+#u6:0)-=Rt
2943 //     MEMb_CLRr_V4          : memb(Rs+#u6:0)&=Rt
2944 //     MEMb_SETr_V4          : memb(Rs+#u6:0)|=Rt
2945 //
2946 //   Not implemented:
2947 //     MEMb_CLRi_indexed_V4  : memb(Rs+#u6:0)=clrbit(#U5)
2948 //     MEMb_SETi_indexed_V4  : memb(Rs+#u6:0)=setbit(#U5)
2949 //     MEMb_CLRi_V4          : memb(Rs+#u6:0)=clrbit(#U5)
2950 //     MEMb_SETi_V4          : memb(Rs+#u6:0)=setbit(#U5)
2951 //===----------------------------------------------------------------------===//
2952
2953 // memb(Rs+#u6:0) += #U5
2954 let AddedComplexity = 30 in
2955 def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2956             (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
2957             "memb($base+#$offset) += $addend",
2958             []>,
2959             Requires<[HasV4T, UseMEMOP]>;
2960
2961 // memb(Rs+#u6:0) -= #U5
2962 let AddedComplexity = 30 in
2963 def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2964             (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
2965             "memb($base+#$offset) -= $subend",
2966             []>,
2967             Requires<[HasV4T, UseMEMOP]>;
2968
2969 // memb(Rs+#u6:0) += Rt
2970 let AddedComplexity = 30 in
2971 def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2972             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
2973             "memb($base+#$offset) += $addend",
2974             [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
2975                                                  u6_0ImmPred:$offset)),
2976                                 (i32 IntRegs:$addend)),
2977                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2978             Requires<[HasV4T, UseMEMOP]>;
2979
2980 // memb(Rs+#u6:0) -= Rt
2981 let AddedComplexity = 30 in
2982 def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2983             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
2984             "memb($base+#$offset) -= $subend",
2985             [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
2986                                                  u6_0ImmPred:$offset)),
2987                                 (i32 IntRegs:$subend)),
2988                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2989             Requires<[HasV4T, UseMEMOP]>;
2990
2991 // memb(Rs+#u6:0) &= Rt
2992 let AddedComplexity = 30 in
2993 def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2994             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
2995             "memb($base+#$offset) += $andend",
2996             [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
2997                                                  u6_0ImmPred:$offset)),
2998                                 (i32 IntRegs:$andend)),
2999                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3000             Requires<[HasV4T, UseMEMOP]>;
3001
3002 // memb(Rs+#u6:0) |= Rt
3003 let AddedComplexity = 30 in
3004 def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
3005             (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
3006             "memb($base+#$offset) |= $orend",
3007             [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
3008                                                 u6_0ImmPred:$offset)),
3009                                (i32 IntRegs:$orend)),
3010                            (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3011             Requires<[HasV4T, UseMEMOP]>;
3012
3013 // memb(Rs+#u6:0) += #U5
3014 let AddedComplexity = 30 in
3015 def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
3016             (ins MEMri:$addr, u5Imm:$addend),
3017             "memb($addr) += $addend",
3018             []>,
3019             Requires<[HasV4T, UseMEMOP]>;
3020
3021 // memb(Rs+#u6:0) -= #U5
3022 let AddedComplexity = 30 in
3023 def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
3024             (ins MEMri:$addr, u5Imm:$subend),
3025             "memb($addr) -= $subend",
3026             []>,
3027             Requires<[HasV4T, UseMEMOP]>;
3028
3029 // memb(Rs+#u6:0) += Rt
3030 let AddedComplexity = 30 in
3031 def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
3032             (ins MEMri:$addr, IntRegs:$addend),
3033             "memb($addr) += $addend",
3034             [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
3035                                 (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
3036             Requires<[HasV4T, UseMEMOP]>;
3037
3038 // memb(Rs+#u6:0) -= Rt
3039 let AddedComplexity = 30 in
3040 def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
3041             (ins MEMri:$addr, IntRegs:$subend),
3042             "memb($addr) -= $subend",
3043             [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
3044                                 (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
3045             Requires<[HasV4T, UseMEMOP]>;
3046
3047 // memb(Rs+#u6:0) &= Rt
3048 let AddedComplexity = 30 in
3049 def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
3050             (ins MEMri:$addr, IntRegs:$andend),
3051             "memb($addr) &= $andend",
3052             [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
3053                                 (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
3054             Requires<[HasV4T, UseMEMOP]>;
3055
3056 // memb(Rs+#u6:0) |= Rt
3057 let AddedComplexity = 30 in
3058 def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
3059             (ins MEMri:$addr, IntRegs:$orend),
3060             "memb($addr) |= $orend",
3061             [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
3062                                (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
3063             Requires<[HasV4T, UseMEMOP]>;
3064
3065
3066 //===----------------------------------------------------------------------===//
3067 // XTYPE/PRED +
3068 //===----------------------------------------------------------------------===//
3069
3070 // Hexagon V4 only supports these flavors of byte/half compare instructions:
3071 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
3072 // hardware. However, compiler can still implement these patterns through
3073 // appropriate patterns combinations based on current implemented patterns.
3074 // The implemented patterns are: EQ/GT/GTU.
3075 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
3076
3077 // Following instruction is not being extended as it results into the
3078 // incorrect code for negative numbers.
3079 // Pd=cmpb.eq(Rs,#u8)
3080
3081 // p=!cmp.eq(r1,r2)
3082 let isCompare = 1, validSubTargets = HasV4SubT in
3083 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
3084                            (ins IntRegs:$src1, IntRegs:$src2),
3085       "$dst = !cmp.eq($src1, $src2)",
3086       [(set (i1 PredRegs:$dst),
3087             (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
3088       Requires<[HasV4T]>;
3089
3090 // p=!cmp.eq(r1,#s10)
3091 let isCompare = 1, validSubTargets = HasV4SubT in
3092 def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
3093                            (ins IntRegs:$src1, s10Ext:$src2),
3094       "$dst = !cmp.eq($src1, #$src2)",
3095       [(set (i1 PredRegs:$dst),
3096             (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
3097       Requires<[HasV4T]>;
3098
3099 // p=!cmp.gt(r1,r2)
3100 let isCompare = 1, validSubTargets = HasV4SubT in
3101 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
3102                            (ins IntRegs:$src1, IntRegs:$src2),
3103       "$dst = !cmp.gt($src1, $src2)",
3104       [(set (i1 PredRegs:$dst),
3105             (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3106       Requires<[HasV4T]>;
3107
3108 // p=!cmp.gt(r1,#s10)
3109 let isCompare = 1, validSubTargets = HasV4SubT in
3110 def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
3111                            (ins IntRegs:$src1, s10Ext:$src2),
3112       "$dst = !cmp.gt($src1, #$src2)",
3113       [(set (i1 PredRegs:$dst),
3114             (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
3115       Requires<[HasV4T]>;
3116
3117 // p=!cmp.gtu(r1,r2)
3118 let isCompare = 1, validSubTargets = HasV4SubT in
3119 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
3120                             (ins IntRegs:$src1, IntRegs:$src2),
3121       "$dst = !cmp.gtu($src1, $src2)",
3122       [(set (i1 PredRegs:$dst),
3123             (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3124       Requires<[HasV4T]>;
3125
3126 // p=!cmp.gtu(r1,#u9)
3127 let isCompare = 1, validSubTargets = HasV4SubT in
3128 def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
3129                             (ins IntRegs:$src1, u9Ext:$src2),
3130       "$dst = !cmp.gtu($src1, #$src2)",
3131       [(set (i1 PredRegs:$dst),
3132             (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
3133       Requires<[HasV4T]>;
3134
3135 let isCompare = 1, validSubTargets = HasV4SubT in
3136 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
3137             (ins IntRegs:$src1, u8Imm:$src2),
3138             "$dst = cmpb.eq($src1, #$src2)",
3139             [(set (i1 PredRegs:$dst),
3140                   (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
3141             Requires<[HasV4T]>;
3142
3143 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
3144                        bb:$offset),
3145       (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
3146                 bb:$offset)>,
3147       Requires<[HasV4T]>;
3148
3149 // Pd=cmpb.eq(Rs,Rt)
3150 let isCompare = 1, validSubTargets = HasV4SubT in
3151 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
3152             (ins IntRegs:$src1, IntRegs:$src2),
3153             "$dst = cmpb.eq($src1, $src2)",
3154             [(set (i1 PredRegs:$dst),
3155                   (seteq (and (xor (i32 IntRegs:$src1),
3156                                    (i32 IntRegs:$src2)), 255), 0))]>,
3157             Requires<[HasV4T]>;
3158
3159 // Pd=cmpb.eq(Rs,Rt)
3160 let isCompare = 1, validSubTargets = HasV4SubT in
3161 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
3162             (ins IntRegs:$src1, IntRegs:$src2),
3163             "$dst = cmpb.eq($src1, $src2)",
3164             [(set (i1 PredRegs:$dst),
3165                   (seteq (shl (i32 IntRegs:$src1), (i32 24)),
3166                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
3167             Requires<[HasV4T]>;
3168
3169 // Pd=cmpb.gt(Rs,Rt)
3170 let isCompare = 1, validSubTargets = HasV4SubT in
3171 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
3172             (ins IntRegs:$src1, IntRegs:$src2),
3173             "$dst = cmpb.gt($src1, $src2)",
3174             [(set (i1 PredRegs:$dst),
3175                   (setgt (shl (i32 IntRegs:$src1), (i32 24)),
3176                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
3177             Requires<[HasV4T]>;
3178
3179 // Pd=cmpb.gtu(Rs,#u7)
3180 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3181 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
3182 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
3183             (ins IntRegs:$src1, u7Ext:$src2),
3184             "$dst = cmpb.gtu($src1, #$src2)",
3185             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3186                                               u7ExtPred:$src2))]>,
3187             Requires<[HasV4T]>, ImmRegRel;
3188
3189 // SDNode for converting immediate C to C-1.
3190 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
3191    // Return the byte immediate const-1 as an SDNode.
3192    int32_t imm = N->getSExtValue();
3193    return XformU7ToU7M1Imm(imm);
3194 }]>;
3195
3196 // For the sequence
3197 //   zext( seteq ( and(Rs, 255), u8))
3198 // Generate
3199 //   Pd=cmpb.eq(Rs, #u8)
3200 //   if (Pd.new) Rd=#1
3201 //   if (!Pd.new) Rd=#0
3202 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
3203                                            u8ExtPred:$u8)))),
3204            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3205                                                  (u8ExtPred:$u8))),
3206                                 1, 0))>,
3207            Requires<[HasV4T]>;
3208
3209 // For the sequence
3210 //   zext( setne ( and(Rs, 255), u8))
3211 // Generate
3212 //   Pd=cmpb.eq(Rs, #u8)
3213 //   if (Pd.new) Rd=#0
3214 //   if (!Pd.new) Rd=#1
3215 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
3216                                            u8ExtPred:$u8)))),
3217            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3218                                                  (u8ExtPred:$u8))),
3219                                 0, 1))>,
3220            Requires<[HasV4T]>;
3221
3222 // For the sequence
3223 //   zext( seteq (Rs, and(Rt, 255)))
3224 // Generate
3225 //   Pd=cmpb.eq(Rs, Rt)
3226 //   if (Pd.new) Rd=#1
3227 //   if (!Pd.new) Rd=#0
3228 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
3229                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
3230            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3231                                                       (i32 IntRegs:$Rt))),
3232                                 1, 0))>,
3233            Requires<[HasV4T]>;
3234
3235 // For the sequence
3236 //   zext( setne (Rs, and(Rt, 255)))
3237 // Generate
3238 //   Pd=cmpb.eq(Rs, Rt)
3239 //   if (Pd.new) Rd=#0
3240 //   if (!Pd.new) Rd=#1
3241 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
3242                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
3243            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3244                                                       (i32 IntRegs:$Rt))),
3245                                 0, 1))>,
3246            Requires<[HasV4T]>;
3247
3248 // For the sequence
3249 //   zext( setugt ( and(Rs, 255), u8))
3250 // Generate
3251 //   Pd=cmpb.gtu(Rs, #u8)
3252 //   if (Pd.new) Rd=#1
3253 //   if (!Pd.new) Rd=#0
3254 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
3255                                             u8ExtPred:$u8)))),
3256            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3257                                                   (u8ExtPred:$u8))),
3258                                 1, 0))>,
3259            Requires<[HasV4T]>;
3260
3261 // For the sequence
3262 //   zext( setugt ( and(Rs, 254), u8))
3263 // Generate
3264 //   Pd=cmpb.gtu(Rs, #u8)
3265 //   if (Pd.new) Rd=#1
3266 //   if (!Pd.new) Rd=#0
3267 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
3268                                             u8ExtPred:$u8)))),
3269            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3270                                                   (u8ExtPred:$u8))),
3271                                 1, 0))>,
3272            Requires<[HasV4T]>;
3273
3274 // For the sequence
3275 //   zext( setult ( Rs, Rt))
3276 // Generate
3277 //   Pd=cmp.ltu(Rs, Rt)
3278 //   if (Pd.new) Rd=#1
3279 //   if (!Pd.new) Rd=#0
3280 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3281 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3282            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3283                                               (i32 IntRegs:$Rs))),
3284                                 1, 0))>,
3285            Requires<[HasV4T]>;
3286
3287 // For the sequence
3288 //   zext( setlt ( Rs, Rt))
3289 // Generate
3290 //   Pd=cmp.lt(Rs, Rt)
3291 //   if (Pd.new) Rd=#1
3292 //   if (!Pd.new) Rd=#0
3293 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3294 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3295            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3296                                              (i32 IntRegs:$Rs))),
3297                                 1, 0))>,
3298            Requires<[HasV4T]>;
3299
3300 // For the sequence
3301 //   zext( setugt ( Rs, Rt))
3302 // Generate
3303 //   Pd=cmp.gtu(Rs, Rt)
3304 //   if (Pd.new) Rd=#1
3305 //   if (!Pd.new) Rd=#0
3306 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3307            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3308                                               (i32 IntRegs:$Rt))),
3309                                 1, 0))>,
3310            Requires<[HasV4T]>;
3311
3312 // This pattern interefers with coremark performance, not implementing at this
3313 // time.
3314 // For the sequence
3315 //   zext( setgt ( Rs, Rt))
3316 // Generate
3317 //   Pd=cmp.gt(Rs, Rt)
3318 //   if (Pd.new) Rd=#1
3319 //   if (!Pd.new) Rd=#0
3320
3321 // For the sequence
3322 //   zext( setuge ( Rs, Rt))
3323 // Generate
3324 //   Pd=cmp.ltu(Rs, Rt)
3325 //   if (Pd.new) Rd=#0
3326 //   if (!Pd.new) Rd=#1
3327 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3328 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3329            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3330                                               (i32 IntRegs:$Rs))),
3331                                 0, 1))>,
3332            Requires<[HasV4T]>;
3333
3334 // For the sequence
3335 //   zext( setge ( Rs, Rt))
3336 // Generate
3337 //   Pd=cmp.lt(Rs, Rt)
3338 //   if (Pd.new) Rd=#0
3339 //   if (!Pd.new) Rd=#1
3340 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3341 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3342            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3343                                              (i32 IntRegs:$Rs))),
3344                                 0, 1))>,
3345            Requires<[HasV4T]>;
3346
3347 // For the sequence
3348 //   zext( setule ( Rs, Rt))
3349 // Generate
3350 //   Pd=cmp.gtu(Rs, Rt)
3351 //   if (Pd.new) Rd=#0
3352 //   if (!Pd.new) Rd=#1
3353 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3354            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3355                                               (i32 IntRegs:$Rt))),
3356                                 0, 1))>,
3357            Requires<[HasV4T]>;
3358
3359 // For the sequence
3360 //   zext( setle ( Rs, Rt))
3361 // Generate
3362 //   Pd=cmp.gt(Rs, Rt)
3363 //   if (Pd.new) Rd=#0
3364 //   if (!Pd.new) Rd=#1
3365 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3366            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
3367                                              (i32 IntRegs:$Rt))),
3368                                 0, 1))>,
3369            Requires<[HasV4T]>;
3370
3371 // For the sequence
3372 //   zext( setult ( and(Rs, 255), u8))
3373 // Use the isdigit transformation below
3374
3375 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
3376 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
3377 // The isdigit transformation relies on two 'clever' aspects:
3378 // 1) The data type is unsigned which allows us to eliminate a zero test after
3379 //    biasing the expression by 48. We are depending on the representation of
3380 //    the unsigned types, and semantics.
3381 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
3382 //
3383 // For the C code:
3384 //   retval = ((c>='0') & (c<='9')) ? 1 : 0;
3385 // The code is transformed upstream of llvm into
3386 //   retval = (c-48) < 10 ? 1 : 0;
3387 let AddedComplexity = 139 in
3388 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
3389                                   u7StrictPosImmPred:$src2)))),
3390   (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
3391                                  (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
3392                    0, 1))>,
3393                    Requires<[HasV4T]>;
3394
3395 // Pd=cmpb.gtu(Rs,Rt)
3396 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
3397 InputType = "reg" in
3398 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
3399             (ins IntRegs:$src1, IntRegs:$src2),
3400             "$dst = cmpb.gtu($src1, $src2)",
3401             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3402                                              (and (i32 IntRegs:$src2), 255)))]>,
3403             Requires<[HasV4T]>, ImmRegRel;
3404
3405 // Following instruction is not being extended as it results into the incorrect
3406 // code for negative numbers.
3407
3408 // Signed half compare(.eq) ri.
3409 // Pd=cmph.eq(Rs,#s8)
3410 let isCompare = 1, validSubTargets = HasV4SubT in
3411 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
3412             (ins IntRegs:$src1, s8Imm:$src2),
3413             "$dst = cmph.eq($src1, #$src2)",
3414             [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
3415                                              s8ImmPred:$src2))]>,
3416             Requires<[HasV4T]>;
3417
3418 // Signed half compare(.eq) rr.
3419 // Case 1: xor + and, then compare:
3420 //   r0=xor(r0,r1)
3421 //   r0=and(r0,#0xffff)
3422 //   p0=cmp.eq(r0,#0)
3423 // Pd=cmph.eq(Rs,Rt)
3424 let isCompare = 1, validSubTargets = HasV4SubT in
3425 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
3426             (ins IntRegs:$src1, IntRegs:$src2),
3427             "$dst = cmph.eq($src1, $src2)",
3428             [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
3429                                                        (i32 IntRegs:$src2)),
3430                                                   65535), 0))]>,
3431             Requires<[HasV4T]>;
3432
3433 // Signed half compare(.eq) rr.
3434 // Case 2: shift left 16 bits then compare:
3435 //   r0=asl(r0,16)
3436 //   r1=asl(r1,16)
3437 //   p0=cmp.eq(r0,r1)
3438 // Pd=cmph.eq(Rs,Rt)
3439 let isCompare = 1, validSubTargets = HasV4SubT in
3440 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
3441             (ins IntRegs:$src1, IntRegs:$src2),
3442             "$dst = cmph.eq($src1, $src2)",
3443             [(set (i1 PredRegs:$dst),
3444                   (seteq (shl (i32 IntRegs:$src1), (i32 16)),
3445                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
3446             Requires<[HasV4T]>;
3447
3448 /* Incorrect Pattern -- immediate should be right shifted before being
3449 used in the cmph.gt instruction.
3450 // Signed half compare(.gt) ri.
3451 // Pd=cmph.gt(Rs,#s8)
3452
3453 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
3454 isCompare = 1, validSubTargets = HasV4SubT in
3455 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
3456             (ins IntRegs:$src1, s8Ext:$src2),
3457             "$dst = cmph.gt($src1, #$src2)",
3458             [(set (i1 PredRegs:$dst),
3459                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3460                          s8ExtPred:$src2))]>,
3461             Requires<[HasV4T]>;
3462 */
3463
3464 // Signed half compare(.gt) rr.
3465 // Pd=cmph.gt(Rs,Rt)
3466 let isCompare = 1, validSubTargets = HasV4SubT in
3467 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
3468             (ins IntRegs:$src1, IntRegs:$src2),
3469             "$dst = cmph.gt($src1, $src2)",
3470             [(set (i1 PredRegs:$dst),
3471                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3472                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
3473             Requires<[HasV4T]>;
3474
3475 // Unsigned half compare rr (.gtu).
3476 // Pd=cmph.gtu(Rs,Rt)
3477 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3478 InputType = "reg" in
3479 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
3480             (ins IntRegs:$src1, IntRegs:$src2),
3481             "$dst = cmph.gtu($src1, $src2)",
3482             [(set (i1 PredRegs:$dst),
3483                   (setugt (and (i32 IntRegs:$src1), 65535),
3484                           (and (i32 IntRegs:$src2), 65535)))]>,
3485             Requires<[HasV4T]>, ImmRegRel;
3486
3487 // Unsigned half compare ri (.gtu).
3488 // Pd=cmph.gtu(Rs,#u7)
3489 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3490 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3491 InputType = "imm" in
3492 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
3493             (ins IntRegs:$src1, u7Ext:$src2),
3494             "$dst = cmph.gtu($src1, #$src2)",
3495             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
3496                                               u7ExtPred:$src2))]>,
3497             Requires<[HasV4T]>, ImmRegRel;
3498
3499 let validSubTargets = HasV4SubT in
3500 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
3501     "$dst = !tstbit($src1, $src2)",
3502     [(set (i1 PredRegs:$dst),
3503           (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
3504     Requires<[HasV4T]>;
3505
3506 let validSubTargets = HasV4SubT in
3507 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
3508     "$dst = !tstbit($src1, $src2)",
3509     [(set (i1 PredRegs:$dst),
3510           (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
3511     Requires<[HasV4T]>;
3512
3513 //===----------------------------------------------------------------------===//
3514 // XTYPE/PRED -
3515 //===----------------------------------------------------------------------===//
3516
3517 //Deallocate frame and return.
3518 //    dealloc_return
3519 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
3520   Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
3521   def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
3522             "dealloc_return",
3523             []>,
3524             Requires<[HasV4T]>;
3525 }
3526
3527 // Restore registers and dealloc return function call.
3528 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3529   Defs = [R29, R30, R31, PC] in {
3530   def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
3531                                    (ins calltarget:$dst),
3532              "jump $dst // Restore_and_dealloc_return",
3533              []>,
3534              Requires<[HasV4T]>;
3535 }
3536
3537 // Restore registers and dealloc frame before a tail call.
3538 let isCall = 1, isBarrier = 1,
3539   Defs = [R29, R30, R31, PC] in {
3540   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
3541                                            (ins calltarget:$dst),
3542              "call $dst // Restore_and_dealloc_before_tailcall",
3543              []>,
3544              Requires<[HasV4T]>;
3545 }
3546
3547 // Save registers function call.
3548 let isCall = 1, isBarrier = 1,
3549   Uses = [R29, R31] in {
3550   def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
3551                                (ins calltarget:$dst),
3552              "call $dst // Save_calle_saved_registers",
3553              []>,
3554              Requires<[HasV4T]>;
3555 }
3556
3557 //    if (Ps) dealloc_return
3558 let isReturn = 1, isTerminator = 1,
3559     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3560     isPredicated = 1 in {
3561   def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
3562                            (ins PredRegs:$src1, i32imm:$amt1),
3563             "if ($src1) dealloc_return",
3564             []>,
3565             Requires<[HasV4T]>;
3566 }
3567
3568 //    if (!Ps) dealloc_return
3569 let isReturn = 1, isTerminator = 1,
3570     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3571     isPredicated = 1 in {
3572   def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3573                                                      i32imm:$amt1),
3574             "if (!$src1) dealloc_return",
3575             []>,
3576             Requires<[HasV4T]>;
3577 }
3578
3579 //    if (Ps.new) dealloc_return:nt
3580 let isReturn = 1, isTerminator = 1,
3581     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3582     isPredicated = 1 in {
3583   def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3584                                                      i32imm:$amt1),
3585             "if ($src1.new) dealloc_return:nt",
3586             []>,
3587             Requires<[HasV4T]>;
3588 }
3589
3590 //    if (!Ps.new) dealloc_return:nt
3591 let isReturn = 1, isTerminator = 1,
3592     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3593     isPredicated = 1 in {
3594   def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3595                                                         i32imm:$amt1),
3596             "if (!$src1.new) dealloc_return:nt",
3597             []>,
3598             Requires<[HasV4T]>;
3599 }
3600
3601 //    if (Ps.new) dealloc_return:t
3602 let isReturn = 1, isTerminator = 1,
3603     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3604     isPredicated = 1 in {
3605   def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3606                                                     i32imm:$amt1),
3607             "if ($src1.new) dealloc_return:t",
3608             []>,
3609             Requires<[HasV4T]>;
3610 }
3611
3612 //    if (!Ps.new) dealloc_return:nt
3613 let isReturn = 1, isTerminator = 1,
3614     Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3615     isPredicated = 1 in {
3616   def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3617                                                        i32imm:$amt1),
3618             "if (!$src1.new) dealloc_return:t",
3619             []>,
3620             Requires<[HasV4T]>;
3621 }
3622
3623 // Load/Store with absolute addressing mode
3624 // memw(#u6)=Rt
3625
3626 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3627                            bit isPredNew> {
3628   let PNewValue = !if(isPredNew, "new", "") in
3629   def NAME#_V4 : STInst2<(outs),
3630             (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3631             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3632             ") ")#mnemonic#"(##$absaddr) = $src2",
3633             []>,
3634             Requires<[HasV4T]>;
3635 }
3636
3637 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3638   let PredSense = !if(PredNot, "false", "true") in {
3639     defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3640     // Predicate new
3641     defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3642   }
3643 }
3644
3645 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
3646 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3647   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3648     let opExtendable = 0, isPredicable = 1 in
3649     def NAME#_V4 : STInst2<(outs),
3650             (ins globaladdressExt:$absaddr, RC:$src),
3651             mnemonic#"(##$absaddr) = $src",
3652             []>,
3653             Requires<[HasV4T]>;
3654
3655     let opExtendable = 1, isPredicated = 1 in {
3656       defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
3657       defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
3658     }
3659   }
3660 }
3661
3662 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
3663                            bit isPredNew> {
3664   let PNewValue = !if(isPredNew, "new", "") in
3665   def NAME#_nv_V4 : NVInst_V4<(outs),
3666             (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3667             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3668             ") ")#mnemonic#"(##$absaddr) = $src2.new",
3669             []>,
3670             Requires<[HasV4T]>;
3671 }
3672
3673 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
3674   let PredSense = !if(PredNot, "false", "true") in {
3675     defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
3676     // Predicate new
3677     defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
3678   }
3679 }
3680
3681 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
3682 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
3683   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3684     let opExtendable = 0, isPredicable = 1 in
3685     def NAME#_nv_V4 : NVInst_V4<(outs),
3686             (ins globaladdressExt:$absaddr, RC:$src),
3687             mnemonic#"(##$absaddr) = $src.new",
3688             []>,
3689             Requires<[HasV4T]>;
3690
3691     let opExtendable = 1, isPredicated = 1 in {
3692       defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
3693       defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
3694     }
3695   }
3696 }
3697
3698 let addrMode = Absolute in {
3699     defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
3700                      ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
3701
3702     defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
3703                      ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
3704
3705     defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
3706                      ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
3707
3708   let isNVStorable = 0 in
3709     defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
3710 }
3711
3712 let Predicates = [HasV4T], AddedComplexity = 30 in {
3713 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
3714                         (HexagonCONST32 tglobaladdr:$absaddr)),
3715           (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3716
3717 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
3718                           (HexagonCONST32 tglobaladdr:$absaddr)),
3719           (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3720
3721 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
3722           (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3723
3724 def : Pat<(store (i64 DoubleRegs:$src1),
3725                  (HexagonCONST32 tglobaladdr:$absaddr)),
3726           (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
3727 }
3728
3729 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3730                            bit isPredNew> {
3731   let PNewValue = !if(isPredNew, "new", "") in
3732   def NAME : LDInst2<(outs RC:$dst),
3733             (ins PredRegs:$src1, globaladdressExt:$absaddr),
3734             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3735             ") ")#"$dst = "#mnemonic#"(##$absaddr)",
3736             []>,
3737             Requires<[HasV4T]>;
3738 }
3739
3740 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3741   let PredSense = !if(PredNot, "false", "true") in {
3742     defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3743     // Predicate new
3744     defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3745   }
3746 }
3747
3748 let isExtended = 1, neverHasSideEffects = 1 in
3749 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3750   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3751     let  opExtendable = 1, isPredicable = 1 in
3752     def NAME#_V4 : LDInst2<(outs RC:$dst),
3753             (ins globaladdressExt:$absaddr),
3754             "$dst = "#mnemonic#"(##$absaddr)",
3755             []>,
3756             Requires<[HasV4T]>;
3757
3758     let opExtendable = 2, isPredicated = 1 in {
3759       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3760       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3761     }
3762   }
3763 }
3764
3765 let addrMode = Absolute in {
3766     defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3767     defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
3768     defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3769     defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
3770     defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
3771     defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
3772 }
3773
3774 let Predicates = [HasV4T], AddedComplexity  = 30 in
3775 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3776           (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3777
3778 let Predicates = [HasV4T], AddedComplexity=30 in
3779 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3780           (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3781
3782 let Predicates = [HasV4T], AddedComplexity=30 in
3783 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3784           (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3785
3786 let Predicates = [HasV4T], AddedComplexity=30 in
3787 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3788           (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3789
3790 let Predicates = [HasV4T], AddedComplexity=30 in
3791 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3792           (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
3793
3794 // Transfer global address into a register
3795 let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
3796 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
3797            "$dst = ##$src1",
3798            [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3799            Requires<[HasV4T]>;
3800
3801 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3802 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3803                            (ins PredRegs:$src1, globaladdress:$src2),
3804            "if($src1) $dst = ##$src2",
3805            []>,
3806            Requires<[HasV4T]>;
3807
3808 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3809 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3810                               (ins PredRegs:$src1, globaladdress:$src2),
3811            "if(!$src1) $dst = ##$src2",
3812            []>,
3813            Requires<[HasV4T]>;
3814
3815 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3816 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3817                              (ins PredRegs:$src1, globaladdress:$src2),
3818            "if($src1.new) $dst = ##$src2",
3819            []>,
3820            Requires<[HasV4T]>;
3821
3822 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3823 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3824                                 (ins PredRegs:$src1, globaladdress:$src2),
3825            "if(!$src1.new) $dst = ##$src2",
3826            []>,
3827            Requires<[HasV4T]>;
3828
3829 let AddedComplexity = 50, Predicates = [HasV4T] in
3830 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3831            (TFRI_V4 tglobaladdr:$src1)>;
3832
3833
3834 // Load - Indirect with long offset: These instructions take global address
3835 // as an operand
3836 let AddedComplexity = 10 in
3837 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3838             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3839             "$dst=memd($src1<<#$src2+##$offset)",
3840             [(set (i64 DoubleRegs:$dst),
3841                   (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3842                         (HexagonCONST32 tglobaladdr:$offset))))]>,
3843             Requires<[HasV4T]>;
3844
3845 let AddedComplexity = 10 in
3846 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3847   def _lo_V4 : LDInst<(outs IntRegs:$dst),
3848             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3849             !strconcat("$dst = ",
3850             !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3851             [(set IntRegs:$dst,
3852                   (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3853                           (HexagonCONST32 tglobaladdr:$offset)))))]>,
3854             Requires<[HasV4T]>;
3855 }
3856
3857 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3858 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3859 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3860 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3861 defm LDriw_ind : LD_indirect_lo<"memw", load>;
3862
3863 // Store - Indirect with long offset: These instructions take global address
3864 // as an operand
3865 let AddedComplexity = 10 in
3866 def STrid_ind_lo_V4 : STInst<(outs),
3867             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3868                  DoubleRegs:$src4),
3869             "memd($src1<<#$src2+#$src3) = $src4",
3870             [(store (i64 DoubleRegs:$src4),
3871                  (add (shl IntRegs:$src1, u2ImmPred:$src2),
3872                       (HexagonCONST32 tglobaladdr:$src3)))]>,
3873              Requires<[HasV4T]>;
3874
3875 let AddedComplexity = 10 in
3876 multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
3877   def _lo_V4 : STInst<(outs),
3878             (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3879                  IntRegs:$src4),
3880             !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
3881             [(OpNode (i32 IntRegs:$src4),
3882                  (add (shl IntRegs:$src1, u2ImmPred:$src2),
3883                       (HexagonCONST32 tglobaladdr:$src3)))]>,
3884              Requires<[HasV4T]>;
3885 }
3886
3887 defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
3888 defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
3889 defm STriw_ind : ST_indirect_lo<"memw", store>;
3890
3891 // Store - absolute addressing mode: These instruction take constant
3892 // value as the extended operand.
3893 multiclass ST_absimm<string OpcStr> {
3894 let isExtended = 1, opExtendable = 0, isPredicable = 1,
3895 validSubTargets = HasV4SubT in
3896   def _abs_V4 : STInst2<(outs),
3897             (ins u0AlwaysExt:$src1, IntRegs:$src2),
3898             !strconcat(OpcStr, "(##$src1) = $src2"),
3899             []>,
3900             Requires<[HasV4T]>;
3901
3902 let isExtended = 1, opExtendable = 1, isPredicated = 1,
3903 validSubTargets = HasV4SubT in {
3904   def _abs_cPt_V4 : STInst2<(outs),
3905             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3906             !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3907             []>,
3908             Requires<[HasV4T]>;
3909
3910   def _abs_cNotPt_V4 : STInst2<(outs),
3911             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3912             !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3913             []>,
3914             Requires<[HasV4T]>;
3915
3916   def _abs_cdnPt_V4 : STInst2<(outs),
3917             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3918             !strconcat("if ($src1.new)",
3919             !strconcat(OpcStr, "(##$src2) = $src3")),
3920             []>,
3921             Requires<[HasV4T]>;
3922
3923   def _abs_cdnNotPt_V4 : STInst2<(outs),
3924             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3925             !strconcat("if (!$src1.new)",
3926             !strconcat(OpcStr, "(##$src2) = $src3")),
3927             []>,
3928             Requires<[HasV4T]>;
3929 }
3930
3931 let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
3932 validSubTargets = HasV4SubT in
3933   def _abs_nv_V4 : NVInst_V4<(outs),
3934             (ins u0AlwaysExt:$src1, IntRegs:$src2),
3935             !strconcat(OpcStr, "(##$src1) = $src2.new"),
3936             []>,
3937             Requires<[HasV4T]>;
3938
3939 let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
3940 isNVStore = 1, validSubTargets = HasV4SubT in {
3941   def _abs_cPt_nv_V4 : NVInst_V4<(outs),
3942             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3943             !strconcat("if ($src1)",
3944             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3945             []>,
3946             Requires<[HasV4T]>;
3947
3948   def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
3949             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3950             !strconcat("if (!$src1)",
3951             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3952             []>,
3953             Requires<[HasV4T]>;
3954
3955   def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
3956             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3957             !strconcat("if ($src1.new)",
3958             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3959             []>,
3960             Requires<[HasV4T]>;
3961
3962   def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
3963             (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3964             !strconcat("if (!$src1.new)",
3965             !strconcat(OpcStr, "(##$src2) = $src3.new")),
3966             []>,
3967             Requires<[HasV4T]>;
3968 }
3969 }
3970
3971 defm STrib_imm : ST_absimm<"memb">;
3972 defm STrih_imm : ST_absimm<"memh">;
3973 defm STriw_imm : ST_absimm<"memw">;
3974
3975 let Predicates = [HasV4T], AddedComplexity  = 30 in {
3976 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3977           (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3978
3979 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3980           (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3981
3982 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3983           (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3984 }
3985
3986 // Load - absolute addressing mode: These instruction take constant
3987 // value as the extended operand
3988
3989 multiclass LD_absimm<string OpcStr> {
3990 let isExtended = 1, opExtendable = 1, isPredicable = 1,
3991 validSubTargets = HasV4SubT in
3992   def _abs_V4 : LDInst2<(outs IntRegs:$dst),
3993             (ins u0AlwaysExt:$src),
3994             !strconcat("$dst = ",
3995             !strconcat(OpcStr, "(##$src)")),
3996             []>,
3997             Requires<[HasV4T]>;
3998
3999 let isExtended = 1, opExtendable = 2, isPredicated = 1,
4000 validSubTargets = HasV4SubT in {
4001   def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
4002             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4003             !strconcat("if ($src1) $dst = ",
4004             !strconcat(OpcStr, "(##$src2)")),
4005             []>,
4006             Requires<[HasV4T]>;
4007
4008   def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4009             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4010             !strconcat("if (!$src1) $dst = ",
4011             !strconcat(OpcStr, "(##$src2)")),
4012             []>,
4013             Requires<[HasV4T]>;
4014
4015   def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
4016             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4017             !strconcat("if ($src1.new) $dst = ",
4018             !strconcat(OpcStr, "(##$src2)")),
4019             []>,
4020             Requires<[HasV4T]>;
4021
4022   def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4023             (ins PredRegs:$src1, u0AlwaysExt:$src2),
4024             !strconcat("if (!$src1.new) $dst = ",
4025             !strconcat(OpcStr, "(##$src2)")),
4026             []>,
4027             Requires<[HasV4T]>;
4028 }
4029 }
4030
4031 defm LDrib_imm  : LD_absimm<"memb">;
4032 defm LDriub_imm : LD_absimm<"memub">;
4033 defm LDrih_imm  : LD_absimm<"memh">;
4034 defm LDriuh_imm : LD_absimm<"memuh">;
4035 defm LDriw_imm  : LD_absimm<"memw">;
4036
4037 let Predicates = [HasV4T], AddedComplexity  = 30 in {
4038 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
4039           (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
4040
4041 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
4042           (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
4043
4044 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
4045           (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
4046
4047 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
4048           (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
4049
4050 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
4051           (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
4052 }
4053
4054 // Indexed store double word - global address.
4055 // memw(Rs+#u6:2)=#S8
4056 let AddedComplexity = 10 in
4057 def STriw_offset_ext_V4 : STInst<(outs),
4058             (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
4059             "memw($src1+#$src2) = ##$src3",
4060             [(store (HexagonCONST32 tglobaladdr:$src3),
4061                     (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
4062             Requires<[HasV4T]>;
4063
4064
4065 // Indexed store double word - global address.
4066 // memw(Rs+#u6:2)=#S8
4067 let AddedComplexity = 10 in
4068 def STrih_offset_ext_V4 : STInst<(outs),
4069             (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
4070             "memh($src1+#$src2) = ##$src3",
4071             [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
4072                     (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
4073             Requires<[HasV4T]>;
4074 // Map from store(globaladdress + x) -> memd(#foo + x)
4075 let AddedComplexity = 100 in
4076 def : Pat<(store (i64 DoubleRegs:$src1),
4077                  FoldGlobalAddrGP:$addr),
4078           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4079           Requires<[HasV4T]>;
4080
4081 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
4082                            (i64 DoubleRegs:$src1)),
4083           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4084           Requires<[HasV4T]>;
4085
4086 // Map from store(globaladdress + x) -> memb(#foo + x)
4087 let AddedComplexity = 100 in
4088 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4089           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4090             Requires<[HasV4T]>;
4091
4092 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4093           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4094             Requires<[HasV4T]>;
4095
4096 // Map from store(globaladdress + x) -> memh(#foo + x)
4097 let AddedComplexity = 100 in
4098 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4099           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4100             Requires<[HasV4T]>;
4101
4102 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4103           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4104             Requires<[HasV4T]>;
4105
4106 // Map from store(globaladdress + x) -> memw(#foo + x)
4107 let AddedComplexity = 100 in
4108 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4109           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4110            Requires<[HasV4T]>;
4111
4112 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4113           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4114             Requires<[HasV4T]>;
4115
4116 // Map from load(globaladdress + x) -> memd(#foo + x)
4117 let AddedComplexity = 100 in
4118 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
4119           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4120            Requires<[HasV4T]>;
4121
4122 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
4123           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4124            Requires<[HasV4T]>;
4125
4126 // Map from load(globaladdress + x) -> memb(#foo + x)
4127 let AddedComplexity = 100 in
4128 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
4129           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4130            Requires<[HasV4T]>;
4131
4132 // Map from load(globaladdress + x) -> memb(#foo + x)
4133 let AddedComplexity = 100 in
4134 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
4135           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4136            Requires<[HasV4T]>;
4137
4138 //let AddedComplexity = 100 in
4139 let AddedComplexity = 100 in
4140 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
4141           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4142            Requires<[HasV4T]>;
4143
4144 // Map from load(globaladdress + x) -> memh(#foo + x)
4145 let AddedComplexity = 100 in
4146 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
4147           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4148            Requires<[HasV4T]>;
4149
4150 // Map from load(globaladdress + x) -> memuh(#foo + x)
4151 let AddedComplexity = 100 in
4152 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
4153           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4154            Requires<[HasV4T]>;
4155
4156 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
4157           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4158            Requires<[HasV4T]>;
4159
4160 // Map from load(globaladdress + x) -> memub(#foo + x)
4161 let AddedComplexity = 100 in
4162 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
4163           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4164            Requires<[HasV4T]>;
4165
4166 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
4167           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4168            Requires<[HasV4T]>;
4169
4170 // Map from load(globaladdress + x) -> memw(#foo + x)
4171 let AddedComplexity = 100 in
4172 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
4173           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4174            Requires<[HasV4T]>;
4175
4176 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
4177           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4178            Requires<[HasV4T]>;
4179