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