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