HexagonInstrInfoV4.td revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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 isTaken>
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(isTaken, "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 isBrTaken = !if(isTaken, "true", "false");
1023      let isPredicatedFalse = isNegCond;
1024
1025      let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
1026      let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
1027
1028      let IClass = 0b0010;
1029      let Inst{26} = 0b0;
1030      let Inst{25-23} = majOp;
1031      let Inst{22} = isNegCond;
1032      let Inst{18-16} = Ns;
1033      let Inst{13} = isTaken;
1034      let Inst{12-8} = RegOp;
1035      let Inst{21-20} = offset{10-9};
1036      let Inst{7-1} = offset{8-2};
1037}
1038
1039
1040multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
1041                       bit isNegCond> {
1042  // Branch not taken:
1043  def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
1044  // Branch taken:
1045  def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
1046}
1047
1048// NvOpNum = 0 -> First Operand is a new-value Register
1049// NvOpNum = 1 -> Second Operand is a new-value Register
1050
1051multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
1052                       bit NvOpNum> {
1053  let BaseOpcode = BaseOp#_NVJ in {
1054    defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
1055    defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
1056  }
1057}
1058
1059// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
1060// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
1061// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
1062// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
1063// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
1064
1065let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1066  Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
1067  defm CMPEQrr  : NVJrr_base<"cmp.eq",  "CMPEQ",  0b000, 0>, PredRel;
1068  defm CMPGTrr  : NVJrr_base<"cmp.gt",  "CMPGT",  0b001, 0>, PredRel;
1069  defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
1070  defm CMPLTrr  : NVJrr_base<"cmp.gt",  "CMPLT",  0b011, 1>, PredRel;
1071  defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
1072}
1073
1074//===----------------------------------------------------------------------===//
1075// multiclass/template class for the new-value compare jumps instruction
1076// with a register and an unsigned immediate (U5) operand.
1077//===----------------------------------------------------------------------===//
1078
1079let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
1080class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
1081                         bit isTaken>
1082  : NVInst_V4<(outs),
1083    (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1084    "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
1085    #!if(isTaken, "t","nt")#" $offset",
1086    []>, Requires<[HasV4T]> {
1087
1088      let isPredicatedFalse = isNegCond;
1089      let isBrTaken = !if(isTaken, "true", "false");
1090
1091      bits<3> src1;
1092      bits<5> src2;
1093      bits<11> offset;
1094
1095      let IClass = 0b0010;
1096      let Inst{26} = 0b1;
1097      let Inst{25-23} = majOp;
1098      let Inst{22} = isNegCond;
1099      let Inst{18-16} = src1;
1100      let Inst{13} = isTaken;
1101      let Inst{12-8} = src2;
1102      let Inst{21-20} = offset{10-9};
1103      let Inst{7-1} = offset{8-2};
1104}
1105
1106multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
1107  // Branch not taken:
1108  def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
1109  // Branch taken:
1110  def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
1111}
1112
1113multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
1114  let BaseOpcode = BaseOp#_NVJri in {
1115    defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
1116    defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
1117  }
1118}
1119
1120// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2
1121// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2
1122// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
1123
1124let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
1125  Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
1126  defm CMPEQri  : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
1127  defm CMPGTri  : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
1128  defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
1129}
1130
1131//===----------------------------------------------------------------------===//
1132// multiclass/template class for the new-value compare jumps instruction
1133// with a register and an hardcoded 0/-1 immediate value.
1134//===----------------------------------------------------------------------===//
1135
1136let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
1137class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
1138                            bit isNegCond, bit isTaken>
1139  : NVInst_V4<(outs),
1140    (ins IntRegs:$src1, brtarget:$offset),
1141    "if ("#!if(isNegCond, "!","")#mnemonic
1142    #"($src1.new, #"#ImmVal#")) jump:"
1143    #!if(isTaken, "t","nt")#" $offset",
1144    []>, Requires<[HasV4T]> {
1145
1146      let isPredicatedFalse = isNegCond;
1147      let isBrTaken = !if(isTaken, "true", "false");
1148
1149      bits<3> src1;
1150      bits<11> offset;
1151      let IClass = 0b0010;
1152      let Inst{26} = 0b1;
1153      let Inst{25-23} = majOp;
1154      let Inst{22} = isNegCond;
1155      let Inst{18-16} = src1;
1156      let Inst{13} = isTaken;
1157      let Inst{21-20} = offset{10-9};
1158      let Inst{7-1} = offset{8-2};
1159}
1160
1161multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
1162                             bit isNegCond> {
1163  // Branch not taken:
1164  def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
1165  // Branch taken:
1166  def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
1167}
1168
1169multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
1170                             string ImmVal> {
1171  let BaseOpcode = BaseOp#_NVJ_ConstImm in {
1172  defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
1173  defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
1174  }
1175}
1176
1177// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2
1178// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2
1179// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
1180
1181let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
1182  Defs = [PC], neverHasSideEffects = 1 in {
1183  defm TSTBIT0  : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
1184  defm CMPEQn1  : NVJ_ConstImm_base<"cmp.eq", "CMPEQ",  0b100, "-1">, PredRel;
1185  defm CMPGTn1  : NVJ_ConstImm_base<"cmp.gt", "CMPGT",  0b101, "-1">, PredRel;
1186}
1187
1188//===----------------------------------------------------------------------===//
1189// XTYPE/ALU +
1190//===----------------------------------------------------------------------===//
1191
1192//  Add and accumulate.
1193//  Rd=add(Rs,add(Ru,#s6))
1194let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
1195validSubTargets = HasV4SubT in
1196def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
1197          (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
1198          "$dst = add($src1, add($src2, #$src3))",
1199          [(set (i32 IntRegs:$dst),
1200           (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
1201                                          s6_16ExtPred:$src3)))]>,
1202          Requires<[HasV4T]>;
1203
1204//  Rd=add(Rs,sub(#s6,Ru))
1205let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
1206validSubTargets = HasV4SubT in
1207def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
1208          (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
1209          "$dst = add($src1, sub(#$src2, $src3))",
1210          [(set (i32 IntRegs:$dst),
1211           (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
1212                                          (i32 IntRegs:$src3))))]>,
1213          Requires<[HasV4T]>;
1214
1215// Generates the same instruction as ADDr_SUBri_V4 but matches different
1216// pattern.
1217//  Rd=add(Rs,sub(#s6,Ru))
1218let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
1219validSubTargets = HasV4SubT in
1220def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
1221          (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
1222          "$dst = add($src1, sub(#$src2, $src3))",
1223          [(set (i32 IntRegs:$dst),
1224                (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
1225                     (i32 IntRegs:$src3)))]>,
1226          Requires<[HasV4T]>;
1227
1228
1229//  Add or subtract doublewords with carry.
1230//TODO:
1231//  Rdd=add(Rss,Rtt,Px):carry
1232//TODO:
1233//  Rdd=sub(Rss,Rtt,Px):carry
1234
1235
1236//  Logical doublewords.
1237//  Rdd=and(Rtt,~Rss)
1238let validSubTargets = HasV4SubT in
1239def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
1240          (ins DoubleRegs:$src1, DoubleRegs:$src2),
1241          "$dst = and($src1, ~$src2)",
1242          [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
1243                                      (not (i64 DoubleRegs:$src2))))]>,
1244          Requires<[HasV4T]>;
1245
1246//  Rdd=or(Rtt,~Rss)
1247let validSubTargets = HasV4SubT in
1248def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
1249          (ins DoubleRegs:$src1, DoubleRegs:$src2),
1250          "$dst = or($src1, ~$src2)",
1251          [(set (i64 DoubleRegs:$dst),
1252           (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
1253          Requires<[HasV4T]>;
1254
1255
1256//  Logical-logical doublewords.
1257//  Rxx^=xor(Rss,Rtt)
1258let validSubTargets = HasV4SubT in
1259def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
1260          (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
1261          "$dst ^= xor($src2, $src3)",
1262          [(set (i64 DoubleRegs:$dst),
1263           (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
1264                                             (i64 DoubleRegs:$src3))))],
1265          "$src1 = $dst">,
1266          Requires<[HasV4T]>;
1267
1268
1269// Logical-logical words.
1270// Rx=or(Ru,and(Rx,#s10))
1271let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1272validSubTargets = HasV4SubT in
1273def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
1274            (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1275            "$dst = or($src1, and($src2, #$src3))",
1276            [(set (i32 IntRegs:$dst),
1277                  (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1278                                                s10ExtPred:$src3)))],
1279            "$src2 = $dst">,
1280            Requires<[HasV4T]>;
1281
1282// Rx[&|^]=and(Rs,Rt)
1283// Rx&=and(Rs,Rt)
1284let validSubTargets = HasV4SubT in
1285def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1286            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1287            "$dst &= and($src2, $src3)",
1288            [(set (i32 IntRegs:$dst),
1289                  (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1290                                                 (i32 IntRegs:$src3))))],
1291            "$src1 = $dst">,
1292            Requires<[HasV4T]>;
1293
1294// Rx|=and(Rs,Rt)
1295let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
1296def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1297            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1298            "$dst |= and($src2, $src3)",
1299            [(set (i32 IntRegs:$dst),
1300                  (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1301                                                (i32 IntRegs:$src3))))],
1302            "$src1 = $dst">,
1303            Requires<[HasV4T]>, ImmRegRel;
1304
1305// Rx^=and(Rs,Rt)
1306let validSubTargets = HasV4SubT in
1307def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
1308            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1309            "$dst ^= and($src2, $src3)",
1310            [(set (i32 IntRegs:$dst),
1311             (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1312                                            (i32 IntRegs:$src3))))],
1313            "$src1 = $dst">,
1314            Requires<[HasV4T]>;
1315
1316// Rx[&|^]=and(Rs,~Rt)
1317// Rx&=and(Rs,~Rt)
1318let validSubTargets = HasV4SubT in
1319def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1320            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1321            "$dst &= and($src2, ~$src3)",
1322            [(set (i32 IntRegs:$dst),
1323                  (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1324                                                 (not (i32 IntRegs:$src3)))))],
1325            "$src1 = $dst">,
1326            Requires<[HasV4T]>;
1327
1328// Rx|=and(Rs,~Rt)
1329let validSubTargets = HasV4SubT in
1330def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1331            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1332            "$dst |= and($src2, ~$src3)",
1333            [(set (i32 IntRegs:$dst),
1334             (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1335                                           (not (i32 IntRegs:$src3)))))],
1336            "$src1 = $dst">,
1337            Requires<[HasV4T]>;
1338
1339// Rx^=and(Rs,~Rt)
1340let validSubTargets = HasV4SubT in
1341def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
1342            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1343            "$dst ^= and($src2, ~$src3)",
1344            [(set (i32 IntRegs:$dst),
1345             (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1346                                            (not (i32 IntRegs:$src3)))))],
1347            "$src1 = $dst">,
1348            Requires<[HasV4T]>;
1349
1350// Rx[&|^]=or(Rs,Rt)
1351// Rx&=or(Rs,Rt)
1352let validSubTargets = HasV4SubT in
1353def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1354            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1355            "$dst &= or($src2, $src3)",
1356            [(set (i32 IntRegs:$dst),
1357                  (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1358                                                (i32 IntRegs:$src3))))],
1359            "$src1 = $dst">,
1360            Requires<[HasV4T]>;
1361
1362// Rx|=or(Rs,Rt)
1363let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
1364def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1365            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1366            "$dst |= or($src2, $src3)",
1367            [(set (i32 IntRegs:$dst),
1368                  (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1369                                               (i32 IntRegs:$src3))))],
1370            "$src1 = $dst">,
1371            Requires<[HasV4T]>, ImmRegRel;
1372
1373// Rx^=or(Rs,Rt)
1374let validSubTargets = HasV4SubT in
1375def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1376            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1377            "$dst ^= or($src2, $src3)",
1378            [(set (i32 IntRegs:$dst),
1379             (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
1380                                           (i32 IntRegs:$src3))))],
1381            "$src1 = $dst">,
1382            Requires<[HasV4T]>;
1383
1384// Rx[&|^]=xor(Rs,Rt)
1385// Rx&=xor(Rs,Rt)
1386let validSubTargets = HasV4SubT in
1387def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1388            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1389            "$dst &= xor($src2, $src3)",
1390            [(set (i32 IntRegs:$dst),
1391                  (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1392                                                 (i32 IntRegs:$src3))))],
1393            "$src1 = $dst">,
1394            Requires<[HasV4T]>;
1395
1396// Rx|=xor(Rs,Rt)
1397let validSubTargets = HasV4SubT in
1398def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1399            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1400            "$dst |= xor($src2, $src3)",
1401            [(set (i32 IntRegs:$dst),
1402                  (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1403                                                 (i32 IntRegs:$src3))))],
1404            "$src1 = $dst">,
1405            Requires<[HasV4T]>;
1406
1407// Rx^=xor(Rs,Rt)
1408let validSubTargets = HasV4SubT in
1409def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
1410            (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
1411            "$dst ^= xor($src2, $src3)",
1412            [(set (i32 IntRegs:$dst),
1413             (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
1414                                            (i32 IntRegs:$src3))))],
1415            "$src1 = $dst">,
1416            Requires<[HasV4T]>;
1417
1418// Rx|=and(Rs,#s10)
1419let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1420validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
1421def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
1422            (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1423            "$dst |= and($src2, #$src3)",
1424            [(set (i32 IntRegs:$dst),
1425                  (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1426                                                s10ExtPred:$src3)))],
1427            "$src1 = $dst">,
1428            Requires<[HasV4T]>, ImmRegRel;
1429
1430// Rx|=or(Rs,#s10)
1431let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
1432validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
1433def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
1434            (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
1435            "$dst |= or($src2, #$src3)",
1436            [(set (i32 IntRegs:$dst),
1437                  (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
1438                                                s10ExtPred:$src3)))],
1439            "$src1 = $dst">,
1440            Requires<[HasV4T]>, ImmRegRel;
1441
1442
1443//    Modulo wrap
1444//        Rd=modwrap(Rs,Rt)
1445//    Round
1446//        Rd=cround(Rs,#u5)
1447//        Rd=cround(Rs,Rt)
1448//        Rd=round(Rs,#u5)[:sat]
1449//        Rd=round(Rs,Rt)[:sat]
1450//    Vector reduce add unsigned halfwords
1451//        Rd=vraddh(Rss,Rtt)
1452//    Vector add bytes
1453//        Rdd=vaddb(Rss,Rtt)
1454//    Vector conditional negate
1455//        Rdd=vcnegh(Rss,Rt)
1456//        Rxx+=vrcnegh(Rss,Rt)
1457//    Vector maximum bytes
1458//        Rdd=vmaxb(Rtt,Rss)
1459//    Vector reduce maximum halfwords
1460//        Rxx=vrmaxh(Rss,Ru)
1461//        Rxx=vrmaxuh(Rss,Ru)
1462//    Vector reduce maximum words
1463//        Rxx=vrmaxuw(Rss,Ru)
1464//        Rxx=vrmaxw(Rss,Ru)
1465//    Vector minimum bytes
1466//        Rdd=vminb(Rtt,Rss)
1467//    Vector reduce minimum halfwords
1468//        Rxx=vrminh(Rss,Ru)
1469//        Rxx=vrminuh(Rss,Ru)
1470//    Vector reduce minimum words
1471//        Rxx=vrminuw(Rss,Ru)
1472//        Rxx=vrminw(Rss,Ru)
1473//    Vector subtract bytes
1474//        Rdd=vsubb(Rss,Rtt)
1475
1476//===----------------------------------------------------------------------===//
1477// XTYPE/ALU -
1478//===----------------------------------------------------------------------===//
1479
1480
1481//===----------------------------------------------------------------------===//
1482// XTYPE/MPY +
1483//===----------------------------------------------------------------------===//
1484
1485// Multiply and user lower result.
1486// Rd=add(#u6,mpyi(Rs,#U6))
1487let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
1488validSubTargets = HasV4SubT in
1489def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
1490            (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
1491            "$dst = add(#$src1, mpyi($src2, #$src3))",
1492            [(set (i32 IntRegs:$dst),
1493                  (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
1494                       u6ExtPred:$src1))]>,
1495            Requires<[HasV4T]>;
1496
1497// Rd=add(##,mpyi(Rs,#U6))
1498def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
1499                     (HexagonCONST32 tglobaladdr:$src1)),
1500           (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
1501                               u6ImmPred:$src3))>;
1502
1503// Rd=add(#u6,mpyi(Rs,Rt))
1504let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
1505validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
1506def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
1507            (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
1508            "$dst = add(#$src1, mpyi($src2, $src3))",
1509            [(set (i32 IntRegs:$dst),
1510                  (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1511                       u6ExtPred:$src1))]>,
1512            Requires<[HasV4T]>, ImmRegRel;
1513
1514// Rd=add(##,mpyi(Rs,Rt))
1515def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
1516                     (HexagonCONST32 tglobaladdr:$src1)),
1517           (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
1518                               IntRegs:$src3))>;
1519
1520// Rd=add(Ru,mpyi(#u6:2,Rs))
1521let validSubTargets = HasV4SubT in
1522def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
1523            (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
1524            "$dst = add($src1, mpyi(#$src2, $src3))",
1525            [(set (i32 IntRegs:$dst),
1526             (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
1527                                            u6_2ImmPred:$src2)))]>,
1528            Requires<[HasV4T]>;
1529
1530// Rd=add(Ru,mpyi(Rs,#u6))
1531let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
1532validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
1533def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
1534            (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
1535            "$dst = add($src1, mpyi($src2, #$src3))",
1536            [(set (i32 IntRegs:$dst),
1537                  (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1538                                                 u6ExtPred:$src3)))]>,
1539            Requires<[HasV4T]>, ImmRegRel;
1540
1541// Rx=add(Ru,mpyi(Rx,Rs))
1542let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
1543def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
1544            (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
1545            "$dst = add($src1, mpyi($src2, $src3))",
1546            [(set (i32 IntRegs:$dst),
1547             (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
1548                                            (i32 IntRegs:$src3))))],
1549            "$src2 = $dst">,
1550            Requires<[HasV4T]>, ImmRegRel;
1551
1552
1553// Polynomial multiply words
1554// Rdd=pmpyw(Rs,Rt)
1555// Rxx^=pmpyw(Rs,Rt)
1556
1557// Vector reduce multiply word by signed half (32x16)
1558// Rdd=vrmpyweh(Rss,Rtt)[:<<1]
1559// Rdd=vrmpywoh(Rss,Rtt)[:<<1]
1560// Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
1561// Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
1562
1563// Multiply and use upper result
1564// Rd=mpy(Rs,Rt.H):<<1:sat
1565// Rd=mpy(Rs,Rt.L):<<1:sat
1566// Rd=mpy(Rs,Rt):<<1
1567// Rd=mpy(Rs,Rt):<<1:sat
1568// Rd=mpysu(Rs,Rt)
1569// Rx+=mpy(Rs,Rt):<<1:sat
1570// Rx-=mpy(Rs,Rt):<<1:sat
1571
1572// Vector multiply bytes
1573// Rdd=vmpybsu(Rs,Rt)
1574// Rdd=vmpybu(Rs,Rt)
1575// Rxx+=vmpybsu(Rs,Rt)
1576// Rxx+=vmpybu(Rs,Rt)
1577
1578// Vector polynomial multiply halfwords
1579// Rdd=vpmpyh(Rs,Rt)
1580// Rxx^=vpmpyh(Rs,Rt)
1581
1582//===----------------------------------------------------------------------===//
1583// XTYPE/MPY -
1584//===----------------------------------------------------------------------===//
1585
1586
1587//===----------------------------------------------------------------------===//
1588// XTYPE/SHIFT +
1589//===----------------------------------------------------------------------===//
1590
1591// Shift by immediate and accumulate.
1592// Rx=add(#u8,asl(Rx,#U5))
1593let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1594validSubTargets = HasV4SubT in
1595def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1596            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1597            "$dst = add(#$src1, asl($src2, #$src3))",
1598            [(set (i32 IntRegs:$dst),
1599                  (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1600                       u8ExtPred:$src1))],
1601            "$src2 = $dst">,
1602            Requires<[HasV4T]>;
1603
1604// Rx=add(#u8,lsr(Rx,#U5))
1605let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1606validSubTargets = HasV4SubT in
1607def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1608            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1609            "$dst = add(#$src1, lsr($src2, #$src3))",
1610            [(set (i32 IntRegs:$dst),
1611                  (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1612                       u8ExtPred:$src1))],
1613            "$src2 = $dst">,
1614            Requires<[HasV4T]>;
1615
1616// Rx=sub(#u8,asl(Rx,#U5))
1617let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1618validSubTargets = HasV4SubT in
1619def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1620            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1621            "$dst = sub(#$src1, asl($src2, #$src3))",
1622            [(set (i32 IntRegs:$dst),
1623                  (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1624                       u8ExtPred:$src1))],
1625            "$src2 = $dst">,
1626            Requires<[HasV4T]>;
1627
1628// Rx=sub(#u8,lsr(Rx,#U5))
1629let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1630validSubTargets = HasV4SubT in
1631def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1632            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1633            "$dst = sub(#$src1, lsr($src2, #$src3))",
1634            [(set (i32 IntRegs:$dst),
1635                  (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1636                       u8ExtPred:$src1))],
1637            "$src2 = $dst">,
1638            Requires<[HasV4T]>;
1639
1640
1641//Shift by immediate and logical.
1642//Rx=and(#u8,asl(Rx,#U5))
1643let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1644validSubTargets = HasV4SubT in
1645def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1646            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1647            "$dst = and(#$src1, asl($src2, #$src3))",
1648            [(set (i32 IntRegs:$dst),
1649                  (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1650                       u8ExtPred:$src1))],
1651            "$src2 = $dst">,
1652            Requires<[HasV4T]>;
1653
1654//Rx=and(#u8,lsr(Rx,#U5))
1655let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1656validSubTargets = HasV4SubT in
1657def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1658            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1659            "$dst = and(#$src1, lsr($src2, #$src3))",
1660            [(set (i32 IntRegs:$dst),
1661                  (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1662                       u8ExtPred:$src1))],
1663            "$src2 = $dst">,
1664            Requires<[HasV4T]>;
1665
1666//Rx=or(#u8,asl(Rx,#U5))
1667let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1668AddedComplexity = 30, validSubTargets = HasV4SubT in
1669def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
1670            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1671            "$dst = or(#$src1, asl($src2, #$src3))",
1672            [(set (i32 IntRegs:$dst),
1673                  (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
1674                      u8ExtPred:$src1))],
1675            "$src2 = $dst">,
1676            Requires<[HasV4T]>;
1677
1678//Rx=or(#u8,lsr(Rx,#U5))
1679let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
1680AddedComplexity = 30, validSubTargets = HasV4SubT in
1681def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
1682            (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
1683            "$dst = or(#$src1, lsr($src2, #$src3))",
1684            [(set (i32 IntRegs:$dst),
1685                  (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
1686                      u8ExtPred:$src1))],
1687            "$src2 = $dst">,
1688            Requires<[HasV4T]>;
1689
1690
1691//Shift by register.
1692//Rd=lsl(#s6,Rt)
1693let validSubTargets = HasV4SubT in {
1694def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
1695            "$dst = lsl(#$src1, $src2)",
1696            [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
1697                                           (i32 IntRegs:$src2)))]>,
1698            Requires<[HasV4T]>;
1699
1700
1701//Shift by register and logical.
1702//Rxx^=asl(Rss,Rt)
1703def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1704            (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1705            "$dst ^= asl($src2, $src3)",
1706            [(set (i64 DoubleRegs:$dst),
1707                  (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
1708                                                    (i32 IntRegs:$src3))))],
1709            "$src1 = $dst">,
1710            Requires<[HasV4T]>;
1711
1712//Rxx^=asr(Rss,Rt)
1713def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1714            (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1715            "$dst ^= asr($src2, $src3)",
1716            [(set (i64 DoubleRegs:$dst),
1717                  (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
1718                                                    (i32 IntRegs:$src3))))],
1719            "$src1 = $dst">,
1720            Requires<[HasV4T]>;
1721
1722//Rxx^=lsl(Rss,Rt)
1723def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1724            (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1725            "$dst ^= lsl($src2, $src3)",
1726            [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
1727                                              (shl (i64 DoubleRegs:$src2),
1728                                                   (i32 IntRegs:$src3))))],
1729            "$src1 = $dst">,
1730            Requires<[HasV4T]>;
1731
1732//Rxx^=lsr(Rss,Rt)
1733def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
1734            (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
1735            "$dst ^= lsr($src2, $src3)",
1736            [(set (i64 DoubleRegs:$dst),
1737                  (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
1738                                                    (i32 IntRegs:$src3))))],
1739            "$src1 = $dst">,
1740            Requires<[HasV4T]>;
1741}
1742
1743//===----------------------------------------------------------------------===//
1744// XTYPE/SHIFT -
1745//===----------------------------------------------------------------------===//
1746
1747//===----------------------------------------------------------------------===//
1748// MEMOP: Word, Half, Byte
1749//===----------------------------------------------------------------------===//
1750
1751def MEMOPIMM : SDNodeXForm<imm, [{
1752  // Call the transformation function XformM5ToU5Imm to get the negative
1753  // immediate's positive counterpart.
1754  int32_t imm = N->getSExtValue();
1755  return XformM5ToU5Imm(imm);
1756}]>;
1757
1758def MEMOPIMM_HALF : SDNodeXForm<imm, [{
1759  // -1 .. -31 represented as 65535..65515
1760  // assigning to a short restores our desired signed value.
1761  // Call the transformation function XformM5ToU5Imm to get the negative
1762  // immediate's positive counterpart.
1763  int16_t imm = N->getSExtValue();
1764  return XformM5ToU5Imm(imm);
1765}]>;
1766
1767def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
1768  // -1 .. -31 represented as 255..235
1769  // assigning to a char restores our desired signed value.
1770  // Call the transformation function XformM5ToU5Imm to get the negative
1771  // immediate's positive counterpart.
1772  int8_t imm = N->getSExtValue();
1773  return XformM5ToU5Imm(imm);
1774}]>;
1775
1776def SETMEMIMM : SDNodeXForm<imm, [{
1777   // Return the bit position we will set [0-31].
1778   // As an SDNode.
1779   int32_t imm = N->getSExtValue();
1780   return XformMskToBitPosU5Imm(imm);
1781}]>;
1782
1783def CLRMEMIMM : SDNodeXForm<imm, [{
1784   // Return the bit position we will clear [0-31].
1785   // As an SDNode.
1786   // we bit negate the value first
1787   int32_t imm = ~(N->getSExtValue());
1788   return XformMskToBitPosU5Imm(imm);
1789}]>;
1790
1791def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
1792   // Return the bit position we will set [0-15].
1793   // As an SDNode.
1794   int16_t imm = N->getSExtValue();
1795   return XformMskToBitPosU4Imm(imm);
1796}]>;
1797
1798def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
1799   // Return the bit position we will clear [0-15].
1800   // As an SDNode.
1801   // we bit negate the value first
1802   int16_t imm = ~(N->getSExtValue());
1803   return XformMskToBitPosU4Imm(imm);
1804}]>;
1805
1806def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
1807   // Return the bit position we will set [0-7].
1808   // As an SDNode.
1809   int8_t imm =  N->getSExtValue();
1810   return XformMskToBitPosU3Imm(imm);
1811}]>;
1812
1813def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
1814   // Return the bit position we will clear [0-7].
1815   // As an SDNode.
1816   // we bit negate the value first
1817   int8_t imm = ~(N->getSExtValue());
1818   return XformMskToBitPosU3Imm(imm);
1819}]>;
1820
1821//===----------------------------------------------------------------------===//
1822// Template class for MemOp instructions with the register value.
1823//===----------------------------------------------------------------------===//
1824class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
1825                     string memOp, bits<2> memOpBits> :
1826      MEMInst_V4<(outs),
1827                 (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
1828                 opc#"($base+#$offset)"#memOp#"$delta",
1829                 []>,
1830                 Requires<[HasV4T, UseMEMOP]> {
1831
1832    bits<5> base;
1833    bits<5> delta;
1834    bits<32> offset;
1835    bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
1836
1837    let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
1838                     !if (!eq(opcBits, 0b01), offset{6-1},
1839                     !if (!eq(opcBits, 0b10), offset{7-2},0)));
1840
1841    let IClass = 0b0011;
1842    let Inst{27-24} = 0b1110;
1843    let Inst{22-21} = opcBits;
1844    let Inst{20-16} = base;
1845    let Inst{13} = 0b0;
1846    let Inst{12-7} = offsetBits;
1847    let Inst{6-5} = memOpBits;
1848    let Inst{4-0} = delta;
1849}
1850
1851//===----------------------------------------------------------------------===//
1852// Template class for MemOp instructions with the immediate value.
1853//===----------------------------------------------------------------------===//
1854class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
1855                     string memOp, bits<2> memOpBits> :
1856      MEMInst_V4 <(outs),
1857                  (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
1858                  opc#"($base+#$offset)"#memOp#"#$delta"
1859                  #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
1860                  []>,
1861                  Requires<[HasV4T, UseMEMOP]> {
1862
1863    bits<5> base;
1864    bits<5> delta;
1865    bits<32> offset;
1866    bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
1867
1868    let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
1869                     !if (!eq(opcBits, 0b01), offset{6-1},
1870                     !if (!eq(opcBits, 0b10), offset{7-2},0)));
1871
1872    let IClass = 0b0011;
1873    let Inst{27-24} = 0b1111;
1874    let Inst{22-21} = opcBits;
1875    let Inst{20-16} = base;
1876    let Inst{13} = 0b0;
1877    let Inst{12-7} = offsetBits;
1878    let Inst{6-5} = memOpBits;
1879    let Inst{4-0} = delta;
1880}
1881
1882// multiclass to define MemOp instructions with register operand.
1883multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
1884  def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
1885  def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
1886  def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
1887  def _OR#NAME#_V4  : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
1888}
1889
1890// multiclass to define MemOp instructions with immediate Operand.
1891multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
1892  def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
1893  def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
1894  def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
1895  def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
1896}
1897
1898multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
1899  defm r : MemOp_rr <opc, opcBits, ImmOp>;
1900  defm i : MemOp_ri <opc, opcBits, ImmOp>;
1901}
1902
1903// Define MemOp instructions.
1904let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
1905validSubTargets =HasV4SubT in {
1906  let opExtentBits = 6, accessSize = ByteAccess in
1907  defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
1908
1909  let opExtentBits = 7, accessSize = HalfWordAccess in
1910  defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
1911
1912  let opExtentBits = 8, accessSize = WordAccess in
1913  defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
1914}
1915
1916//===----------------------------------------------------------------------===//
1917// Multiclass to define 'Def Pats' for ALU operations on the memory
1918// Here value used for the ALU operation is an immediate value.
1919// mem[bh](Rs+#0) += #U5
1920// mem[bh](Rs+#u6) += #U5
1921//===----------------------------------------------------------------------===//
1922
1923multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
1924                          InstHexagon MI, SDNode OpNode> {
1925  let AddedComplexity = 180 in
1926  def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
1927                    IntRegs:$addr),
1928              (MI IntRegs:$addr, #0, u5ImmPred:$addend )>;
1929
1930  let AddedComplexity = 190 in
1931  def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)),
1932                     u5ImmPred:$addend),
1933             (add IntRegs:$base, ExtPred:$offset)),
1934       (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>;
1935}
1936
1937multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
1938                          InstHexagon addMI, InstHexagon subMI> {
1939  defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>;
1940  defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>;
1941}
1942
1943multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
1944  // Half Word
1945  defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
1946                         MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
1947  // Byte
1948  defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
1949                         MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
1950}
1951
1952let Predicates = [HasV4T, UseMEMOP] in {
1953  defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
1954  defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
1955  defm : MemOpi_u5ExtType<extloadi8,  extloadi16>;  // any extend
1956
1957  // Word
1958  defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
1959                         MemOPw_SUBi_V4>;
1960}
1961
1962//===----------------------------------------------------------------------===//
1963// multiclass to define 'Def Pats' for ALU operations on the memory.
1964// Here value used for the ALU operation is a negative value.
1965// mem[bh](Rs+#0) += #m5
1966// mem[bh](Rs+#u6) += #m5
1967//===----------------------------------------------------------------------===//
1968
1969multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
1970                          PatLeaf immPred, ComplexPattern addrPred,
1971                          SDNodeXForm xformFunc, InstHexagon MI> {
1972  let AddedComplexity = 190 in
1973  def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend),
1974                   IntRegs:$addr),
1975             (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>;
1976
1977  let AddedComplexity = 195 in
1978  def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)),
1979                       immPred:$subend),
1980                  (add IntRegs:$base, extPred:$offset)),
1981            (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>;
1982}
1983
1984multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
1985  // Half Word
1986  defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
1987                        ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
1988  // Byte
1989  defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
1990                        ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
1991}
1992
1993let Predicates = [HasV4T, UseMEMOP] in {
1994  defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
1995  defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
1996  defm : MemOpi_m5ExtType<extloadi8,  extloadi16>;  // any extend
1997
1998  // Word
1999  defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
2000                          ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
2001}
2002
2003//===----------------------------------------------------------------------===//
2004// Multiclass to define 'def Pats' for bit operations on the memory.
2005// mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
2006// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
2007//===----------------------------------------------------------------------===//
2008
2009multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
2010                     PatLeaf extPred, ComplexPattern addrPred,
2011                     SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> {
2012
2013  // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
2014  let AddedComplexity = 250 in
2015  def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
2016                          immPred:$bitend),
2017                  (add IntRegs:$base, extPred:$offset)),
2018            (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
2019
2020  // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
2021  let AddedComplexity = 225 in
2022  def : Pat <(stOp (OpNode (ldOp addrPred:$addr), immPred:$bitend),
2023                   addrPred:$addr),
2024             (MI IntRegs:$addr, #0, (xformFunc immPred:$bitend))>;
2025}
2026
2027multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2028  // Byte - clrbit
2029  defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
2030                       ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
2031  // Byte - setbit
2032  defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred,  u6ExtPred,
2033                       ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
2034  // Half Word - clrbit
2035  defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
2036                       ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
2037  // Half Word - setbit
2038  defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
2039                       ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
2040}
2041
2042let Predicates = [HasV4T, UseMEMOP] in {
2043  // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
2044  // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
2045  defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
2046  defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
2047  defm : MemOpi_bitExtType<extloadi8,  extloadi16>;  // any extend
2048
2049  // memw(Rs+#0) = [clrbit|setbit](#U5)
2050  // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
2051  defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
2052                       CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
2053  defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
2054                       SETMEMIMM, MemOPw_SETBITi_V4, or>;
2055}
2056
2057//===----------------------------------------------------------------------===//
2058// Multiclass to define 'def Pats' for ALU operations on the memory
2059// where addend is a register.
2060// mem[bhw](Rs+#0) [+-&|]= Rt
2061// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
2062//===----------------------------------------------------------------------===//
2063
2064multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred,
2065                     PatLeaf extPred, InstHexagon MI, SDNode OpNode> {
2066  let AddedComplexity = 141 in
2067  // mem[bhw](Rs+#0) [+-&|]= Rt
2068  def : Pat <(stOp (OpNode (ldOp addrPred:$addr), (i32 IntRegs:$addend)),
2069                   addrPred:$addr),
2070             (MI IntRegs:$addr, #0, (i32 IntRegs:$addend) )>;
2071
2072  // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
2073  let AddedComplexity = 150 in
2074  def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
2075                           (i32 IntRegs:$orend)),
2076                   (add IntRegs:$base, extPred:$offset)),
2077             (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>;
2078}
2079
2080multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
2081                        ComplexPattern addrPred, PatLeaf extPred,
2082                        InstHexagon addMI, InstHexagon subMI,
2083                        InstHexagon andMI, InstHexagon orMI > {
2084
2085  defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>;
2086  defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>;
2087  defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>;
2088  defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI,  or>;
2089}
2090
2091multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
2092  // Half Word
2093  defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
2094                       MemOPh_ADDr_V4, MemOPh_SUBr_V4,
2095                       MemOPh_ANDr_V4, MemOPh_ORr_V4>;
2096  // Byte
2097  defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
2098                       MemOPb_ADDr_V4, MemOPb_SUBr_V4,
2099                       MemOPb_ANDr_V4, MemOPb_ORr_V4>;
2100}
2101
2102// Define 'def Pats' for MemOps with register addend.
2103let Predicates = [HasV4T, UseMEMOP] in {
2104  // Byte, Half Word
2105  defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
2106  defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
2107  defm : MemOPr_ExtType<extloadi8,  extloadi16>;  // any extend
2108  // Word
2109  defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
2110                       MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
2111}
2112
2113//===----------------------------------------------------------------------===//
2114// XTYPE/PRED +
2115//===----------------------------------------------------------------------===//
2116
2117// Hexagon V4 only supports these flavors of byte/half compare instructions:
2118// EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
2119// hardware. However, compiler can still implement these patterns through
2120// appropriate patterns combinations based on current implemented patterns.
2121// The implemented patterns are: EQ/GT/GTU.
2122// Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
2123
2124// Following instruction is not being extended as it results into the
2125// incorrect code for negative numbers.
2126// Pd=cmpb.eq(Rs,#u8)
2127
2128// p=!cmp.eq(r1,r2)
2129let isCompare = 1, validSubTargets = HasV4SubT in
2130def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
2131                           (ins IntRegs:$src1, IntRegs:$src2),
2132      "$dst = !cmp.eq($src1, $src2)",
2133      [(set (i1 PredRegs:$dst),
2134            (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
2135      Requires<[HasV4T]>;
2136
2137// p=!cmp.eq(r1,#s10)
2138let isCompare = 1, validSubTargets = HasV4SubT in
2139def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
2140                           (ins IntRegs:$src1, s10Ext:$src2),
2141      "$dst = !cmp.eq($src1, #$src2)",
2142      [(set (i1 PredRegs:$dst),
2143            (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
2144      Requires<[HasV4T]>;
2145
2146// p=!cmp.gt(r1,r2)
2147let isCompare = 1, validSubTargets = HasV4SubT in
2148def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
2149                           (ins IntRegs:$src1, IntRegs:$src2),
2150      "$dst = !cmp.gt($src1, $src2)",
2151      [(set (i1 PredRegs:$dst),
2152            (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
2153      Requires<[HasV4T]>;
2154
2155// p=!cmp.gt(r1,#s10)
2156let isCompare = 1, validSubTargets = HasV4SubT in
2157def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
2158                           (ins IntRegs:$src1, s10Ext:$src2),
2159      "$dst = !cmp.gt($src1, #$src2)",
2160      [(set (i1 PredRegs:$dst),
2161            (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
2162      Requires<[HasV4T]>;
2163
2164// p=!cmp.gtu(r1,r2)
2165let isCompare = 1, validSubTargets = HasV4SubT in
2166def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
2167                            (ins IntRegs:$src1, IntRegs:$src2),
2168      "$dst = !cmp.gtu($src1, $src2)",
2169      [(set (i1 PredRegs:$dst),
2170            (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
2171      Requires<[HasV4T]>;
2172
2173// p=!cmp.gtu(r1,#u9)
2174let isCompare = 1, validSubTargets = HasV4SubT in
2175def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
2176                            (ins IntRegs:$src1, u9Ext:$src2),
2177      "$dst = !cmp.gtu($src1, #$src2)",
2178      [(set (i1 PredRegs:$dst),
2179            (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
2180      Requires<[HasV4T]>;
2181
2182let isCompare = 1, validSubTargets = HasV4SubT in
2183def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
2184            (ins IntRegs:$src1, u8Imm:$src2),
2185            "$dst = cmpb.eq($src1, #$src2)",
2186            [(set (i1 PredRegs:$dst),
2187                  (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
2188            Requires<[HasV4T]>;
2189
2190def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
2191                       bb:$offset),
2192      (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
2193                bb:$offset)>,
2194      Requires<[HasV4T]>;
2195
2196// Pd=cmpb.eq(Rs,Rt)
2197let isCompare = 1, validSubTargets = HasV4SubT in
2198def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
2199            (ins IntRegs:$src1, IntRegs:$src2),
2200            "$dst = cmpb.eq($src1, $src2)",
2201            [(set (i1 PredRegs:$dst),
2202                  (seteq (and (xor (i32 IntRegs:$src1),
2203                                   (i32 IntRegs:$src2)), 255), 0))]>,
2204            Requires<[HasV4T]>;
2205
2206// Pd=cmpb.eq(Rs,Rt)
2207let isCompare = 1, validSubTargets = HasV4SubT in
2208def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
2209            (ins IntRegs:$src1, IntRegs:$src2),
2210            "$dst = cmpb.eq($src1, $src2)",
2211            [(set (i1 PredRegs:$dst),
2212                  (seteq (shl (i32 IntRegs:$src1), (i32 24)),
2213                         (shl (i32 IntRegs:$src2), (i32 24))))]>,
2214            Requires<[HasV4T]>;
2215
2216// Pd=cmpb.gt(Rs,Rt)
2217let isCompare = 1, validSubTargets = HasV4SubT in
2218def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
2219            (ins IntRegs:$src1, IntRegs:$src2),
2220            "$dst = cmpb.gt($src1, $src2)",
2221            [(set (i1 PredRegs:$dst),
2222                  (setgt (shl (i32 IntRegs:$src1), (i32 24)),
2223                         (shl (i32 IntRegs:$src2), (i32 24))))]>,
2224            Requires<[HasV4T]>;
2225
2226// Pd=cmpb.gtu(Rs,#u7)
2227let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
2228isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
2229def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
2230            (ins IntRegs:$src1, u7Ext:$src2),
2231            "$dst = cmpb.gtu($src1, #$src2)",
2232            [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
2233                                              u7ExtPred:$src2))]>,
2234            Requires<[HasV4T]>, ImmRegRel;
2235
2236// SDNode for converting immediate C to C-1.
2237def DEC_CONST_BYTE : SDNodeXForm<imm, [{
2238   // Return the byte immediate const-1 as an SDNode.
2239   int32_t imm = N->getSExtValue();
2240   return XformU7ToU7M1Imm(imm);
2241}]>;
2242
2243// For the sequence
2244//   zext( seteq ( and(Rs, 255), u8))
2245// Generate
2246//   Pd=cmpb.eq(Rs, #u8)
2247//   if (Pd.new) Rd=#1
2248//   if (!Pd.new) Rd=#0
2249def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
2250                                           u8ExtPred:$u8)))),
2251           (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
2252                                                 (u8ExtPred:$u8))),
2253                                1, 0))>,
2254           Requires<[HasV4T]>;
2255
2256// For the sequence
2257//   zext( setne ( and(Rs, 255), u8))
2258// Generate
2259//   Pd=cmpb.eq(Rs, #u8)
2260//   if (Pd.new) Rd=#0
2261//   if (!Pd.new) Rd=#1
2262def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
2263                                           u8ExtPred:$u8)))),
2264           (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
2265                                                 (u8ExtPred:$u8))),
2266                                0, 1))>,
2267           Requires<[HasV4T]>;
2268
2269// For the sequence
2270//   zext( seteq (Rs, and(Rt, 255)))
2271// Generate
2272//   Pd=cmpb.eq(Rs, Rt)
2273//   if (Pd.new) Rd=#1
2274//   if (!Pd.new) Rd=#0
2275def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
2276                                 (i32 (and (i32 IntRegs:$Rs), 255)))))),
2277           (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
2278                                                      (i32 IntRegs:$Rt))),
2279                                1, 0))>,
2280           Requires<[HasV4T]>;
2281
2282// For the sequence
2283//   zext( setne (Rs, and(Rt, 255)))
2284// Generate
2285//   Pd=cmpb.eq(Rs, Rt)
2286//   if (Pd.new) Rd=#0
2287//   if (!Pd.new) Rd=#1
2288def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
2289                                 (i32 (and (i32 IntRegs:$Rs), 255)))))),
2290           (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
2291                                                      (i32 IntRegs:$Rt))),
2292                                0, 1))>,
2293           Requires<[HasV4T]>;
2294
2295// For the sequence
2296//   zext( setugt ( and(Rs, 255), u8))
2297// Generate
2298//   Pd=cmpb.gtu(Rs, #u8)
2299//   if (Pd.new) Rd=#1
2300//   if (!Pd.new) Rd=#0
2301def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
2302                                            u8ExtPred:$u8)))),
2303           (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
2304                                                  (u8ExtPred:$u8))),
2305                                1, 0))>,
2306           Requires<[HasV4T]>;
2307
2308// For the sequence
2309//   zext( setugt ( and(Rs, 254), u8))
2310// Generate
2311//   Pd=cmpb.gtu(Rs, #u8)
2312//   if (Pd.new) Rd=#1
2313//   if (!Pd.new) Rd=#0
2314def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
2315                                            u8ExtPred:$u8)))),
2316           (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
2317                                                  (u8ExtPred:$u8))),
2318                                1, 0))>,
2319           Requires<[HasV4T]>;
2320
2321// For the sequence
2322//   zext( setult ( Rs, Rt))
2323// Generate
2324//   Pd=cmp.ltu(Rs, Rt)
2325//   if (Pd.new) Rd=#1
2326//   if (!Pd.new) Rd=#0
2327// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
2328def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2329           (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
2330                                              (i32 IntRegs:$Rs))),
2331                                1, 0))>,
2332           Requires<[HasV4T]>;
2333
2334// For the sequence
2335//   zext( setlt ( Rs, Rt))
2336// Generate
2337//   Pd=cmp.lt(Rs, Rt)
2338//   if (Pd.new) Rd=#1
2339//   if (!Pd.new) Rd=#0
2340// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
2341def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2342           (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
2343                                             (i32 IntRegs:$Rs))),
2344                                1, 0))>,
2345           Requires<[HasV4T]>;
2346
2347// For the sequence
2348//   zext( setugt ( Rs, Rt))
2349// Generate
2350//   Pd=cmp.gtu(Rs, Rt)
2351//   if (Pd.new) Rd=#1
2352//   if (!Pd.new) Rd=#0
2353def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2354           (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
2355                                              (i32 IntRegs:$Rt))),
2356                                1, 0))>,
2357           Requires<[HasV4T]>;
2358
2359// This pattern interefers with coremark performance, not implementing at this
2360// time.
2361// For the sequence
2362//   zext( setgt ( Rs, Rt))
2363// Generate
2364//   Pd=cmp.gt(Rs, Rt)
2365//   if (Pd.new) Rd=#1
2366//   if (!Pd.new) Rd=#0
2367
2368// For the sequence
2369//   zext( setuge ( Rs, Rt))
2370// Generate
2371//   Pd=cmp.ltu(Rs, Rt)
2372//   if (Pd.new) Rd=#0
2373//   if (!Pd.new) Rd=#1
2374// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
2375def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2376           (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
2377                                              (i32 IntRegs:$Rs))),
2378                                0, 1))>,
2379           Requires<[HasV4T]>;
2380
2381// For the sequence
2382//   zext( setge ( Rs, Rt))
2383// Generate
2384//   Pd=cmp.lt(Rs, Rt)
2385//   if (Pd.new) Rd=#0
2386//   if (!Pd.new) Rd=#1
2387// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
2388def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2389           (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
2390                                             (i32 IntRegs:$Rs))),
2391                                0, 1))>,
2392           Requires<[HasV4T]>;
2393
2394// For the sequence
2395//   zext( setule ( Rs, Rt))
2396// Generate
2397//   Pd=cmp.gtu(Rs, Rt)
2398//   if (Pd.new) Rd=#0
2399//   if (!Pd.new) Rd=#1
2400def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2401           (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
2402                                              (i32 IntRegs:$Rt))),
2403                                0, 1))>,
2404           Requires<[HasV4T]>;
2405
2406// For the sequence
2407//   zext( setle ( Rs, Rt))
2408// Generate
2409//   Pd=cmp.gt(Rs, Rt)
2410//   if (Pd.new) Rd=#0
2411//   if (!Pd.new) Rd=#1
2412def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
2413           (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
2414                                             (i32 IntRegs:$Rt))),
2415                                0, 1))>,
2416           Requires<[HasV4T]>;
2417
2418// For the sequence
2419//   zext( setult ( and(Rs, 255), u8))
2420// Use the isdigit transformation below
2421
2422// Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
2423// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
2424// The isdigit transformation relies on two 'clever' aspects:
2425// 1) The data type is unsigned which allows us to eliminate a zero test after
2426//    biasing the expression by 48. We are depending on the representation of
2427//    the unsigned types, and semantics.
2428// 2) The front end has converted <= 9 into < 10 on entry to LLVM
2429//
2430// For the C code:
2431//   retval = ((c>='0') & (c<='9')) ? 1 : 0;
2432// The code is transformed upstream of llvm into
2433//   retval = (c-48) < 10 ? 1 : 0;
2434let AddedComplexity = 139 in
2435def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
2436                                  u7StrictPosImmPred:$src2)))),
2437  (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
2438                                 (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
2439                   0, 1))>,
2440                   Requires<[HasV4T]>;
2441
2442// Pd=cmpb.gtu(Rs,Rt)
2443let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
2444InputType = "reg" in
2445def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
2446            (ins IntRegs:$src1, IntRegs:$src2),
2447            "$dst = cmpb.gtu($src1, $src2)",
2448            [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
2449                                             (and (i32 IntRegs:$src2), 255)))]>,
2450            Requires<[HasV4T]>, ImmRegRel;
2451
2452// Following instruction is not being extended as it results into the incorrect
2453// code for negative numbers.
2454
2455// Signed half compare(.eq) ri.
2456// Pd=cmph.eq(Rs,#s8)
2457let isCompare = 1, validSubTargets = HasV4SubT in
2458def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
2459            (ins IntRegs:$src1, s8Imm:$src2),
2460            "$dst = cmph.eq($src1, #$src2)",
2461            [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
2462                                             s8ImmPred:$src2))]>,
2463            Requires<[HasV4T]>;
2464
2465// Signed half compare(.eq) rr.
2466// Case 1: xor + and, then compare:
2467//   r0=xor(r0,r1)
2468//   r0=and(r0,#0xffff)
2469//   p0=cmp.eq(r0,#0)
2470// Pd=cmph.eq(Rs,Rt)
2471let isCompare = 1, validSubTargets = HasV4SubT in
2472def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
2473            (ins IntRegs:$src1, IntRegs:$src2),
2474            "$dst = cmph.eq($src1, $src2)",
2475            [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
2476                                                       (i32 IntRegs:$src2)),
2477                                                  65535), 0))]>,
2478            Requires<[HasV4T]>;
2479
2480// Signed half compare(.eq) rr.
2481// Case 2: shift left 16 bits then compare:
2482//   r0=asl(r0,16)
2483//   r1=asl(r1,16)
2484//   p0=cmp.eq(r0,r1)
2485// Pd=cmph.eq(Rs,Rt)
2486let isCompare = 1, validSubTargets = HasV4SubT in
2487def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
2488            (ins IntRegs:$src1, IntRegs:$src2),
2489            "$dst = cmph.eq($src1, $src2)",
2490            [(set (i1 PredRegs:$dst),
2491                  (seteq (shl (i32 IntRegs:$src1), (i32 16)),
2492                         (shl (i32 IntRegs:$src2), (i32 16))))]>,
2493            Requires<[HasV4T]>;
2494
2495/* Incorrect Pattern -- immediate should be right shifted before being
2496used in the cmph.gt instruction.
2497// Signed half compare(.gt) ri.
2498// Pd=cmph.gt(Rs,#s8)
2499
2500let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
2501isCompare = 1, validSubTargets = HasV4SubT in
2502def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
2503            (ins IntRegs:$src1, s8Ext:$src2),
2504            "$dst = cmph.gt($src1, #$src2)",
2505            [(set (i1 PredRegs:$dst),
2506                  (setgt (shl (i32 IntRegs:$src1), (i32 16)),
2507                         s8ExtPred:$src2))]>,
2508            Requires<[HasV4T]>;
2509*/
2510
2511// Signed half compare(.gt) rr.
2512// Pd=cmph.gt(Rs,Rt)
2513let isCompare = 1, validSubTargets = HasV4SubT in
2514def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
2515            (ins IntRegs:$src1, IntRegs:$src2),
2516            "$dst = cmph.gt($src1, $src2)",
2517            [(set (i1 PredRegs:$dst),
2518                  (setgt (shl (i32 IntRegs:$src1), (i32 16)),
2519                         (shl (i32 IntRegs:$src2), (i32 16))))]>,
2520            Requires<[HasV4T]>;
2521
2522// Unsigned half compare rr (.gtu).
2523// Pd=cmph.gtu(Rs,Rt)
2524let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
2525InputType = "reg" in
2526def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
2527            (ins IntRegs:$src1, IntRegs:$src2),
2528            "$dst = cmph.gtu($src1, $src2)",
2529            [(set (i1 PredRegs:$dst),
2530                  (setugt (and (i32 IntRegs:$src1), 65535),
2531                          (and (i32 IntRegs:$src2), 65535)))]>,
2532            Requires<[HasV4T]>, ImmRegRel;
2533
2534// Unsigned half compare ri (.gtu).
2535// Pd=cmph.gtu(Rs,#u7)
2536let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
2537isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
2538InputType = "imm" in
2539def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
2540            (ins IntRegs:$src1, u7Ext:$src2),
2541            "$dst = cmph.gtu($src1, #$src2)",
2542            [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
2543                                              u7ExtPred:$src2))]>,
2544            Requires<[HasV4T]>, ImmRegRel;
2545
2546let validSubTargets = HasV4SubT in
2547def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
2548    "$dst = !tstbit($src1, $src2)",
2549    [(set (i1 PredRegs:$dst),
2550          (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
2551    Requires<[HasV4T]>;
2552
2553let validSubTargets = HasV4SubT in
2554def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
2555    "$dst = !tstbit($src1, $src2)",
2556    [(set (i1 PredRegs:$dst),
2557          (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
2558    Requires<[HasV4T]>;
2559
2560//===----------------------------------------------------------------------===//
2561// XTYPE/PRED -
2562//===----------------------------------------------------------------------===//
2563
2564//Deallocate frame and return.
2565//    dealloc_return
2566let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
2567  Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in {
2568let validSubTargets = HasV4SubT in
2569  def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
2570            "dealloc_return",
2571            []>,
2572            Requires<[HasV4T]>;
2573}
2574
2575// Restore registers and dealloc return function call.
2576let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
2577  Defs = [R29, R30, R31, PC] in {
2578let validSubTargets = HasV4SubT in
2579  def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
2580                                   (ins calltarget:$dst),
2581             "jump $dst",
2582             []>,
2583             Requires<[HasV4T]>;
2584}
2585
2586// Restore registers and dealloc frame before a tail call.
2587let isCall = 1, isBarrier = 1,
2588  Defs = [R29, R30, R31, PC] in {
2589let validSubTargets = HasV4SubT in
2590  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
2591                                           (ins calltarget:$dst),
2592             "call $dst",
2593             []>,
2594             Requires<[HasV4T]>;
2595}
2596
2597// Save registers function call.
2598let isCall = 1, isBarrier = 1,
2599  Uses = [R29, R31] in {
2600  def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
2601                               (ins calltarget:$dst),
2602             "call $dst // Save_calle_saved_registers",
2603             []>,
2604             Requires<[HasV4T]>;
2605}
2606
2607//    if (Ps) dealloc_return
2608let isReturn = 1, isTerminator = 1,
2609    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2610    isPredicated = 1 in {
2611let validSubTargets = HasV4SubT in
2612  def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
2613                           (ins PredRegs:$src1),
2614            "if ($src1) dealloc_return",
2615            []>,
2616            Requires<[HasV4T]>;
2617}
2618
2619//    if (!Ps) dealloc_return
2620let isReturn = 1, isTerminator = 1,
2621    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2622    isPredicated = 1, isPredicatedFalse = 1 in {
2623let validSubTargets = HasV4SubT in
2624  def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2625            "if (!$src1) dealloc_return",
2626            []>,
2627            Requires<[HasV4T]>;
2628}
2629
2630//    if (Ps.new) dealloc_return:nt
2631let isReturn = 1, isTerminator = 1,
2632    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2633    isPredicated = 1 in {
2634let validSubTargets = HasV4SubT in
2635  def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2636            "if ($src1.new) dealloc_return:nt",
2637            []>,
2638            Requires<[HasV4T]>;
2639}
2640
2641//    if (!Ps.new) dealloc_return:nt
2642let isReturn = 1, isTerminator = 1,
2643    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2644    isPredicated = 1, isPredicatedFalse = 1 in {
2645let validSubTargets = HasV4SubT in
2646  def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2647            "if (!$src1.new) dealloc_return:nt",
2648            []>,
2649            Requires<[HasV4T]>;
2650}
2651
2652//    if (Ps.new) dealloc_return:t
2653let isReturn = 1, isTerminator = 1,
2654    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2655    isPredicated = 1 in {
2656let validSubTargets = HasV4SubT in
2657  def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2658            "if ($src1.new) dealloc_return:t",
2659            []>,
2660            Requires<[HasV4T]>;
2661}
2662
2663// if (!Ps.new) dealloc_return:nt
2664let isReturn = 1, isTerminator = 1,
2665    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2666    isPredicated = 1, isPredicatedFalse = 1 in {
2667let validSubTargets = HasV4SubT in
2668  def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2669            "if (!$src1.new) dealloc_return:t",
2670            []>,
2671            Requires<[HasV4T]>;
2672}
2673
2674// Load/Store with absolute addressing mode
2675// memw(#u6)=Rt
2676
2677multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
2678                           bit isPredNew> {
2679  let isPredicatedNew = isPredNew in
2680  def NAME#_V4 : STInst2<(outs),
2681            (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2682            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2683            ") ")#mnemonic#"(##$absaddr) = $src2",
2684            []>,
2685            Requires<[HasV4T]>;
2686}
2687
2688multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
2689  let isPredicatedFalse = PredNot in {
2690    defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
2691    // Predicate new
2692    defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
2693  }
2694}
2695
2696let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
2697multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
2698  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2699    let opExtendable = 0, isPredicable = 1 in
2700    def NAME#_V4 : STInst2<(outs),
2701            (ins u0AlwaysExt:$absaddr, RC:$src),
2702            mnemonic#"(##$absaddr) = $src",
2703            []>,
2704            Requires<[HasV4T]>;
2705
2706    let opExtendable = 1, isPredicated = 1 in {
2707      defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
2708      defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
2709    }
2710  }
2711}
2712
2713multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
2714                           bit isPredNew> {
2715  let isPredicatedNew = isPredNew in
2716  def NAME#_nv_V4 : NVInst_V4<(outs),
2717            (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2718            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2719            ") ")#mnemonic#"(##$absaddr) = $src2.new",
2720            []>,
2721            Requires<[HasV4T]>;
2722}
2723
2724multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
2725  let isPredicatedFalse = PredNot in {
2726    defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
2727    // Predicate new
2728    defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
2729  }
2730}
2731
2732let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
2733multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
2734  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2735    let opExtendable = 0, isPredicable = 1 in
2736    def NAME#_nv_V4 : NVInst_V4<(outs),
2737            (ins u0AlwaysExt:$absaddr, RC:$src),
2738            mnemonic#"(##$absaddr) = $src.new",
2739            []>,
2740            Requires<[HasV4T]>;
2741
2742    let opExtendable = 1, isPredicated = 1 in {
2743      defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
2744      defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
2745    }
2746  }
2747}
2748
2749let addrMode = Absolute in {
2750  let accessSize = ByteAccess in
2751    defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
2752                     ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
2753
2754  let accessSize = HalfWordAccess in
2755    defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
2756                     ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
2757
2758  let accessSize = WordAccess in
2759    defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
2760                     ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
2761
2762  let accessSize = DoubleWordAccess, isNVStorable = 0 in
2763    defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
2764}
2765
2766let Predicates = [HasV4T], AddedComplexity = 30 in {
2767def : Pat<(truncstorei8 (i32 IntRegs:$src1),
2768                        (HexagonCONST32 tglobaladdr:$absaddr)),
2769          (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2770
2771def : Pat<(truncstorei16 (i32 IntRegs:$src1),
2772                          (HexagonCONST32 tglobaladdr:$absaddr)),
2773          (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2774
2775def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
2776          (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
2777
2778def : Pat<(store (i64 DoubleRegs:$src1),
2779                 (HexagonCONST32 tglobaladdr:$absaddr)),
2780          (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
2781}
2782
2783//===----------------------------------------------------------------------===//
2784// multiclass for store instructions with GP-relative addressing mode.
2785// mem[bhwd](#global)=Rt
2786// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
2787//===----------------------------------------------------------------------===//
2788let mayStore = 1, isNVStorable = 1 in
2789multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
2790  let BaseOpcode = BaseOp, isPredicable = 1 in
2791  def NAME#_V4 : STInst2<(outs),
2792          (ins globaladdress:$global, RC:$src),
2793          mnemonic#"(#$global) = $src",
2794          []>;
2795
2796  // When GP-relative instructions are predicated, their addressing mode is
2797  // changed to absolute and they are always constant extended.
2798  let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
2799  isPredicated = 1 in {
2800    defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
2801    defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
2802  }
2803}
2804
2805let mayStore = 1, isNVStore = 1 in
2806multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
2807  let BaseOpcode = BaseOp, isPredicable = 1 in
2808  def NAME#_nv_V4 : NVInst_V4<(outs),
2809          (ins u0AlwaysExt:$global, RC:$src),
2810          mnemonic#"(#$global) = $src.new",
2811          []>,
2812          Requires<[HasV4T]>;
2813
2814  // When GP-relative instructions are predicated, their addressing mode is
2815  // changed to absolute and they are always constant extended.
2816  let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
2817  isPredicated = 1 in {
2818    defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
2819    defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
2820  }
2821}
2822
2823let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
2824  let isNVStorable = 0 in
2825  defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
2826
2827  defm STb_GP : ST_GP<"memb",  "STb_GP", IntRegs>,
2828                ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
2829  defm STh_GP : ST_GP<"memh",  "STh_GP", IntRegs>,
2830                ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
2831  defm STw_GP : ST_GP<"memw",  "STw_GP", IntRegs>,
2832                ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
2833}
2834
2835// 64 bit atomic store
2836def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
2837                            (i64 DoubleRegs:$src1)),
2838           (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
2839           Requires<[HasV4T]>;
2840
2841// Map from store(globaladdress) -> memd(#foo)
2842let AddedComplexity = 100 in
2843def : Pat <(store (i64 DoubleRegs:$src1),
2844                  (HexagonCONST32_GP tglobaladdr:$global)),
2845           (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
2846
2847// 8 bit atomic store
2848def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
2849                            (i32 IntRegs:$src1)),
2850            (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2851
2852// Map from store(globaladdress) -> memb(#foo)
2853let AddedComplexity = 100 in
2854def : Pat<(truncstorei8 (i32 IntRegs:$src1),
2855          (HexagonCONST32_GP tglobaladdr:$global)),
2856          (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2857
2858// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
2859//       to "r0 = 1; memw(#foo) = r0"
2860let AddedComplexity = 100 in
2861def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
2862          (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
2863
2864def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
2865                           (i32 IntRegs:$src1)),
2866          (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2867
2868// Map from store(globaladdress) -> memh(#foo)
2869let AddedComplexity = 100 in
2870def : Pat<(truncstorei16 (i32 IntRegs:$src1),
2871                         (HexagonCONST32_GP tglobaladdr:$global)),
2872          (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2873
2874// 32 bit atomic store
2875def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
2876                           (i32 IntRegs:$src1)),
2877          (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2878
2879// Map from store(globaladdress) -> memw(#foo)
2880let AddedComplexity = 100 in
2881def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
2882          (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
2883
2884//===----------------------------------------------------------------------===//
2885// Multiclass for the load instructions with absolute addressing mode.
2886//===----------------------------------------------------------------------===//
2887multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
2888                           bit isPredNew> {
2889  let isPredicatedNew = isPredNew in
2890  def NAME : LDInst2<(outs RC:$dst),
2891            (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
2892            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2893            ") ")#"$dst = "#mnemonic#"(##$absaddr)",
2894            []>,
2895            Requires<[HasV4T]>;
2896}
2897
2898multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
2899  let isPredicatedFalse = PredNot in {
2900    defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
2901    // Predicate new
2902    defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
2903  }
2904}
2905
2906let isExtended = 1, neverHasSideEffects = 1 in
2907multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
2908  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2909    let  opExtendable = 1, isPredicable = 1 in
2910    def NAME#_V4 : LDInst2<(outs RC:$dst),
2911            (ins u0AlwaysExt:$absaddr),
2912            "$dst = "#mnemonic#"(##$absaddr)",
2913            []>,
2914            Requires<[HasV4T]>;
2915
2916    let opExtendable = 2, isPredicated = 1 in {
2917      defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
2918      defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
2919    }
2920  }
2921}
2922
2923let addrMode = Absolute in {
2924  let accessSize = ByteAccess in {
2925    defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
2926    defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
2927  }
2928  let accessSize = HalfWordAccess in {
2929    defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
2930    defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
2931  }
2932  let accessSize = WordAccess in
2933    defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
2934
2935  let accessSize = DoubleWordAccess in
2936    defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
2937}
2938
2939let Predicates = [HasV4T], AddedComplexity  = 30 in {
2940def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
2941          (LDriw_abs_V4 tglobaladdr: $absaddr)>;
2942
2943def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
2944          (LDrib_abs_V4 tglobaladdr:$absaddr)>;
2945
2946def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
2947          (LDriub_abs_V4 tglobaladdr:$absaddr)>;
2948
2949def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
2950          (LDrih_abs_V4 tglobaladdr:$absaddr)>;
2951
2952def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
2953          (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
2954}
2955
2956//===----------------------------------------------------------------------===//
2957// multiclass for load instructions with GP-relative addressing mode.
2958// Rx=mem[bhwd](##global)
2959// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
2960//===----------------------------------------------------------------------===//
2961let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
2962multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
2963  let BaseOpcode = BaseOp in {
2964    let isPredicable = 1 in
2965    def NAME#_V4 : LDInst2<(outs RC:$dst),
2966            (ins globaladdress:$global),
2967            "$dst = "#mnemonic#"(#$global)",
2968            []>;
2969
2970    let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
2971      defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
2972      defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
2973    }
2974  }
2975}
2976
2977defm LDd_GP  : LD_GP<"memd",  "LDd_GP",  DoubleRegs>, PredNewRel;
2978defm LDb_GP  : LD_GP<"memb",  "LDb_GP",  IntRegs>, PredNewRel;
2979defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
2980defm LDh_GP  : LD_GP<"memh",  "LDh_GP",  IntRegs>, PredNewRel;
2981defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
2982defm LDw_GP  : LD_GP<"memw",  "LDw_GP",  IntRegs>, PredNewRel;
2983
2984def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
2985           (i64 (LDd_GP_V4 tglobaladdr:$global))>;
2986
2987def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
2988           (i32 (LDw_GP_V4 tglobaladdr:$global))>;
2989
2990def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
2991           (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
2992
2993def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
2994           (i32 (LDub_GP_V4 tglobaladdr:$global))>;
2995
2996// Map from load(globaladdress) -> memw(#foo + 0)
2997let AddedComplexity = 100 in
2998def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
2999           (i64 (LDd_GP_V4 tglobaladdr:$global))>;
3000
3001// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
3002let AddedComplexity = 100 in
3003def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
3004           (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
3005
3006// When the Interprocedural Global Variable optimizer realizes that a certain
3007// global variable takes only two constant values, it shrinks the global to
3008// a boolean. Catch those loads here in the following 3 patterns.
3009let AddedComplexity = 100 in
3010def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3011           (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3012
3013let AddedComplexity = 100 in
3014def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3015           (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3016
3017// Map from load(globaladdress) -> memb(#foo)
3018let AddedComplexity = 100 in
3019def : Pat <(i32 (extloadi8 (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 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
3025           (i32 (LDb_GP_V4 tglobaladdr:$global))>;
3026
3027let AddedComplexity = 100 in
3028def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
3029           (i32 (LDub_GP_V4 tglobaladdr:$global))>;
3030
3031// Map from load(globaladdress) -> memub(#foo)
3032let AddedComplexity = 100 in
3033def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
3034           (i32 (LDub_GP_V4 tglobaladdr:$global))>;
3035
3036// Map from load(globaladdress) -> memh(#foo)
3037let AddedComplexity = 100 in
3038def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3039           (i32 (LDh_GP_V4 tglobaladdr:$global))>;
3040
3041// Map from load(globaladdress) -> memh(#foo)
3042let AddedComplexity = 100 in
3043def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3044           (i32 (LDh_GP_V4 tglobaladdr:$global))>;
3045
3046// Map from load(globaladdress) -> memuh(#foo)
3047let AddedComplexity = 100 in
3048def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
3049           (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
3050
3051// Map from load(globaladdress) -> memw(#foo)
3052let AddedComplexity = 100 in
3053def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
3054           (i32 (LDw_GP_V4 tglobaladdr:$global))>;
3055
3056
3057// Transfer global address into a register
3058let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
3059isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in
3060def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
3061           "$dst = #$src1",
3062           [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3063           Requires<[HasV4T]>;
3064
3065// Transfer a block address into a register
3066def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
3067          (TFRI_V4 tblockaddress:$src1)>,
3068          Requires<[HasV4T]>;
3069
3070let isExtended = 1, opExtendable = 2, AddedComplexity=50,
3071neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3072def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3073                           (ins PredRegs:$src1, s16Ext:$src2),
3074           "if($src1) $dst = #$src2",
3075           []>,
3076           Requires<[HasV4T]>;
3077
3078let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
3079neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3080def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3081                              (ins PredRegs:$src1, s16Ext:$src2),
3082           "if(!$src1) $dst = #$src2",
3083           []>,
3084           Requires<[HasV4T]>;
3085
3086let isExtended = 1, opExtendable = 2, AddedComplexity=50,
3087neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3088def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3089                             (ins PredRegs:$src1, s16Ext:$src2),
3090           "if($src1.new) $dst = #$src2",
3091           []>,
3092           Requires<[HasV4T]>;
3093
3094let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
3095neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3096def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3097                                (ins PredRegs:$src1, s16Ext:$src2),
3098           "if(!$src1.new) $dst = #$src2",
3099           []>,
3100           Requires<[HasV4T]>;
3101
3102let AddedComplexity = 50, Predicates = [HasV4T] in
3103def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3104           (TFRI_V4 tglobaladdr:$src1)>,
3105           Requires<[HasV4T]>;
3106
3107
3108// Load - Indirect with long offset: These instructions take global address
3109// as an operand
3110let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
3111validSubTargets = HasV4SubT in
3112def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3113            (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3114            "$dst=memd($src1<<#$src2+##$offset)",
3115            [(set (i64 DoubleRegs:$dst),
3116                  (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3117                        (HexagonCONST32 tglobaladdr:$offset))))]>,
3118            Requires<[HasV4T]>;
3119
3120let AddedComplexity = 40 in
3121multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3122let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
3123  def _lo_V4 : LDInst<(outs IntRegs:$dst),
3124            (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3125            !strconcat("$dst = ",
3126            !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3127            [(set IntRegs:$dst,
3128                  (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3129                          (HexagonCONST32 tglobaladdr:$offset)))))]>,
3130            Requires<[HasV4T]>;
3131}
3132
3133defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3134defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3135defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
3136defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3137defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3138defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
3139defm LDriw_ind : LD_indirect_lo<"memw", load>;
3140
3141let AddedComplexity = 40 in
3142def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
3143                                 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
3144           (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
3145           Requires<[HasV4T]>;
3146
3147let AddedComplexity = 40 in
3148def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
3149                                 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
3150           (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
3151           Requires<[HasV4T]>;
3152
3153let Predicates = [HasV4T], AddedComplexity  = 30 in {
3154def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3155          (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3156
3157def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3158          (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3159
3160def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3161          (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3162}
3163
3164let Predicates = [HasV4T], AddedComplexity  = 30 in {
3165def : Pat<(i32 (load u0AlwaysExtPred:$src)),
3166          (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
3167
3168def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
3169          (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
3170
3171def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
3172          (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
3173
3174def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
3175          (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
3176
3177def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
3178          (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
3179}
3180
3181// Indexed store word - global address.
3182// memw(Rs+#u6:2)=#S8
3183let AddedComplexity = 10 in
3184def STriw_offset_ext_V4 : STInst<(outs),
3185            (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
3186            "memw($src1+#$src2) = ##$src3",
3187            [(store (HexagonCONST32 tglobaladdr:$src3),
3188                    (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
3189            Requires<[HasV4T]>;
3190
3191def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
3192          (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
3193          Requires<[HasV4T]>;
3194
3195def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
3196          (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
3197          Requires<[HasV4T]>;
3198
3199
3200// i8 -> i64 loads
3201// We need a complexity of 120 here to override preceding handling of
3202// zextloadi8.
3203let Predicates = [HasV4T], AddedComplexity = 120 in {
3204def:  Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3205      (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
3206
3207def:  Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3208      (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
3209
3210def:  Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3211      (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>;
3212
3213def:  Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
3214      (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
3215
3216def:  Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
3217      (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
3218
3219def:  Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
3220      (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
3221}
3222// i16 -> i64 loads
3223// We need a complexity of 120 here to override preceding handling of
3224// zextloadi16.
3225let AddedComplexity = 120 in {
3226def:  Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3227      (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
3228      Requires<[HasV4T]>;
3229
3230def:  Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3231      (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
3232      Requires<[HasV4T]>;
3233
3234def:  Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3235      (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>,
3236      Requires<[HasV4T]>;
3237
3238def:  Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
3239      (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
3240      Requires<[HasV4T]>;
3241
3242def:  Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
3243      (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
3244      Requires<[HasV4T]>;
3245
3246def:  Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
3247      (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
3248      Requires<[HasV4T]>;
3249}
3250// i32->i64 loads
3251// We need a complexity of 120 here to override preceding handling of
3252// zextloadi32.
3253let AddedComplexity = 120 in {
3254def:  Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3255      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
3256      Requires<[HasV4T]>;
3257
3258def:  Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3259      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
3260      Requires<[HasV4T]>;
3261
3262def:  Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
3263      (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>,
3264      Requires<[HasV4T]>;
3265
3266def:  Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
3267      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3268      Requires<[HasV4T]>;
3269
3270def:  Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
3271      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3272      Requires<[HasV4T]>;
3273
3274def:  Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
3275      (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
3276      Requires<[HasV4T]>;
3277}
3278
3279// Indexed store double word - global address.
3280// memw(Rs+#u6:2)=#S8
3281let AddedComplexity = 10 in
3282def STrih_offset_ext_V4 : STInst<(outs),
3283            (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
3284            "memh($src1+#$src2) = ##$src3",
3285            [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
3286                    (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
3287            Requires<[HasV4T]>;
3288// Map from store(globaladdress + x) -> memd(#foo + x)
3289let AddedComplexity = 100 in
3290def : Pat<(store (i64 DoubleRegs:$src1),
3291                 FoldGlobalAddrGP:$addr),
3292          (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
3293          Requires<[HasV4T]>;
3294
3295def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
3296                           (i64 DoubleRegs:$src1)),
3297          (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
3298          Requires<[HasV4T]>;
3299
3300// Map from store(globaladdress + x) -> memb(#foo + x)
3301let AddedComplexity = 100 in
3302def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3303          (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3304            Requires<[HasV4T]>;
3305
3306def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3307          (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3308            Requires<[HasV4T]>;
3309
3310// Map from store(globaladdress + x) -> memh(#foo + x)
3311let AddedComplexity = 100 in
3312def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3313          (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3314            Requires<[HasV4T]>;
3315
3316def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3317          (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3318            Requires<[HasV4T]>;
3319
3320// Map from store(globaladdress + x) -> memw(#foo + x)
3321let AddedComplexity = 100 in
3322def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
3323          (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3324           Requires<[HasV4T]>;
3325
3326def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
3327          (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
3328            Requires<[HasV4T]>;
3329
3330// Map from load(globaladdress + x) -> memd(#foo + x)
3331let AddedComplexity = 100 in
3332def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
3333          (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
3334           Requires<[HasV4T]>;
3335
3336def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
3337          (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
3338           Requires<[HasV4T]>;
3339
3340// Map from load(globaladdress + x) -> memb(#foo + x)
3341let AddedComplexity = 100 in
3342def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
3343          (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
3344           Requires<[HasV4T]>;
3345
3346// Map from load(globaladdress + x) -> memb(#foo + x)
3347let AddedComplexity = 100 in
3348def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
3349          (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
3350           Requires<[HasV4T]>;
3351
3352//let AddedComplexity = 100 in
3353let AddedComplexity = 100 in
3354def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
3355          (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
3356           Requires<[HasV4T]>;
3357
3358// Map from load(globaladdress + x) -> memh(#foo + x)
3359let AddedComplexity = 100 in
3360def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
3361          (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
3362           Requires<[HasV4T]>;
3363
3364// Map from load(globaladdress + x) -> memuh(#foo + x)
3365let AddedComplexity = 100 in
3366def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
3367          (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
3368           Requires<[HasV4T]>;
3369
3370def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
3371          (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
3372           Requires<[HasV4T]>;
3373
3374// Map from load(globaladdress + x) -> memub(#foo + x)
3375let AddedComplexity = 100 in
3376def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
3377          (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
3378           Requires<[HasV4T]>;
3379
3380def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
3381          (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
3382           Requires<[HasV4T]>;
3383
3384// Map from load(globaladdress + x) -> memw(#foo + x)
3385let AddedComplexity = 100 in
3386def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
3387          (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
3388           Requires<[HasV4T]>;
3389
3390def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
3391          (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
3392           Requires<[HasV4T]>;
3393