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