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