1 //=- HexagonInstrInfoV4.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Hexagon V4 instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 let neverHasSideEffects = 1 in
15 class T_Immext<dag ins> :
16 EXTENDERInst<(outs), ins, "immext(#$imm)", []>,
19 def IMMEXT_b : T_Immext<(ins brtarget:$imm)>;
20 def IMMEXT_c : T_Immext<(ins calltarget:$imm)>;
21 def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>;
22 def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>;
24 // Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address.
25 def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>;
27 // Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address.
28 def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>;
30 def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
31 (HexagonCONST32 node:$addr), [{
32 return hasNumUsesBelowThresGA(N->getOperand(0).getNode());
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
40 // ========================================
41 // Loads (8/16/32/64 bit)
45 // ========================================
46 // Stores (8/16/32/64 bit)
49 // ALU32 Instructions:
50 // ========================================
51 // Arithmetic / Logical (32 bit)
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
62 // Vector Halfword (ALU, Shift, Multiply)
63 // Vector Word (ALU, Shift)
66 // ========================================
67 // Jump/Call PC-relative
70 // ========================================
73 // MEMOP Instructions:
74 // ========================================
75 // Operation on memory (8/16/32 bit)
78 // ========================================
83 // ========================================
84 // Control-Register Transfers
85 // Hardware Loop Setup
86 // Predicate Logicals & Reductions
88 // SYSTEM Instructions (not implemented in the compiler):
89 // ========================================
95 //===----------------------------------------------------------------------===//
97 //===----------------------------------------------------------------------===//
101 let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
102 def ASLH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
103 (ins PredRegs:$src1, IntRegs:$src2),
104 "if ($src1) $dst = aslh($src2)",
108 def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
109 (ins PredRegs:$src1, IntRegs:$src2),
110 "if (!$src1) $dst = aslh($src2)",
114 def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
115 (ins PredRegs:$src1, IntRegs:$src2),
116 "if ($src1.new) $dst = aslh($src2)",
120 def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
121 (ins PredRegs:$src1, IntRegs:$src2),
122 "if (!$src1.new) $dst = aslh($src2)",
126 def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
127 (ins PredRegs:$src1, IntRegs:$src2),
128 "if ($src1) $dst = asrh($src2)",
132 def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
133 (ins PredRegs:$src1, IntRegs:$src2),
134 "if (!$src1) $dst = asrh($src2)",
138 def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
139 (ins PredRegs:$src1, IntRegs:$src2),
140 "if ($src1.new) $dst = asrh($src2)",
144 def ASRH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
145 (ins PredRegs:$src1, IntRegs:$src2),
146 "if (!$src1.new) $dst = asrh($src2)",
153 let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
154 def SXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
155 (ins PredRegs:$src1, IntRegs:$src2),
156 "if ($src1) $dst = sxtb($src2)",
160 def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
161 (ins PredRegs:$src1, IntRegs:$src2),
162 "if (!$src1) $dst = sxtb($src2)",
166 def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
167 (ins PredRegs:$src1, IntRegs:$src2),
168 "if ($src1.new) $dst = sxtb($src2)",
172 def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
173 (ins PredRegs:$src1, IntRegs:$src2),
174 "if (!$src1.new) $dst = sxtb($src2)",
179 def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
180 (ins PredRegs:$src1, IntRegs:$src2),
181 "if ($src1) $dst = sxth($src2)",
185 def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
186 (ins PredRegs:$src1, IntRegs:$src2),
187 "if (!$src1) $dst = sxth($src2)",
191 def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
192 (ins PredRegs:$src1, IntRegs:$src2),
193 "if ($src1.new) $dst = sxth($src2)",
197 def SXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
198 (ins PredRegs:$src1, IntRegs:$src2),
199 "if (!$src1.new) $dst = sxth($src2)",
206 let neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in {
207 def ZXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
208 (ins PredRegs:$src1, IntRegs:$src2),
209 "if ($src1) $dst = zxtb($src2)",
213 def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
214 (ins PredRegs:$src1, IntRegs:$src2),
215 "if (!$src1) $dst = zxtb($src2)",
219 def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
220 (ins PredRegs:$src1, IntRegs:$src2),
221 "if ($src1.new) $dst = zxtb($src2)",
225 def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
226 (ins PredRegs:$src1, IntRegs:$src2),
227 "if (!$src1.new) $dst = zxtb($src2)",
231 def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
232 (ins PredRegs:$src1, IntRegs:$src2),
233 "if ($src1) $dst = zxth($src2)",
237 def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
238 (ins PredRegs:$src1, IntRegs:$src2),
239 "if (!$src1) $dst = zxth($src2)",
243 def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
244 (ins PredRegs:$src1, IntRegs:$src2),
245 "if ($src1.new) $dst = zxth($src2)",
249 def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
250 (ins PredRegs:$src1, IntRegs:$src2),
251 "if (!$src1.new) $dst = zxth($src2)",
256 // Generate frame index addresses.
257 let neverHasSideEffects = 1, isReMaterializable = 1,
258 isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
259 def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
260 (ins IntRegs:$src1, s32Imm:$offset),
261 "$dst = add($src1, ##$offset)",
266 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
267 isExtentSigned = 1, opExtentBits = 8 in
268 def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd),
269 (ins IntRegs:$Rs, s8Ext:$s8),
270 "$Rd = cmp.eq($Rs, #$s8)",
271 [(set (i32 IntRegs:$Rd),
272 (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
273 s8ExtPred:$s8)))))]>,
276 // Preserve the TSTBIT generation
277 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
278 (i32 IntRegs:$src1))), 0)))),
279 (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
282 // Interfered with tstbit generation, above pattern preserves, see : tstbit.ll
284 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
285 isExtentSigned = 1, opExtentBits = 8 in
286 def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd),
287 (ins IntRegs:$Rs, s8Ext:$s8),
288 "$Rd = !cmp.eq($Rs, #$s8)",
289 [(set (i32 IntRegs:$Rd),
290 (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
291 s8ExtPred:$s8)))))]>,
295 let validSubTargets = HasV4SubT in
296 def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd),
297 (ins IntRegs:$Rs, IntRegs:$Rt),
298 "$Rd = cmp.eq($Rs, $Rt)",
299 [(set (i32 IntRegs:$Rd),
300 (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
305 let validSubTargets = HasV4SubT in
306 def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
307 (ins IntRegs:$Rs, IntRegs:$Rt),
308 "$Rd = !cmp.eq($Rs, $Rt)",
309 [(set (i32 IntRegs:$Rd),
310 (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
314 //===----------------------------------------------------------------------===//
316 //===----------------------------------------------------------------------===//
319 //===----------------------------------------------------------------------===//
321 //===----------------------------------------------------------------------===//
324 // Rdd=combine(Rs, #s8)
325 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
326 neverHasSideEffects = 1, validSubTargets = HasV4SubT in
327 def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst),
328 (ins IntRegs:$src1, s8Ext:$src2),
329 "$dst = combine($src1, #$src2)",
333 // Rdd=combine(#s8, Rs)
334 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
335 neverHasSideEffects = 1, validSubTargets = HasV4SubT in
336 def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
337 (ins s8Ext:$src1, IntRegs:$src2),
338 "$dst = combine(#$src1, $src2)",
342 def HexagonWrapperCombineRI_V4 :
343 SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>;
344 def HexagonWrapperCombineIR_V4 :
345 SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
347 def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
348 (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>,
351 def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
352 (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>,
355 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6,
356 neverHasSideEffects = 1, validSubTargets = HasV4SubT in
357 def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
358 (ins s8Imm:$src1, u6Ext:$src2),
359 "$dst = combine(#$src1, #$src2)",
363 //===----------------------------------------------------------------------===//
365 //===----------------------------------------------------------------------===//
367 //===----------------------------------------------------------------------===//
369 //===----------------------------------------------------------------------===//
371 // These absolute set addressing mode instructions accept immediate as
372 // an operand. We have duplicated these patterns to take global address.
374 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
375 validSubTargets = HasV4SubT in {
376 def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
377 (ins u0AlwaysExt:$addr),
378 "$dst1 = memd($dst2=##$addr)",
383 def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
384 (ins u0AlwaysExt:$addr),
385 "$dst1 = memb($dst2=##$addr)",
390 def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
391 (ins u0AlwaysExt:$addr),
392 "$dst1 = memh($dst2=##$addr)",
397 def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
398 (ins u0AlwaysExt:$addr),
399 "$dst1 = memub($dst2=##$addr)",
404 def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
405 (ins u0AlwaysExt:$addr),
406 "$dst1 = memuh($dst2=##$addr)",
411 def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
412 (ins u0AlwaysExt:$addr),
413 "$dst1 = memw($dst2=##$addr)",
418 // Following patterns are defined for absolute set addressing mode
419 // instruction which take global address as operand.
420 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
421 validSubTargets = HasV4SubT in {
422 def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
423 (ins globaladdressExt:$addr),
424 "$dst1 = memd($dst2=##$addr)",
429 def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
430 (ins globaladdressExt:$addr),
431 "$dst1 = memb($dst2=##$addr)",
436 def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
437 (ins globaladdressExt:$addr),
438 "$dst1 = memh($dst2=##$addr)",
443 def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
444 (ins globaladdressExt:$addr),
445 "$dst1 = memub($dst2=##$addr)",
450 def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
451 (ins globaladdressExt:$addr),
452 "$dst1 = memuh($dst2=##$addr)",
457 def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
458 (ins globaladdressExt:$addr),
459 "$dst1 = memw($dst2=##$addr)",
464 // multiclass for load instructions with base + register offset
466 multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
468 let PNewValue = !if(isPredNew, "new", "") in
469 def NAME : LDInst2<(outs RC:$dst),
470 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
471 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
472 ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
473 []>, Requires<[HasV4T]>;
476 multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
477 let PredSense = !if(PredNot, "false", "true") in {
478 defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
480 defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
484 let neverHasSideEffects = 1 in
485 multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
486 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
487 let isPredicable = 1 in
488 def NAME#_V4 : LDInst2<(outs RC:$dst),
489 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
490 "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
491 []>, Requires<[HasV4T]>;
493 let isPredicated = 1 in {
494 defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
495 defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
500 let addrMode = BaseRegOffset in {
501 defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, AddrModeRel;
502 defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, AddrModeRel;
503 defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
504 defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, AddrModeRel;
505 defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
506 defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, AddrModeRel;
509 // 'def pats' for load instructions with base + register offset and non-zero
510 // immediate value. Immediate value is used to left-shift the second
512 let AddedComplexity = 40 in {
513 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
514 (shl IntRegs:$src2, u2ImmPred:$offset)))),
515 (LDrib_indexed_shl_V4 IntRegs:$src1,
516 IntRegs:$src2, u2ImmPred:$offset)>,
519 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
520 (shl IntRegs:$src2, u2ImmPred:$offset)))),
521 (LDriub_indexed_shl_V4 IntRegs:$src1,
522 IntRegs:$src2, u2ImmPred:$offset)>,
525 def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
526 (shl IntRegs:$src2, u2ImmPred:$offset)))),
527 (LDriub_indexed_shl_V4 IntRegs:$src1,
528 IntRegs:$src2, u2ImmPred:$offset)>,
531 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
532 (shl IntRegs:$src2, u2ImmPred:$offset)))),
533 (LDrih_indexed_shl_V4 IntRegs:$src1,
534 IntRegs:$src2, u2ImmPred:$offset)>,
537 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
538 (shl IntRegs:$src2, u2ImmPred:$offset)))),
539 (LDriuh_indexed_shl_V4 IntRegs:$src1,
540 IntRegs:$src2, u2ImmPred:$offset)>,
543 def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
544 (shl IntRegs:$src2, u2ImmPred:$offset)))),
545 (LDriuh_indexed_shl_V4 IntRegs:$src1,
546 IntRegs:$src2, u2ImmPred:$offset)>,
549 def : Pat <(i32 (load (add IntRegs:$src1,
550 (shl IntRegs:$src2, u2ImmPred:$offset)))),
551 (LDriw_indexed_shl_V4 IntRegs:$src1,
552 IntRegs:$src2, u2ImmPred:$offset)>,
555 def : Pat <(i64 (load (add IntRegs:$src1,
556 (shl IntRegs:$src2, u2ImmPred:$offset)))),
557 (LDrid_indexed_shl_V4 IntRegs:$src1,
558 IntRegs:$src2, u2ImmPred:$offset)>,
563 // 'def pats' for load instruction base + register offset and
564 // zero immediate value.
565 let AddedComplexity = 10 in {
566 def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))),
567 (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
570 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
571 (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
574 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
575 (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
578 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))),
579 (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
582 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
583 (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
586 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
587 (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
590 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))),
591 (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
594 def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
595 (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
599 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
600 def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
601 (ins globaladdress:$global),
602 "$dst=memd(#$global)",
606 // if (Pv) Rtt=memd(##global)
607 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
608 validSubTargets = HasV4SubT in {
609 def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
610 (ins PredRegs:$src1, globaladdress:$global),
611 "if ($src1) $dst=memd(##$global)",
616 // if (!Pv) Rtt=memd(##global)
617 def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
618 (ins PredRegs:$src1, globaladdress:$global),
619 "if (!$src1) $dst=memd(##$global)",
623 // if (Pv) Rtt=memd(##global)
624 def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
625 (ins PredRegs:$src1, globaladdress:$global),
626 "if ($src1.new) $dst=memd(##$global)",
631 // if (!Pv) Rtt=memd(##global)
632 def LDd_GP_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
633 (ins PredRegs:$src1, globaladdress:$global),
634 "if (!$src1.new) $dst=memd(##$global)",
639 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
640 def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
641 (ins globaladdress:$global),
642 "$dst=memb(#$global)",
646 // if (Pv) Rt=memb(##global)
647 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
648 validSubTargets = HasV4SubT in {
649 def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
650 (ins PredRegs:$src1, globaladdress:$global),
651 "if ($src1) $dst=memb(##$global)",
655 // if (!Pv) Rt=memb(##global)
656 def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
657 (ins PredRegs:$src1, globaladdress:$global),
658 "if (!$src1) $dst=memb(##$global)",
662 // if (Pv) Rt=memb(##global)
663 def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
664 (ins PredRegs:$src1, globaladdress:$global),
665 "if ($src1.new) $dst=memb(##$global)",
669 // if (!Pv) Rt=memb(##global)
670 def LDb_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
671 (ins PredRegs:$src1, globaladdress:$global),
672 "if (!$src1.new) $dst=memb(##$global)",
677 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
678 def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
679 (ins globaladdress:$global),
680 "$dst=memub(#$global)",
684 // if (Pv) Rt=memub(##global)
685 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
686 validSubTargets = HasV4SubT in {
687 def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
688 (ins PredRegs:$src1, globaladdress:$global),
689 "if ($src1) $dst=memub(##$global)",
694 // if (!Pv) Rt=memub(##global)
695 def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
696 (ins PredRegs:$src1, globaladdress:$global),
697 "if (!$src1) $dst=memub(##$global)",
701 // if (Pv) Rt=memub(##global)
702 def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
703 (ins PredRegs:$src1, globaladdress:$global),
704 "if ($src1.new) $dst=memub(##$global)",
709 // if (!Pv) Rt=memub(##global)
710 def LDub_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
711 (ins PredRegs:$src1, globaladdress:$global),
712 "if (!$src1.new) $dst=memub(##$global)",
717 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
718 def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
719 (ins globaladdress:$global),
720 "$dst=memh(#$global)",
724 // if (Pv) Rt=memh(##global)
725 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
726 validSubTargets = HasV4SubT in {
727 def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
728 (ins PredRegs:$src1, globaladdress:$global),
729 "if ($src1) $dst=memh(##$global)",
733 // if (!Pv) Rt=memh(##global)
734 def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
735 (ins PredRegs:$src1, globaladdress:$global),
736 "if (!$src1) $dst=memh(##$global)",
740 // if (Pv) Rt=memh(##global)
741 def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
742 (ins PredRegs:$src1, globaladdress:$global),
743 "if ($src1.new) $dst=memh(##$global)",
747 // if (!Pv) Rt=memh(##global)
748 def LDh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
749 (ins PredRegs:$src1, globaladdress:$global),
750 "if (!$src1.new) $dst=memh(##$global)",
755 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
756 def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
757 (ins globaladdress:$global),
758 "$dst=memuh(#$global)",
762 // if (Pv) Rt=memuh(##global)
763 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
764 validSubTargets = HasV4SubT in {
765 def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
766 (ins PredRegs:$src1, globaladdress:$global),
767 "if ($src1) $dst=memuh(##$global)",
771 // if (!Pv) Rt=memuh(##global)
772 def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
773 (ins PredRegs:$src1, globaladdress:$global),
774 "if (!$src1) $dst=memuh(##$global)",
778 // if (Pv) Rt=memuh(##global)
779 def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
780 (ins PredRegs:$src1, globaladdress:$global),
781 "if ($src1.new) $dst=memuh(##$global)",
785 // if (!Pv) Rt=memuh(##global)
786 def LDuh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
787 (ins PredRegs:$src1, globaladdress:$global),
788 "if (!$src1.new) $dst=memuh(##$global)",
793 let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
794 def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
795 (ins globaladdress:$global),
796 "$dst=memw(#$global)",
800 // if (Pv) Rt=memw(##global)
801 let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
802 validSubTargets = HasV4SubT in {
803 def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
804 (ins PredRegs:$src1, globaladdress:$global),
805 "if ($src1) $dst=memw(##$global)",
810 // if (!Pv) Rt=memw(##global)
811 def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
812 (ins PredRegs:$src1, globaladdress:$global),
813 "if (!$src1) $dst=memw(##$global)",
817 // if (Pv) Rt=memw(##global)
818 def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
819 (ins PredRegs:$src1, globaladdress:$global),
820 "if ($src1.new) $dst=memw(##$global)",
825 // if (!Pv) Rt=memw(##global)
826 def LDw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
827 (ins PredRegs:$src1, globaladdress:$global),
828 "if (!$src1.new) $dst=memw(##$global)",
834 def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
835 (i64 (LDd_GP_V4 tglobaladdr:$global))>,
838 def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
839 (i32 (LDw_GP_V4 tglobaladdr:$global))>,
842 def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
843 (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
846 def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
847 (i32 (LDub_GP_V4 tglobaladdr:$global))>,
850 // Map from load(globaladdress) -> memw(#foo + 0)
851 let AddedComplexity = 100 in
852 def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
853 (i64 (LDd_GP_V4 tglobaladdr:$global))>,
856 // Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
857 let AddedComplexity = 100 in
858 def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
859 (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>,
862 // When the Interprocedural Global Variable optimizer realizes that a certain
863 // global variable takes only two constant values, it shrinks the global to
864 // a boolean. Catch those loads here in the following 3 patterns.
865 let AddedComplexity = 100 in
866 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
867 (i32 (LDb_GP_V4 tglobaladdr:$global))>,
870 let AddedComplexity = 100 in
871 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
872 (i32 (LDb_GP_V4 tglobaladdr:$global))>,
875 // Map from load(globaladdress) -> memb(#foo)
876 let AddedComplexity = 100 in
877 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
878 (i32 (LDb_GP_V4 tglobaladdr:$global))>,
881 // Map from load(globaladdress) -> memb(#foo)
882 let AddedComplexity = 100 in
883 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
884 (i32 (LDb_GP_V4 tglobaladdr:$global))>,
887 let AddedComplexity = 100 in
888 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
889 (i32 (LDub_GP_V4 tglobaladdr:$global))>,
892 // Map from load(globaladdress) -> memub(#foo)
893 let AddedComplexity = 100 in
894 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
895 (i32 (LDub_GP_V4 tglobaladdr:$global))>,
898 // Map from load(globaladdress) -> memh(#foo)
899 let AddedComplexity = 100 in
900 def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
901 (i32 (LDh_GP_V4 tglobaladdr:$global))>,
904 // Map from load(globaladdress) -> memh(#foo)
905 let AddedComplexity = 100 in
906 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
907 (i32 (LDh_GP_V4 tglobaladdr:$global))>,
910 // Map from load(globaladdress) -> memuh(#foo)
911 let AddedComplexity = 100 in
912 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
913 (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
916 // Map from load(globaladdress) -> memw(#foo)
917 let AddedComplexity = 100 in
918 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
919 (i32 (LDw_GP_V4 tglobaladdr:$global))>,
923 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
924 (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
928 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
929 (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>,
932 def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
933 (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
936 let AddedComplexity = 20 in
937 def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
938 s11_0ExtPred:$offset))),
939 (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
940 s11_0ExtPred:$offset)))>,
944 def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
945 (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
948 let AddedComplexity = 20 in
949 def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
950 s11_0ExtPred:$offset))),
951 (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
952 s11_0ExtPred:$offset)))>,
956 def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
957 (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
960 let AddedComplexity = 20 in
961 def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
962 s11_1ExtPred:$offset))),
963 (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
964 s11_1ExtPred:$offset)))>,
968 def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
969 (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
972 let AddedComplexity = 20 in
973 def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
974 s11_1ExtPred:$offset))),
975 (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
976 s11_1ExtPred:$offset)))>,
980 def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
981 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
984 let AddedComplexity = 100 in
985 def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
986 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
987 s11_2ExtPred:$offset)))>,
991 def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
992 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
995 let AddedComplexity = 100 in
996 def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
997 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
998 s11_2ExtPred:$offset)))>,
1003 //===----------------------------------------------------------------------===//
1005 //===----------------------------------------------------------------------===//
1007 //===----------------------------------------------------------------------===//
1009 //===----------------------------------------------------------------------===//
1011 /// Assumptions::: ****** DO NOT IGNORE ********
1012 /// 1. Make sure that in post increment store, the zero'th operand is always the
1013 /// post increment operand.
1014 /// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
1019 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1020 def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1021 (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
1022 "memd($dst1=##$src2) = $src1",
1027 def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1028 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1029 "memb($dst1=##$src2) = $src1",
1034 def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1035 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1036 "memh($dst1=##$src2) = $src1",
1041 def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1042 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1043 "memw($dst1=##$src2) = $src1",
1049 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1050 def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1051 (ins DoubleRegs:$src1, globaladdressExt:$src2),
1052 "memd($dst1=##$src2) = $src1",
1057 def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1058 (ins IntRegs:$src1, globaladdressExt:$src2),
1059 "memb($dst1=##$src2) = $src1",
1064 def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1065 (ins IntRegs:$src1, globaladdressExt:$src2),
1066 "memh($dst1=##$src2) = $src1",
1071 def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1072 (ins IntRegs:$src1, globaladdressExt:$src2),
1073 "memw($dst1=##$src2) = $src1",
1078 // multiclass for store instructions with base + register offset addressing
1080 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1082 let PNewValue = !if(isPredNew, "new", "") in
1083 def NAME : STInst2<(outs),
1084 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1086 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1087 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
1092 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1093 let PredSense = !if(PredNot, "false", "true") in {
1094 defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
1096 defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
1100 let isNVStorable = 1 in
1101 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
1102 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1103 let isPredicable = 1 in
1104 def NAME#_V4 : STInst2<(outs),
1105 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1106 mnemonic#"($src1+$src2<<#$src3) = $src4",
1110 let isPredicated = 1 in {
1111 defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
1112 defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
1117 // multiclass for new-value store instructions with base + register offset
1119 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1121 let PNewValue = !if(isPredNew, "new", "") in
1122 def NAME#_nv_V4 : NVInst_V4<(outs),
1123 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1125 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1126 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
1131 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1132 let PredSense = !if(PredNot, "false", "true") in {
1133 defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
1135 defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
1139 let mayStore = 1, isNVStore = 1 in
1140 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
1141 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1142 let isPredicable = 1 in
1143 def NAME#_nv_V4 : NVInst_V4<(outs),
1144 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1145 mnemonic#"($src1+$src2<<#$src3) = $src4.new",
1149 let isPredicated = 1 in {
1150 defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
1151 defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
1156 let addrMode = BaseRegOffset, neverHasSideEffects = 1,
1157 validSubTargets = HasV4SubT in {
1158 defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
1159 ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
1161 defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
1162 ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
1164 defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
1165 ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
1167 let isNVStorable = 0 in
1168 defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
1171 let Predicates = [HasV4T], AddedComplexity = 10 in {
1172 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
1173 (add IntRegs:$src1, (shl IntRegs:$src2,
1175 (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1176 u2ImmPred:$src3, IntRegs:$src4)>;
1178 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
1179 (add IntRegs:$src1, (shl IntRegs:$src2,
1181 (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1182 u2ImmPred:$src3, IntRegs:$src4)>;
1184 def : Pat<(store (i32 IntRegs:$src4),
1185 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1186 (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1187 u2ImmPred:$src3, IntRegs:$src4)>;
1189 def : Pat<(store (i64 DoubleRegs:$src4),
1190 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1191 (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1192 u2ImmPred:$src3, DoubleRegs:$src4)>;
1195 // memd(Ru<<#u2+#U6)=Rtt
1196 let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
1197 validSubTargets = HasV4SubT in
1198 def STrid_shl_V4 : STInst<(outs),
1199 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
1200 "memd($src1<<#$src2+#$src3) = $src4",
1201 [(store (i64 DoubleRegs:$src4),
1202 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1203 u0AlwaysExtPred:$src3))]>,
1206 // memd(Rx++#s4:3)=Rtt
1207 // memd(Rx++#s4:3:circ(Mu))=Rtt
1208 // memd(Rx++I:circ(Mu))=Rtt
1210 // memd(Rx++Mu:brev)=Rtt
1211 // memd(gp+#u16:3)=Rtt
1213 // Store doubleword conditionally.
1214 // if ([!]Pv[.new]) memd(#u6)=Rtt
1215 // TODO: needs to be implemented.
1217 //===----------------------------------------------------------------------===//
1218 // multiclass for store instructions with base + immediate offset
1219 // addressing mode and immediate stored value.
1220 // mem[bhw](Rx++#s4:3)=#s8
1221 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
1222 //===----------------------------------------------------------------------===//
1223 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
1225 let PNewValue = !if(isPredNew, "new", "") in
1226 def NAME : STInst2<(outs),
1227 (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
1228 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1229 ") ")#mnemonic#"($src2+#$src3) = #$src4",
1234 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
1235 let PredSense = !if(PredNot, "false", "true") in {
1236 defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
1238 defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
1242 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
1243 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
1244 let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
1245 let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
1246 def NAME#_V4 : STInst2<(outs),
1247 (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
1248 mnemonic#"($src1+#$src2) = #$src3",
1252 let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
1253 defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
1254 defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
1259 let addrMode = BaseImmOffset, InputType = "imm",
1260 validSubTargets = HasV4SubT in {
1261 defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
1262 defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
1263 defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
1266 let Predicates = [HasV4T], AddedComplexity = 10 in {
1267 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
1268 (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
1270 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
1271 u6_1ImmPred:$src2)),
1272 (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
1274 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
1275 (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
1278 let AddedComplexity = 6 in
1279 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1280 (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1283 // memb(Ru<<#u2+#U6)=Rt
1284 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1285 validSubTargets = HasV4SubT in
1286 def STrib_shl_V4 : STInst<(outs),
1287 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1288 "memb($src1<<#$src2+#$src3) = $src4",
1289 [(truncstorei8 (i32 IntRegs:$src4),
1290 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1291 u0AlwaysExtPred:$src3))]>,
1294 // memb(Rx++#s4:0:circ(Mu))=Rt
1295 // memb(Rx++I:circ(Mu))=Rt
1297 // memb(Rx++Mu:brev)=Rt
1298 // memb(gp+#u16:0)=Rt
1302 // TODO: needs to be implemented
1303 // memh(Re=#U6)=Rt.H
1304 // memh(Rs+#s11:1)=Rt.H
1305 let AddedComplexity = 6 in
1306 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1307 (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1310 // memh(Rs+Ru<<#u2)=Rt.H
1311 // TODO: needs to be implemented.
1313 // memh(Ru<<#u2+#U6)=Rt.H
1314 // memh(Ru<<#u2+#U6)=Rt
1315 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1316 validSubTargets = HasV4SubT in
1317 def STrih_shl_V4 : STInst<(outs),
1318 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1319 "memh($src1<<#$src2+#$src3) = $src4",
1320 [(truncstorei16 (i32 IntRegs:$src4),
1321 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1322 u0AlwaysExtPred:$src3))]>,
1325 // memh(Rx++#s4:1:circ(Mu))=Rt.H
1326 // memh(Rx++#s4:1:circ(Mu))=Rt
1327 // memh(Rx++I:circ(Mu))=Rt.H
1328 // memh(Rx++I:circ(Mu))=Rt
1329 // memh(Rx++Mu)=Rt.H
1331 // memh(Rx++Mu:brev)=Rt.H
1332 // memh(Rx++Mu:brev)=Rt
1333 // memh(gp+#u16:1)=Rt
1334 // if ([!]Pv[.new]) memh(#u6)=Rt.H
1335 // if ([!]Pv[.new]) memh(#u6)=Rt
1338 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
1339 // TODO: needs to be implemented.
1341 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
1342 // TODO: Needs to be implemented.
1346 // TODO: Needs to be implemented.
1349 let neverHasSideEffects = 1 in
1350 def STriw_pred_V4 : STInst2<(outs),
1351 (ins MEMri:$addr, PredRegs:$src1),
1352 "Error; should not emit",
1356 let AddedComplexity = 6 in
1357 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
1358 (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1361 // memw(Ru<<#u2+#U6)=Rt
1362 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1363 validSubTargets = HasV4SubT in
1364 def STriw_shl_V4 : STInst<(outs),
1365 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1366 "memw($src1<<#$src2+#$src3) = $src4",
1367 [(store (i32 IntRegs:$src4),
1368 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1369 u0AlwaysExtPred:$src3))]>,
1372 // memw(Rx++#s4:2)=Rt
1373 // memw(Rx++#s4:2:circ(Mu))=Rt
1374 // memw(Rx++I:circ(Mu))=Rt
1376 // memw(Rx++Mu:brev)=Rt
1377 // memw(gp+#u16:2)=Rt
1380 // memd(#global)=Rtt
1381 let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1,
1382 validSubTargets = HasV4SubT in
1383 def STd_GP_V4 : STInst2<(outs),
1384 (ins globaladdress:$global, DoubleRegs:$src),
1385 "memd(#$global) = $src",
1389 // if (Pv) memd(##global) = Rtt
1390 let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1,
1391 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1392 def STd_GP_cPt_V4 : STInst2<(outs),
1393 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1394 "if ($src1) memd(##$global) = $src2",
1398 // if (!Pv) memd(##global) = Rtt
1399 def STd_GP_cNotPt_V4 : STInst2<(outs),
1400 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1401 "if (!$src1) memd(##$global) = $src2",
1405 // if (Pv) memd(##global) = Rtt
1406 def STd_GP_cdnPt_V4 : STInst2<(outs),
1407 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1408 "if ($src1.new) memd(##$global) = $src2",
1412 // if (!Pv) memd(##global) = Rtt
1413 def STd_GP_cdnNotPt_V4 : STInst2<(outs),
1414 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1415 "if (!$src1.new) memd(##$global) = $src2",
1421 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1422 validSubTargets = HasV4SubT in
1423 def STb_GP_V4 : STInst2<(outs),
1424 (ins globaladdress:$global, IntRegs:$src),
1425 "memb(#$global) = $src",
1429 // if (Pv) memb(##global) = Rt
1430 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1431 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1432 def STb_GP_cPt_V4 : STInst2<(outs),
1433 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1434 "if ($src1) memb(##$global) = $src2",
1438 // if (!Pv) memb(##global) = Rt
1439 def STb_GP_cNotPt_V4 : STInst2<(outs),
1440 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1441 "if (!$src1) memb(##$global) = $src2",
1445 // if (Pv) memb(##global) = Rt
1446 def STb_GP_cdnPt_V4 : STInst2<(outs),
1447 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1448 "if ($src1.new) memb(##$global) = $src2",
1452 // if (!Pv) memb(##global) = Rt
1453 def STb_GP_cdnNotPt_V4 : STInst2<(outs),
1454 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1455 "if (!$src1.new) memb(##$global) = $src2",
1461 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1462 validSubTargets = HasV4SubT in
1463 def STh_GP_V4 : STInst2<(outs),
1464 (ins globaladdress:$global, IntRegs:$src),
1465 "memh(#$global) = $src",
1469 // if (Pv) memh(##global) = Rt
1470 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1471 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1472 def STh_GP_cPt_V4 : STInst2<(outs),
1473 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1474 "if ($src1) memh(##$global) = $src2",
1478 // if (!Pv) memh(##global) = Rt
1479 def STh_GP_cNotPt_V4 : STInst2<(outs),
1480 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1481 "if (!$src1) memh(##$global) = $src2",
1485 // if (Pv) memh(##global) = Rt
1486 def STh_GP_cdnPt_V4 : STInst2<(outs),
1487 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1488 "if ($src1.new) memh(##$global) = $src2",
1492 // if (!Pv) memh(##global) = Rt
1493 def STh_GP_cdnNotPt_V4 : STInst2<(outs),
1494 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1495 "if (!$src1.new) memh(##$global) = $src2",
1501 let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
1502 validSubTargets = HasV4SubT in
1503 def STw_GP_V4 : STInst2<(outs),
1504 (ins globaladdress:$global, IntRegs:$src),
1505 "memw(#$global) = $src",
1509 // if (Pv) memw(##global) = Rt
1510 let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
1511 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1512 def STw_GP_cPt_V4 : STInst2<(outs),
1513 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1514 "if ($src1) memw(##$global) = $src2",
1518 // if (!Pv) memw(##global) = Rt
1519 def STw_GP_cNotPt_V4 : STInst2<(outs),
1520 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1521 "if (!$src1) memw(##$global) = $src2",
1525 // if (Pv) memw(##global) = Rt
1526 def STw_GP_cdnPt_V4 : STInst2<(outs),
1527 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1528 "if ($src1.new) memw(##$global) = $src2",
1532 // if (!Pv) memw(##global) = Rt
1533 def STw_GP_cdnNotPt_V4 : STInst2<(outs),
1534 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1535 "if (!$src1.new) memw(##$global) = $src2",
1540 // 64 bit atomic store
1541 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
1542 (i64 DoubleRegs:$src1)),
1543 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1546 // Map from store(globaladdress) -> memd(#foo)
1547 let AddedComplexity = 100 in
1548 def : Pat <(store (i64 DoubleRegs:$src1),
1549 (HexagonCONST32_GP tglobaladdr:$global)),
1550 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1553 // 8 bit atomic store
1554 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
1555 (i32 IntRegs:$src1)),
1556 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1559 // Map from store(globaladdress) -> memb(#foo)
1560 let AddedComplexity = 100 in
1561 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
1562 (HexagonCONST32_GP tglobaladdr:$global)),
1563 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1566 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
1567 // to "r0 = 1; memw(#foo) = r0"
1568 let AddedComplexity = 100 in
1569 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
1570 (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
1573 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
1574 (i32 IntRegs:$src1)),
1575 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1578 // Map from store(globaladdress) -> memh(#foo)
1579 let AddedComplexity = 100 in
1580 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
1581 (HexagonCONST32_GP tglobaladdr:$global)),
1582 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1585 // 32 bit atomic store
1586 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
1587 (i32 IntRegs:$src1)),
1588 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1591 // Map from store(globaladdress) -> memw(#foo)
1592 let AddedComplexity = 100 in
1593 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
1594 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1597 //===----------------------------------------------------------------------===
1599 //===----------------------------------------------------------------------===
1602 //===----------------------------------------------------------------------===//
1604 //===----------------------------------------------------------------------===//
1606 // multiclass for new-value store instructions with base + immediate offset.
1608 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
1609 Operand predImmOp, bit isNot, bit isPredNew> {
1610 let PNewValue = !if(isPredNew, "new", "") in
1611 def NAME#_nv_V4 : NVInst_V4<(outs),
1612 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1613 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1614 ") ")#mnemonic#"($src2+#$src3) = $src4.new",
1619 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
1621 let PredSense = !if(PredNot, "false", "true") in {
1622 defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
1624 defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
1628 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
1629 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
1630 Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1631 bits<5> PredImmBits> {
1633 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1634 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1636 def NAME#_nv_V4 : NVInst_V4<(outs),
1637 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1638 mnemonic#"($src1+#$src2) = $src3.new",
1642 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1643 isPredicated = 1 in {
1644 defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
1645 defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
1650 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
1651 defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
1652 u6_0Ext, 11, 6>, AddrModeRel;
1653 defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
1654 u6_1Ext, 12, 7>, AddrModeRel;
1655 defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
1656 u6_2Ext, 13, 8>, AddrModeRel;
1659 // multiclass for new-value store instructions with base + immediate offset.
1660 // and MEMri operand.
1661 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1663 let PNewValue = !if(isPredNew, "new", "") in
1664 def NAME#_nv_V4 : NVInst_V4<(outs),
1665 (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1666 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1667 ") ")#mnemonic#"($addr) = $src2.new",
1672 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1673 let PredSense = !if(PredNot, "false", "true") in {
1674 defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
1677 defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
1681 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
1682 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
1683 bits<5> ImmBits, bits<5> PredImmBits> {
1685 let CextOpcode = CextOp, BaseOpcode = CextOp in {
1686 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1688 def NAME#_nv_V4 : NVInst_V4<(outs),
1689 (ins MEMri:$addr, RC:$src),
1690 mnemonic#"($addr) = $src.new",
1694 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1695 neverHasSideEffects = 1, isPredicated = 1 in {
1696 defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
1697 defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
1702 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1704 defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1705 defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1706 defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1709 // memb(Ru<<#u2+#U6)=Nt.new
1710 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1711 isNVStore = 1, validSubTargets = HasV4SubT in
1712 def STrib_shl_nv_V4 : NVInst_V4<(outs),
1713 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1714 "memb($src1<<#$src2+#$src3) = $src4.new",
1718 //===----------------------------------------------------------------------===//
1719 // Post increment store
1720 // mem[bhwd](Rx++#s4:[0123])=Nt.new
1721 //===----------------------------------------------------------------------===//
1723 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
1724 bit isNot, bit isPredNew> {
1725 let PNewValue = !if(isPredNew, "new", "") in
1726 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1727 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1728 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1729 ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1735 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
1736 Operand ImmOp, bit PredNot> {
1737 let PredSense = !if(PredNot, "false", "true") in {
1738 defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
1740 let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1741 defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
1745 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
1746 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
1749 let BaseOpcode = "POST_"#BaseOp in {
1750 let isPredicable = 1 in
1751 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1752 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1753 mnemonic#"($src1++#$offset) = $src2.new",
1758 let isPredicated = 1 in {
1759 defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
1760 defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
1765 let validSubTargets = HasV4SubT in {
1766 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1767 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1768 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1771 // memb(Rx++#s4:0:circ(Mu))=Nt.new
1772 // memb(Rx++I:circ(Mu))=Nt.new
1773 // memb(Rx++Mu)=Nt.new
1774 // memb(Rx++Mu:brev)=Nt.new
1776 // memb(#global)=Nt.new
1777 let mayStore = 1, neverHasSideEffects = 1 in
1778 def STb_GP_nv_V4 : NVInst_V4<(outs),
1779 (ins globaladdress:$global, IntRegs:$src),
1780 "memb(#$global) = $src.new",
1784 // memh(Ru<<#u2+#U6)=Nt.new
1785 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1786 isNVStore = 1, validSubTargets = HasV4SubT in
1787 def STrih_shl_nv_V4 : NVInst_V4<(outs),
1788 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1789 "memh($src1<<#$src2+#$src3) = $src4.new",
1793 // memh(Rx++#s4:1:circ(Mu))=Nt.new
1794 // memh(Rx++I:circ(Mu))=Nt.new
1795 // memh(Rx++Mu)=Nt.new
1796 // memh(Rx++Mu:brev)=Nt.new
1798 // memh(#global)=Nt.new
1799 let mayStore = 1, neverHasSideEffects = 1 in
1800 def STh_GP_nv_V4 : NVInst_V4<(outs),
1801 (ins globaladdress:$global, IntRegs:$src),
1802 "memh(#$global) = $src.new",
1806 // memw(Ru<<#u2+#U6)=Nt.new
1807 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1808 isNVStore = 1, validSubTargets = HasV4SubT in
1809 def STriw_shl_nv_V4 : NVInst_V4<(outs),
1810 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1811 "memw($src1<<#$src2+#$src3) = $src4.new",
1815 // memw(Rx++#s4:2:circ(Mu))=Nt.new
1816 // memw(Rx++I:circ(Mu))=Nt.new
1817 // memw(Rx++Mu)=Nt.new
1818 // memw(Rx++Mu:brev)=Nt.new
1819 // memw(gp+#u16:2)=Nt.new
1821 let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
1822 validSubTargets = HasV4SubT in
1823 def STw_GP_nv_V4 : NVInst_V4<(outs),
1824 (ins globaladdress:$global, IntRegs:$src),
1825 "memw(#$global) = $src.new",
1829 // if (Pv) memb(##global) = Rt
1830 let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
1831 isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
1832 def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
1833 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1834 "if ($src1) memb(##$global) = $src2.new",
1838 // if (!Pv) memb(##global) = Rt
1839 def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1840 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1841 "if (!$src1) memb(##$global) = $src2.new",
1845 // if (Pv) memb(##global) = Rt
1846 def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1847 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1848 "if ($src1.new) memb(##$global) = $src2.new",
1852 // if (!Pv) memb(##global) = Rt
1853 def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1854 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1855 "if (!$src1.new) memb(##$global) = $src2.new",
1859 // if (Pv) memh(##global) = Rt
1860 def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
1861 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1862 "if ($src1) memh(##$global) = $src2.new",
1866 // if (!Pv) memh(##global) = Rt
1867 def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1868 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1869 "if (!$src1) memh(##$global) = $src2.new",
1873 // if (Pv) memh(##global) = Rt
1874 def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1875 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1876 "if ($src1.new) memh(##$global) = $src2.new",
1880 // if (!Pv) memh(##global) = Rt
1881 def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1882 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1883 "if (!$src1.new) memh(##$global) = $src2.new",
1887 // if (Pv) memw(##global) = Rt
1888 def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
1889 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1890 "if ($src1) memw(##$global) = $src2.new",
1894 // if (!Pv) memw(##global) = Rt
1895 def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1896 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1897 "if (!$src1) memw(##$global) = $src2.new",
1901 // if (Pv) memw(##global) = Rt
1902 def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1903 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1904 "if ($src1.new) memw(##$global) = $src2.new",
1908 // if (!Pv) memw(##global) = Rt
1909 def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1910 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1911 "if (!$src1.new) memw(##$global) = $src2.new",
1916 //===----------------------------------------------------------------------===//
1918 //===----------------------------------------------------------------------===//
1920 //===----------------------------------------------------------------------===//
1922 //===----------------------------------------------------------------------===//
1924 multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
1925 def _ie_nv_V4 : NVInst_V4<(outs),
1926 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1927 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1928 !strconcat("($src1.new, $src2)) jump:",
1929 !strconcat(TakenStr, " $offset"))))),
1933 def _nv_V4 : NVInst_V4<(outs),
1934 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1935 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1936 !strconcat("($src1.new, $src2)) jump:",
1937 !strconcat(TakenStr, " $offset"))))),
1942 multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
1944 def _ie_nv_V4 : NVInst_V4<(outs),
1945 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1946 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1947 !strconcat("($src1, $src2.new)) jump:",
1948 !strconcat(TakenStr, " $offset"))))),
1952 def _nv_V4 : NVInst_V4<(outs),
1953 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1954 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1955 !strconcat("($src1, $src2.new)) jump:",
1956 !strconcat(TakenStr, " $offset"))))),
1961 multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
1962 def _ie_nv_V4 : NVInst_V4<(outs),
1963 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1964 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1965 !strconcat("($src1.new, #$src2)) jump:",
1966 !strconcat(TakenStr, " $offset"))))),
1970 def _nv_V4 : NVInst_V4<(outs),
1971 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1972 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1973 !strconcat("($src1.new, #$src2)) jump:",
1974 !strconcat(TakenStr, " $offset"))))),
1979 multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
1980 def _ie_nv_V4 : NVInst_V4<(outs),
1981 (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1982 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1983 !strconcat("($src1.new, #$src2)) jump:",
1984 !strconcat(TakenStr, " $offset"))))),
1988 def _nv_V4 : NVInst_V4<(outs),
1989 (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1990 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1991 !strconcat("($src1.new, #$src2)) jump:",
1992 !strconcat(TakenStr, " $offset"))))),
1997 multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
1999 def _ie_nv_V4 : NVInst_V4<(outs),
2000 (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2001 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2002 !strconcat("($src1.new, #$src2)) jump:",
2003 !strconcat(TakenStr, " $offset"))))),
2007 def _nv_V4 : NVInst_V4<(outs),
2008 (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2009 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2010 !strconcat("($src1.new, #$src2)) jump:",
2011 !strconcat(TakenStr, " $offset"))))),
2016 // Multiclass for regular dot new of Ist operand register.
2017 multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> {
2018 defm Pt : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
2019 defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
2022 // Multiclass for dot new of 2nd operand register.
2023 multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
2024 defm Pt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
2025 defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
2028 // Multiclass for 2nd operand immediate, including -1.
2029 multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
2030 defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2031 defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2032 defm Ptneg : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
2033 defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
2036 // Multiclass for 2nd operand immediate, excluding -1.
2037 multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
2038 defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2039 defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2042 // Multiclass for tstbit, where 2nd operand is always #0.
2043 multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
2044 defm Pt : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
2045 defm Pnt : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
2048 // Multiclass for GT.
2049 multiclass NVJ_type_rr_ri<string OpcStr> {
2050 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2051 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2052 defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2053 defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>;
2054 defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>;
2055 defm ri : NVJ_type_br_pred_imm<"", OpcStr>;
2058 // Multiclass for EQ.
2059 multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> {
2060 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2061 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2062 defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>;
2063 defm ri : NVJ_type_br_pred_imm<"", OpcStr>;
2066 // Multiclass for GTU.
2067 multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> {
2068 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2069 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2070 defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2071 defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>;
2072 defm riNot : NVJ_type_br_pred_imm_only<"!", OpcStr>;
2073 defm ri : NVJ_type_br_pred_imm_only<"", OpcStr>;
2076 // Multiclass for tstbit.
2077 multiclass NVJ_type_r0<string OpcStr> {
2078 defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
2079 defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>;
2082 // Base Multiclass for New Value Jump.
2083 multiclass NVJ_type {
2084 defm GT : NVJ_type_rr_ri<"cmp.gt">;
2085 defm EQ : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
2086 defm GTU : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
2087 defm TSTBIT : NVJ_type_r0<"tstbit">;
2090 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
2091 defm JMP_ : NVJ_type;
2094 //===----------------------------------------------------------------------===//
2096 //===----------------------------------------------------------------------===//
2098 //===----------------------------------------------------------------------===//
2100 //===----------------------------------------------------------------------===//
2102 // Add and accumulate.
2103 // Rd=add(Rs,add(Ru,#s6))
2104 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
2105 validSubTargets = HasV4SubT in
2106 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
2107 (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
2108 "$dst = add($src1, add($src2, #$src3))",
2109 [(set (i32 IntRegs:$dst),
2110 (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
2111 s6_16ExtPred:$src3)))]>,
2114 // Rd=add(Rs,sub(#s6,Ru))
2115 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2116 validSubTargets = HasV4SubT in
2117 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
2118 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2119 "$dst = add($src1, sub(#$src2, $src3))",
2120 [(set (i32 IntRegs:$dst),
2121 (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
2122 (i32 IntRegs:$src3))))]>,
2125 // Generates the same instruction as ADDr_SUBri_V4 but matches different
2127 // Rd=add(Rs,sub(#s6,Ru))
2128 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2129 validSubTargets = HasV4SubT in
2130 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
2131 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2132 "$dst = add($src1, sub(#$src2, $src3))",
2133 [(set (i32 IntRegs:$dst),
2134 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
2135 (i32 IntRegs:$src3)))]>,
2139 // Add or subtract doublewords with carry.
2141 // Rdd=add(Rss,Rtt,Px):carry
2143 // Rdd=sub(Rss,Rtt,Px):carry
2146 // Logical doublewords.
2147 // Rdd=and(Rtt,~Rss)
2148 let validSubTargets = HasV4SubT in
2149 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2150 (ins DoubleRegs:$src1, DoubleRegs:$src2),
2151 "$dst = and($src1, ~$src2)",
2152 [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
2153 (not (i64 DoubleRegs:$src2))))]>,
2157 let validSubTargets = HasV4SubT in
2158 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2159 (ins DoubleRegs:$src1, DoubleRegs:$src2),
2160 "$dst = or($src1, ~$src2)",
2161 [(set (i64 DoubleRegs:$dst),
2162 (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
2166 // Logical-logical doublewords.
2167 // Rxx^=xor(Rss,Rtt)
2168 let validSubTargets = HasV4SubT in
2169 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
2170 (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
2171 "$dst ^= xor($src2, $src3)",
2172 [(set (i64 DoubleRegs:$dst),
2173 (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
2174 (i64 DoubleRegs:$src3))))],
2179 // Logical-logical words.
2180 // Rx=or(Ru,and(Rx,#s10))
2181 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2182 validSubTargets = HasV4SubT in
2183 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
2184 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2185 "$dst = or($src1, and($src2, #$src3))",
2186 [(set (i32 IntRegs:$dst),
2187 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2188 s10ExtPred:$src3)))],
2192 // Rx[&|^]=and(Rs,Rt)
2194 let validSubTargets = HasV4SubT in
2195 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2196 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2197 "$dst &= and($src2, $src3)",
2198 [(set (i32 IntRegs:$dst),
2199 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2200 (i32 IntRegs:$src3))))],
2205 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
2206 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2207 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2208 "$dst |= and($src2, $src3)",
2209 [(set (i32 IntRegs:$dst),
2210 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2211 (i32 IntRegs:$src3))))],
2213 Requires<[HasV4T]>, ImmRegRel;
2216 let validSubTargets = HasV4SubT in
2217 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2218 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2219 "$dst ^= and($src2, $src3)",
2220 [(set (i32 IntRegs:$dst),
2221 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2222 (i32 IntRegs:$src3))))],
2226 // Rx[&|^]=and(Rs,~Rt)
2228 let validSubTargets = HasV4SubT in
2229 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2230 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2231 "$dst &= and($src2, ~$src3)",
2232 [(set (i32 IntRegs:$dst),
2233 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2234 (not (i32 IntRegs:$src3)))))],
2239 let validSubTargets = HasV4SubT in
2240 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2241 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2242 "$dst |= and($src2, ~$src3)",
2243 [(set (i32 IntRegs:$dst),
2244 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2245 (not (i32 IntRegs:$src3)))))],
2250 let validSubTargets = HasV4SubT in
2251 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2252 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2253 "$dst ^= and($src2, ~$src3)",
2254 [(set (i32 IntRegs:$dst),
2255 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2256 (not (i32 IntRegs:$src3)))))],
2260 // Rx[&|^]=or(Rs,Rt)
2262 let validSubTargets = HasV4SubT in
2263 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2264 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2265 "$dst &= or($src2, $src3)",
2266 [(set (i32 IntRegs:$dst),
2267 (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2268 (i32 IntRegs:$src3))))],
2273 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
2274 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2275 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2276 "$dst |= or($src2, $src3)",
2277 [(set (i32 IntRegs:$dst),
2278 (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2279 (i32 IntRegs:$src3))))],
2281 Requires<[HasV4T]>, ImmRegRel;
2284 let validSubTargets = HasV4SubT in
2285 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2286 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2287 "$dst ^= or($src2, $src3)",
2288 [(set (i32 IntRegs:$dst),
2289 (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2290 (i32 IntRegs:$src3))))],
2294 // Rx[&|^]=xor(Rs,Rt)
2296 let validSubTargets = HasV4SubT in
2297 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2298 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2299 "$dst &= xor($src2, $src3)",
2300 [(set (i32 IntRegs:$dst),
2301 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2302 (i32 IntRegs:$src3))))],
2307 let validSubTargets = HasV4SubT in
2308 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2309 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2310 "$dst |= xor($src2, $src3)",
2311 [(set (i32 IntRegs:$dst),
2312 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2313 (i32 IntRegs:$src3))))],
2318 let validSubTargets = HasV4SubT in
2319 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2320 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2321 "$dst ^= xor($src2, $src3)",
2322 [(set (i32 IntRegs:$dst),
2323 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2324 (i32 IntRegs:$src3))))],
2329 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2330 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
2331 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
2332 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2333 "$dst |= and($src2, #$src3)",
2334 [(set (i32 IntRegs:$dst),
2335 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2336 s10ExtPred:$src3)))],
2338 Requires<[HasV4T]>, ImmRegRel;
2341 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2342 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
2343 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
2344 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2345 "$dst |= or($src2, #$src3)",
2346 [(set (i32 IntRegs:$dst),
2347 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2348 s10ExtPred:$src3)))],
2350 Requires<[HasV4T]>, ImmRegRel;
2354 // Rd=modwrap(Rs,Rt)
2356 // Rd=cround(Rs,#u5)
2358 // Rd=round(Rs,#u5)[:sat]
2359 // Rd=round(Rs,Rt)[:sat]
2360 // Vector reduce add unsigned halfwords
2361 // Rd=vraddh(Rss,Rtt)
2363 // Rdd=vaddb(Rss,Rtt)
2364 // Vector conditional negate
2365 // Rdd=vcnegh(Rss,Rt)
2366 // Rxx+=vrcnegh(Rss,Rt)
2367 // Vector maximum bytes
2368 // Rdd=vmaxb(Rtt,Rss)
2369 // Vector reduce maximum halfwords
2370 // Rxx=vrmaxh(Rss,Ru)
2371 // Rxx=vrmaxuh(Rss,Ru)
2372 // Vector reduce maximum words
2373 // Rxx=vrmaxuw(Rss,Ru)
2374 // Rxx=vrmaxw(Rss,Ru)
2375 // Vector minimum bytes
2376 // Rdd=vminb(Rtt,Rss)
2377 // Vector reduce minimum halfwords
2378 // Rxx=vrminh(Rss,Ru)
2379 // Rxx=vrminuh(Rss,Ru)
2380 // Vector reduce minimum words
2381 // Rxx=vrminuw(Rss,Ru)
2382 // Rxx=vrminw(Rss,Ru)
2383 // Vector subtract bytes
2384 // Rdd=vsubb(Rss,Rtt)
2386 //===----------------------------------------------------------------------===//
2388 //===----------------------------------------------------------------------===//
2391 //===----------------------------------------------------------------------===//
2393 //===----------------------------------------------------------------------===//
2395 // Multiply and user lower result.
2396 // Rd=add(#u6,mpyi(Rs,#U6))
2397 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2398 validSubTargets = HasV4SubT in
2399 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
2400 (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
2401 "$dst = add(#$src1, mpyi($src2, #$src3))",
2402 [(set (i32 IntRegs:$dst),
2403 (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2404 u6ExtPred:$src1))]>,
2407 // Rd=add(##,mpyi(Rs,#U6))
2408 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2409 (HexagonCONST32 tglobaladdr:$src1)),
2410 (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
2413 // Rd=add(#u6,mpyi(Rs,Rt))
2414 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2415 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2416 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
2417 (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
2418 "$dst = add(#$src1, mpyi($src2, $src3))",
2419 [(set (i32 IntRegs:$dst),
2420 (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2421 u6ExtPred:$src1))]>,
2422 Requires<[HasV4T]>, ImmRegRel;
2424 // Rd=add(##,mpyi(Rs,Rt))
2425 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2426 (HexagonCONST32 tglobaladdr:$src1)),
2427 (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
2430 // Rd=add(Ru,mpyi(#u6:2,Rs))
2431 let validSubTargets = HasV4SubT in
2432 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
2433 (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
2434 "$dst = add($src1, mpyi(#$src2, $src3))",
2435 [(set (i32 IntRegs:$dst),
2436 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
2437 u6_2ImmPred:$src2)))]>,
2440 // Rd=add(Ru,mpyi(Rs,#u6))
2441 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
2442 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2443 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
2444 (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
2445 "$dst = add($src1, mpyi($src2, #$src3))",
2446 [(set (i32 IntRegs:$dst),
2447 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2448 u6ExtPred:$src3)))]>,
2449 Requires<[HasV4T]>, ImmRegRel;
2451 // Rx=add(Ru,mpyi(Rx,Rs))
2452 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
2453 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
2454 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
2455 "$dst = add($src1, mpyi($src2, $src3))",
2456 [(set (i32 IntRegs:$dst),
2457 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2458 (i32 IntRegs:$src3))))],
2460 Requires<[HasV4T]>, ImmRegRel;
2463 // Polynomial multiply words
2465 // Rxx^=pmpyw(Rs,Rt)
2467 // Vector reduce multiply word by signed half (32x16)
2468 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
2469 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2470 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
2471 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
2473 // Multiply and use upper result
2474 // Rd=mpy(Rs,Rt.H):<<1:sat
2475 // Rd=mpy(Rs,Rt.L):<<1:sat
2476 // Rd=mpy(Rs,Rt):<<1
2477 // Rd=mpy(Rs,Rt):<<1:sat
2479 // Rx+=mpy(Rs,Rt):<<1:sat
2480 // Rx-=mpy(Rs,Rt):<<1:sat
2482 // Vector multiply bytes
2483 // Rdd=vmpybsu(Rs,Rt)
2484 // Rdd=vmpybu(Rs,Rt)
2485 // Rxx+=vmpybsu(Rs,Rt)
2486 // Rxx+=vmpybu(Rs,Rt)
2488 // Vector polynomial multiply halfwords
2489 // Rdd=vpmpyh(Rs,Rt)
2490 // Rxx^=vpmpyh(Rs,Rt)
2492 //===----------------------------------------------------------------------===//
2494 //===----------------------------------------------------------------------===//
2497 //===----------------------------------------------------------------------===//
2499 //===----------------------------------------------------------------------===//
2501 // Shift by immediate and accumulate.
2502 // Rx=add(#u8,asl(Rx,#U5))
2503 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2504 validSubTargets = HasV4SubT in
2505 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2506 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2507 "$dst = add(#$src1, asl($src2, #$src3))",
2508 [(set (i32 IntRegs:$dst),
2509 (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2514 // Rx=add(#u8,lsr(Rx,#U5))
2515 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2516 validSubTargets = HasV4SubT in
2517 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2518 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2519 "$dst = add(#$src1, lsr($src2, #$src3))",
2520 [(set (i32 IntRegs:$dst),
2521 (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2526 // Rx=sub(#u8,asl(Rx,#U5))
2527 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2528 validSubTargets = HasV4SubT in
2529 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2530 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2531 "$dst = sub(#$src1, asl($src2, #$src3))",
2532 [(set (i32 IntRegs:$dst),
2533 (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2538 // Rx=sub(#u8,lsr(Rx,#U5))
2539 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2540 validSubTargets = HasV4SubT in
2541 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2542 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2543 "$dst = sub(#$src1, lsr($src2, #$src3))",
2544 [(set (i32 IntRegs:$dst),
2545 (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2551 //Shift by immediate and logical.
2552 //Rx=and(#u8,asl(Rx,#U5))
2553 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2554 validSubTargets = HasV4SubT in
2555 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2556 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2557 "$dst = and(#$src1, asl($src2, #$src3))",
2558 [(set (i32 IntRegs:$dst),
2559 (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2564 //Rx=and(#u8,lsr(Rx,#U5))
2565 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2566 validSubTargets = HasV4SubT in
2567 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2568 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2569 "$dst = and(#$src1, lsr($src2, #$src3))",
2570 [(set (i32 IntRegs:$dst),
2571 (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2576 //Rx=or(#u8,asl(Rx,#U5))
2577 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2578 AddedComplexity = 30, validSubTargets = HasV4SubT in
2579 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2580 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2581 "$dst = or(#$src1, asl($src2, #$src3))",
2582 [(set (i32 IntRegs:$dst),
2583 (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2588 //Rx=or(#u8,lsr(Rx,#U5))
2589 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2590 AddedComplexity = 30, validSubTargets = HasV4SubT in
2591 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2592 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2593 "$dst = or(#$src1, lsr($src2, #$src3))",
2594 [(set (i32 IntRegs:$dst),
2595 (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2601 //Shift by register.
2603 let validSubTargets = HasV4SubT in {
2604 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
2605 "$dst = lsl(#$src1, $src2)",
2606 [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
2607 (i32 IntRegs:$src2)))]>,
2611 //Shift by register and logical.
2613 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2614 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2615 "$dst ^= asl($src2, $src3)",
2616 [(set (i64 DoubleRegs:$dst),
2617 (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
2618 (i32 IntRegs:$src3))))],
2623 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2624 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2625 "$dst ^= asr($src2, $src3)",
2626 [(set (i64 DoubleRegs:$dst),
2627 (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
2628 (i32 IntRegs:$src3))))],
2633 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2634 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2635 "$dst ^= lsl($src2, $src3)",
2636 [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
2637 (shl (i64 DoubleRegs:$src2),
2638 (i32 IntRegs:$src3))))],
2643 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2644 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2645 "$dst ^= lsr($src2, $src3)",
2646 [(set (i64 DoubleRegs:$dst),
2647 (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
2648 (i32 IntRegs:$src3))))],
2653 //===----------------------------------------------------------------------===//
2655 //===----------------------------------------------------------------------===//
2657 //===----------------------------------------------------------------------===//
2658 // MEMOP: Word, Half, Byte
2659 //===----------------------------------------------------------------------===//
2661 //===----------------------------------------------------------------------===//
2665 // MEMw_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
2666 // MEMw_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
2667 // MEMw_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
2668 // MEMw_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
2669 // MEMw_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
2670 // MEMw_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
2671 // MEMw_ADDi_V4 : memw(Rs+#u6:2)+=#U5
2672 // MEMw_SUBi_V4 : memw(Rs+#u6:2)-=#U5
2673 // MEMw_ADDr_V4 : memw(Rs+#u6:2)+=Rt
2674 // MEMw_SUBr_V4 : memw(Rs+#u6:2)-=Rt
2675 // MEMw_CLRr_V4 : memw(Rs+#u6:2)&=Rt
2676 // MEMw_SETr_V4 : memw(Rs+#u6:2)|=Rt
2679 // MEMw_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2680 // MEMw_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
2681 // MEMw_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2682 // MEMw_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
2683 //===----------------------------------------------------------------------===//
2687 // memw(Rs+#u6:2) += #U5
2688 let AddedComplexity = 30 in
2689 def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2690 (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
2691 "memw($base+#$offset) += #$addend",
2693 Requires<[HasV4T, UseMEMOP]>;
2695 // memw(Rs+#u6:2) -= #U5
2696 let AddedComplexity = 30 in
2697 def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2698 (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
2699 "memw($base+#$offset) -= #$subend",
2701 Requires<[HasV4T, UseMEMOP]>;
2703 // memw(Rs+#u6:2) += Rt
2704 let AddedComplexity = 30 in
2705 def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2706 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
2707 "memw($base+#$offset) += $addend",
2708 [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2709 (i32 IntRegs:$addend)),
2710 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2711 Requires<[HasV4T, UseMEMOP]>;
2713 // memw(Rs+#u6:2) -= Rt
2714 let AddedComplexity = 30 in
2715 def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2716 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
2717 "memw($base+#$offset) -= $subend",
2718 [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2719 (i32 IntRegs:$subend)),
2720 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2721 Requires<[HasV4T, UseMEMOP]>;
2723 // memw(Rs+#u6:2) &= Rt
2724 let AddedComplexity = 30 in
2725 def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2726 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
2727 "memw($base+#$offset) &= $andend",
2728 [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2729 (i32 IntRegs:$andend)),
2730 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2731 Requires<[HasV4T, UseMEMOP]>;
2733 // memw(Rs+#u6:2) |= Rt
2734 let AddedComplexity = 30 in
2735 def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2736 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
2737 "memw($base+#$offset) |= $orend",
2738 [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2739 (i32 IntRegs:$orend)),
2740 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2741 Requires<[HasV4T, UseMEMOP]>;
2743 // memw(Rs+#u6:2) += #U5
2744 let AddedComplexity = 30 in
2745 def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
2746 (ins MEMri:$addr, u5Imm:$addend),
2747 "memw($addr) += $addend",
2749 Requires<[HasV4T, UseMEMOP]>;
2751 // memw(Rs+#u6:2) -= #U5
2752 let AddedComplexity = 30 in
2753 def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
2754 (ins MEMri:$addr, u5Imm:$subend),
2755 "memw($addr) -= $subend",
2757 Requires<[HasV4T, UseMEMOP]>;
2759 // memw(Rs+#u6:2) += Rt
2760 let AddedComplexity = 30 in
2761 def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
2762 (ins MEMri:$addr, IntRegs:$addend),
2763 "memw($addr) += $addend",
2764 [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
2765 ADDRriU6_2:$addr)]>,
2766 Requires<[HasV4T, UseMEMOP]>;
2768 // memw(Rs+#u6:2) -= Rt
2769 let AddedComplexity = 30 in
2770 def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
2771 (ins MEMri:$addr, IntRegs:$subend),
2772 "memw($addr) -= $subend",
2773 [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
2774 ADDRriU6_2:$addr)]>,
2775 Requires<[HasV4T, UseMEMOP]>;
2777 // memw(Rs+#u6:2) &= Rt
2778 let AddedComplexity = 30 in
2779 def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
2780 (ins MEMri:$addr, IntRegs:$andend),
2781 "memw($addr) &= $andend",
2782 [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
2783 ADDRriU6_2:$addr)]>,
2784 Requires<[HasV4T, UseMEMOP]>;
2786 // memw(Rs+#u6:2) |= Rt
2787 let AddedComplexity = 30 in
2788 def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
2789 (ins MEMri:$addr, IntRegs:$orend),
2790 "memw($addr) |= $orend",
2791 [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
2792 ADDRriU6_2:$addr)]>,
2793 Requires<[HasV4T, UseMEMOP]>;
2795 //===----------------------------------------------------------------------===//
2799 // MEMh_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
2800 // MEMh_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
2801 // MEMh_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
2802 // MEMh_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
2803 // MEMh_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
2804 // MEMh_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
2805 // MEMh_ADDi_V4 : memw(Rs+#u6:2)+=#U5
2806 // MEMh_SUBi_V4 : memw(Rs+#u6:2)-=#U5
2807 // MEMh_ADDr_V4 : memw(Rs+#u6:2)+=Rt
2808 // MEMh_SUBr_V4 : memw(Rs+#u6:2)-=Rt
2809 // MEMh_CLRr_V4 : memw(Rs+#u6:2)&=Rt
2810 // MEMh_SETr_V4 : memw(Rs+#u6:2)|=Rt
2813 // MEMh_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2814 // MEMh_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
2815 // MEMh_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2816 // MEMh_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
2817 //===----------------------------------------------------------------------===//
2820 // memh(Rs+#u6:1) += #U5
2821 let AddedComplexity = 30 in
2822 def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2823 (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
2824 "memh($base+#$offset) += $addend",
2826 Requires<[HasV4T, UseMEMOP]>;
2828 // memh(Rs+#u6:1) -= #U5
2829 let AddedComplexity = 30 in
2830 def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2831 (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
2832 "memh($base+#$offset) -= $subend",
2834 Requires<[HasV4T, UseMEMOP]>;
2836 // memh(Rs+#u6:1) += Rt
2837 let AddedComplexity = 30 in
2838 def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2839 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
2840 "memh($base+#$offset) += $addend",
2841 [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
2842 u6_1ImmPred:$offset)),
2843 (i32 IntRegs:$addend)),
2844 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2845 Requires<[HasV4T, UseMEMOP]>;
2847 // memh(Rs+#u6:1) -= Rt
2848 let AddedComplexity = 30 in
2849 def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2850 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
2851 "memh($base+#$offset) -= $subend",
2852 [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
2853 u6_1ImmPred:$offset)),
2854 (i32 IntRegs:$subend)),
2855 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2856 Requires<[HasV4T, UseMEMOP]>;
2858 // memh(Rs+#u6:1) &= Rt
2859 let AddedComplexity = 30 in
2860 def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2861 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
2862 "memh($base+#$offset) += $andend",
2863 [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
2864 u6_1ImmPred:$offset)),
2865 (i32 IntRegs:$andend)),
2866 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2867 Requires<[HasV4T, UseMEMOP]>;
2869 // memh(Rs+#u6:1) |= Rt
2870 let AddedComplexity = 30 in
2871 def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2872 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
2873 "memh($base+#$offset) |= $orend",
2874 [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
2875 u6_1ImmPred:$offset)),
2876 (i32 IntRegs:$orend)),
2877 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2878 Requires<[HasV4T, UseMEMOP]>;
2880 // memh(Rs+#u6:1) += #U5
2881 let AddedComplexity = 30 in
2882 def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
2883 (ins MEMri:$addr, u5Imm:$addend),
2884 "memh($addr) += $addend",
2886 Requires<[HasV4T, UseMEMOP]>;
2888 // memh(Rs+#u6:1) -= #U5
2889 let AddedComplexity = 30 in
2890 def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
2891 (ins MEMri:$addr, u5Imm:$subend),
2892 "memh($addr) -= $subend",
2894 Requires<[HasV4T, UseMEMOP]>;
2896 // memh(Rs+#u6:1) += Rt
2897 let AddedComplexity = 30 in
2898 def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
2899 (ins MEMri:$addr, IntRegs:$addend),
2900 "memh($addr) += $addend",
2901 [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
2902 (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
2903 Requires<[HasV4T, UseMEMOP]>;
2905 // memh(Rs+#u6:1) -= Rt
2906 let AddedComplexity = 30 in
2907 def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
2908 (ins MEMri:$addr, IntRegs:$subend),
2909 "memh($addr) -= $subend",
2910 [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
2911 (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
2912 Requires<[HasV4T, UseMEMOP]>;
2914 // memh(Rs+#u6:1) &= Rt
2915 let AddedComplexity = 30 in
2916 def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
2917 (ins MEMri:$addr, IntRegs:$andend),
2918 "memh($addr) &= $andend",
2919 [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
2920 (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
2921 Requires<[HasV4T, UseMEMOP]>;
2923 // memh(Rs+#u6:1) |= Rt
2924 let AddedComplexity = 30 in
2925 def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
2926 (ins MEMri:$addr, IntRegs:$orend),
2927 "memh($addr) |= $orend",
2928 [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
2929 (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
2930 Requires<[HasV4T, UseMEMOP]>;
2933 //===----------------------------------------------------------------------===//
2937 // MEMb_ADDi_indexed_V4 : memb(Rs+#u6:0)+=#U5
2938 // MEMb_SUBi_indexed_V4 : memb(Rs+#u6:0)-=#U5
2939 // MEMb_ADDr_indexed_V4 : memb(Rs+#u6:0)+=Rt
2940 // MEMb_SUBr_indexed_V4 : memb(Rs+#u6:0)-=Rt
2941 // MEMb_CLRr_indexed_V4 : memb(Rs+#u6:0)&=Rt
2942 // MEMb_SETr_indexed_V4 : memb(Rs+#u6:0)|=Rt
2943 // MEMb_ADDi_V4 : memb(Rs+#u6:0)+=#U5
2944 // MEMb_SUBi_V4 : memb(Rs+#u6:0)-=#U5
2945 // MEMb_ADDr_V4 : memb(Rs+#u6:0)+=Rt
2946 // MEMb_SUBr_V4 : memb(Rs+#u6:0)-=Rt
2947 // MEMb_CLRr_V4 : memb(Rs+#u6:0)&=Rt
2948 // MEMb_SETr_V4 : memb(Rs+#u6:0)|=Rt
2951 // MEMb_CLRi_indexed_V4 : memb(Rs+#u6:0)=clrbit(#U5)
2952 // MEMb_SETi_indexed_V4 : memb(Rs+#u6:0)=setbit(#U5)
2953 // MEMb_CLRi_V4 : memb(Rs+#u6:0)=clrbit(#U5)
2954 // MEMb_SETi_V4 : memb(Rs+#u6:0)=setbit(#U5)
2955 //===----------------------------------------------------------------------===//
2957 // memb(Rs+#u6:0) += #U5
2958 let AddedComplexity = 30 in
2959 def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2960 (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
2961 "memb($base+#$offset) += $addend",
2963 Requires<[HasV4T, UseMEMOP]>;
2965 // memb(Rs+#u6:0) -= #U5
2966 let AddedComplexity = 30 in
2967 def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2968 (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
2969 "memb($base+#$offset) -= $subend",
2971 Requires<[HasV4T, UseMEMOP]>;
2973 // memb(Rs+#u6:0) += Rt
2974 let AddedComplexity = 30 in
2975 def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2976 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
2977 "memb($base+#$offset) += $addend",
2978 [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
2979 u6_0ImmPred:$offset)),
2980 (i32 IntRegs:$addend)),
2981 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2982 Requires<[HasV4T, UseMEMOP]>;
2984 // memb(Rs+#u6:0) -= Rt
2985 let AddedComplexity = 30 in
2986 def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2987 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
2988 "memb($base+#$offset) -= $subend",
2989 [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
2990 u6_0ImmPred:$offset)),
2991 (i32 IntRegs:$subend)),
2992 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2993 Requires<[HasV4T, UseMEMOP]>;
2995 // memb(Rs+#u6:0) &= Rt
2996 let AddedComplexity = 30 in
2997 def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2998 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
2999 "memb($base+#$offset) += $andend",
3000 [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
3001 u6_0ImmPred:$offset)),
3002 (i32 IntRegs:$andend)),
3003 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3004 Requires<[HasV4T, UseMEMOP]>;
3006 // memb(Rs+#u6:0) |= Rt
3007 let AddedComplexity = 30 in
3008 def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
3009 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
3010 "memb($base+#$offset) |= $orend",
3011 [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
3012 u6_0ImmPred:$offset)),
3013 (i32 IntRegs:$orend)),
3014 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3015 Requires<[HasV4T, UseMEMOP]>;
3017 // memb(Rs+#u6:0) += #U5
3018 let AddedComplexity = 30 in
3019 def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
3020 (ins MEMri:$addr, u5Imm:$addend),
3021 "memb($addr) += $addend",
3023 Requires<[HasV4T, UseMEMOP]>;
3025 // memb(Rs+#u6:0) -= #U5
3026 let AddedComplexity = 30 in
3027 def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
3028 (ins MEMri:$addr, u5Imm:$subend),
3029 "memb($addr) -= $subend",
3031 Requires<[HasV4T, UseMEMOP]>;
3033 // memb(Rs+#u6:0) += Rt
3034 let AddedComplexity = 30 in
3035 def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
3036 (ins MEMri:$addr, IntRegs:$addend),
3037 "memb($addr) += $addend",
3038 [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
3039 (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
3040 Requires<[HasV4T, UseMEMOP]>;
3042 // memb(Rs+#u6:0) -= Rt
3043 let AddedComplexity = 30 in
3044 def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
3045 (ins MEMri:$addr, IntRegs:$subend),
3046 "memb($addr) -= $subend",
3047 [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
3048 (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
3049 Requires<[HasV4T, UseMEMOP]>;
3051 // memb(Rs+#u6:0) &= Rt
3052 let AddedComplexity = 30 in
3053 def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
3054 (ins MEMri:$addr, IntRegs:$andend),
3055 "memb($addr) &= $andend",
3056 [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
3057 (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
3058 Requires<[HasV4T, UseMEMOP]>;
3060 // memb(Rs+#u6:0) |= Rt
3061 let AddedComplexity = 30 in
3062 def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
3063 (ins MEMri:$addr, IntRegs:$orend),
3064 "memb($addr) |= $orend",
3065 [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
3066 (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
3067 Requires<[HasV4T, UseMEMOP]>;
3070 //===----------------------------------------------------------------------===//
3072 //===----------------------------------------------------------------------===//
3074 // Hexagon V4 only supports these flavors of byte/half compare instructions:
3075 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
3076 // hardware. However, compiler can still implement these patterns through
3077 // appropriate patterns combinations based on current implemented patterns.
3078 // The implemented patterns are: EQ/GT/GTU.
3079 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
3081 // Following instruction is not being extended as it results into the
3082 // incorrect code for negative numbers.
3083 // Pd=cmpb.eq(Rs,#u8)
3086 let isCompare = 1, validSubTargets = HasV4SubT in
3087 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
3088 (ins IntRegs:$src1, IntRegs:$src2),
3089 "$dst = !cmp.eq($src1, $src2)",
3090 [(set (i1 PredRegs:$dst),
3091 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
3094 // p=!cmp.eq(r1,#s10)
3095 let isCompare = 1, validSubTargets = HasV4SubT in
3096 def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
3097 (ins IntRegs:$src1, s10Ext:$src2),
3098 "$dst = !cmp.eq($src1, #$src2)",
3099 [(set (i1 PredRegs:$dst),
3100 (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
3104 let isCompare = 1, validSubTargets = HasV4SubT in
3105 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
3106 (ins IntRegs:$src1, IntRegs:$src2),
3107 "$dst = !cmp.gt($src1, $src2)",
3108 [(set (i1 PredRegs:$dst),
3109 (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3112 // p=!cmp.gt(r1,#s10)
3113 let isCompare = 1, validSubTargets = HasV4SubT in
3114 def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
3115 (ins IntRegs:$src1, s10Ext:$src2),
3116 "$dst = !cmp.gt($src1, #$src2)",
3117 [(set (i1 PredRegs:$dst),
3118 (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
3121 // p=!cmp.gtu(r1,r2)
3122 let isCompare = 1, validSubTargets = HasV4SubT in
3123 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
3124 (ins IntRegs:$src1, IntRegs:$src2),
3125 "$dst = !cmp.gtu($src1, $src2)",
3126 [(set (i1 PredRegs:$dst),
3127 (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3130 // p=!cmp.gtu(r1,#u9)
3131 let isCompare = 1, validSubTargets = HasV4SubT in
3132 def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
3133 (ins IntRegs:$src1, u9Ext:$src2),
3134 "$dst = !cmp.gtu($src1, #$src2)",
3135 [(set (i1 PredRegs:$dst),
3136 (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
3139 let isCompare = 1, validSubTargets = HasV4SubT in
3140 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
3141 (ins IntRegs:$src1, u8Imm:$src2),
3142 "$dst = cmpb.eq($src1, #$src2)",
3143 [(set (i1 PredRegs:$dst),
3144 (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
3147 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
3149 (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
3153 // Pd=cmpb.eq(Rs,Rt)
3154 let isCompare = 1, validSubTargets = HasV4SubT in
3155 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
3156 (ins IntRegs:$src1, IntRegs:$src2),
3157 "$dst = cmpb.eq($src1, $src2)",
3158 [(set (i1 PredRegs:$dst),
3159 (seteq (and (xor (i32 IntRegs:$src1),
3160 (i32 IntRegs:$src2)), 255), 0))]>,
3163 // Pd=cmpb.eq(Rs,Rt)
3164 let isCompare = 1, validSubTargets = HasV4SubT in
3165 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
3166 (ins IntRegs:$src1, IntRegs:$src2),
3167 "$dst = cmpb.eq($src1, $src2)",
3168 [(set (i1 PredRegs:$dst),
3169 (seteq (shl (i32 IntRegs:$src1), (i32 24)),
3170 (shl (i32 IntRegs:$src2), (i32 24))))]>,
3173 // Pd=cmpb.gt(Rs,Rt)
3174 let isCompare = 1, validSubTargets = HasV4SubT in
3175 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
3176 (ins IntRegs:$src1, IntRegs:$src2),
3177 "$dst = cmpb.gt($src1, $src2)",
3178 [(set (i1 PredRegs:$dst),
3179 (setgt (shl (i32 IntRegs:$src1), (i32 24)),
3180 (shl (i32 IntRegs:$src2), (i32 24))))]>,
3183 // Pd=cmpb.gtu(Rs,#u7)
3184 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3185 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
3186 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
3187 (ins IntRegs:$src1, u7Ext:$src2),
3188 "$dst = cmpb.gtu($src1, #$src2)",
3189 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3190 u7ExtPred:$src2))]>,
3191 Requires<[HasV4T]>, ImmRegRel;
3193 // SDNode for converting immediate C to C-1.
3194 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
3195 // Return the byte immediate const-1 as an SDNode.
3196 int32_t imm = N->getSExtValue();
3197 return XformU7ToU7M1Imm(imm);
3201 // zext( seteq ( and(Rs, 255), u8))
3203 // Pd=cmpb.eq(Rs, #u8)
3204 // if (Pd.new) Rd=#1
3205 // if (!Pd.new) Rd=#0
3206 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
3208 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3214 // zext( setne ( and(Rs, 255), u8))
3216 // Pd=cmpb.eq(Rs, #u8)
3217 // if (Pd.new) Rd=#0
3218 // if (!Pd.new) Rd=#1
3219 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
3221 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3227 // zext( seteq (Rs, and(Rt, 255)))
3229 // Pd=cmpb.eq(Rs, Rt)
3230 // if (Pd.new) Rd=#1
3231 // if (!Pd.new) Rd=#0
3232 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
3233 (i32 (and (i32 IntRegs:$Rs), 255)))))),
3234 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3235 (i32 IntRegs:$Rt))),
3240 // zext( setne (Rs, and(Rt, 255)))
3242 // Pd=cmpb.eq(Rs, Rt)
3243 // if (Pd.new) Rd=#0
3244 // if (!Pd.new) Rd=#1
3245 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
3246 (i32 (and (i32 IntRegs:$Rs), 255)))))),
3247 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3248 (i32 IntRegs:$Rt))),
3253 // zext( setugt ( and(Rs, 255), u8))
3255 // Pd=cmpb.gtu(Rs, #u8)
3256 // if (Pd.new) Rd=#1
3257 // if (!Pd.new) Rd=#0
3258 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
3260 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3266 // zext( setugt ( and(Rs, 254), u8))
3268 // Pd=cmpb.gtu(Rs, #u8)
3269 // if (Pd.new) Rd=#1
3270 // if (!Pd.new) Rd=#0
3271 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
3273 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3279 // zext( setult ( Rs, Rt))
3281 // Pd=cmp.ltu(Rs, Rt)
3282 // if (Pd.new) Rd=#1
3283 // if (!Pd.new) Rd=#0
3284 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3285 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3286 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3287 (i32 IntRegs:$Rs))),
3292 // zext( setlt ( Rs, Rt))
3294 // Pd=cmp.lt(Rs, Rt)
3295 // if (Pd.new) Rd=#1
3296 // if (!Pd.new) Rd=#0
3297 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3298 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3299 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3300 (i32 IntRegs:$Rs))),
3305 // zext( setugt ( Rs, Rt))
3307 // Pd=cmp.gtu(Rs, Rt)
3308 // if (Pd.new) Rd=#1
3309 // if (!Pd.new) Rd=#0
3310 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3311 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3312 (i32 IntRegs:$Rt))),
3316 // This pattern interefers with coremark performance, not implementing at this
3319 // zext( setgt ( Rs, Rt))
3321 // Pd=cmp.gt(Rs, Rt)
3322 // if (Pd.new) Rd=#1
3323 // if (!Pd.new) Rd=#0
3326 // zext( setuge ( Rs, Rt))
3328 // Pd=cmp.ltu(Rs, Rt)
3329 // if (Pd.new) Rd=#0
3330 // if (!Pd.new) Rd=#1
3331 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3332 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3333 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3334 (i32 IntRegs:$Rs))),
3339 // zext( setge ( Rs, Rt))
3341 // Pd=cmp.lt(Rs, Rt)
3342 // if (Pd.new) Rd=#0
3343 // if (!Pd.new) Rd=#1
3344 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3345 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3346 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3347 (i32 IntRegs:$Rs))),
3352 // zext( setule ( Rs, Rt))
3354 // Pd=cmp.gtu(Rs, Rt)
3355 // if (Pd.new) Rd=#0
3356 // if (!Pd.new) Rd=#1
3357 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3358 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3359 (i32 IntRegs:$Rt))),
3364 // zext( setle ( Rs, Rt))
3366 // Pd=cmp.gt(Rs, Rt)
3367 // if (Pd.new) Rd=#0
3368 // if (!Pd.new) Rd=#1
3369 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3370 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
3371 (i32 IntRegs:$Rt))),
3376 // zext( setult ( and(Rs, 255), u8))
3377 // Use the isdigit transformation below
3379 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
3380 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
3381 // The isdigit transformation relies on two 'clever' aspects:
3382 // 1) The data type is unsigned which allows us to eliminate a zero test after
3383 // biasing the expression by 48. We are depending on the representation of
3384 // the unsigned types, and semantics.
3385 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
3388 // retval = ((c>='0') & (c<='9')) ? 1 : 0;
3389 // The code is transformed upstream of llvm into
3390 // retval = (c-48) < 10 ? 1 : 0;
3391 let AddedComplexity = 139 in
3392 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
3393 u7StrictPosImmPred:$src2)))),
3394 (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
3395 (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
3399 // Pd=cmpb.gtu(Rs,Rt)
3400 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
3401 InputType = "reg" in
3402 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
3403 (ins IntRegs:$src1, IntRegs:$src2),
3404 "$dst = cmpb.gtu($src1, $src2)",
3405 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3406 (and (i32 IntRegs:$src2), 255)))]>,
3407 Requires<[HasV4T]>, ImmRegRel;
3409 // Following instruction is not being extended as it results into the incorrect
3410 // code for negative numbers.
3412 // Signed half compare(.eq) ri.
3413 // Pd=cmph.eq(Rs,#s8)
3414 let isCompare = 1, validSubTargets = HasV4SubT in
3415 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
3416 (ins IntRegs:$src1, s8Imm:$src2),
3417 "$dst = cmph.eq($src1, #$src2)",
3418 [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
3419 s8ImmPred:$src2))]>,
3422 // Signed half compare(.eq) rr.
3423 // Case 1: xor + and, then compare:
3425 // r0=and(r0,#0xffff)
3427 // Pd=cmph.eq(Rs,Rt)
3428 let isCompare = 1, validSubTargets = HasV4SubT in
3429 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
3430 (ins IntRegs:$src1, IntRegs:$src2),
3431 "$dst = cmph.eq($src1, $src2)",
3432 [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
3433 (i32 IntRegs:$src2)),
3437 // Signed half compare(.eq) rr.
3438 // Case 2: shift left 16 bits then compare:
3442 // Pd=cmph.eq(Rs,Rt)
3443 let isCompare = 1, validSubTargets = HasV4SubT in
3444 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
3445 (ins IntRegs:$src1, IntRegs:$src2),
3446 "$dst = cmph.eq($src1, $src2)",
3447 [(set (i1 PredRegs:$dst),
3448 (seteq (shl (i32 IntRegs:$src1), (i32 16)),
3449 (shl (i32 IntRegs:$src2), (i32 16))))]>,
3452 /* Incorrect Pattern -- immediate should be right shifted before being
3453 used in the cmph.gt instruction.
3454 // Signed half compare(.gt) ri.
3455 // Pd=cmph.gt(Rs,#s8)
3457 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
3458 isCompare = 1, validSubTargets = HasV4SubT in
3459 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
3460 (ins IntRegs:$src1, s8Ext:$src2),
3461 "$dst = cmph.gt($src1, #$src2)",
3462 [(set (i1 PredRegs:$dst),
3463 (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3464 s8ExtPred:$src2))]>,
3468 // Signed half compare(.gt) rr.
3469 // Pd=cmph.gt(Rs,Rt)
3470 let isCompare = 1, validSubTargets = HasV4SubT in
3471 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
3472 (ins IntRegs:$src1, IntRegs:$src2),
3473 "$dst = cmph.gt($src1, $src2)",
3474 [(set (i1 PredRegs:$dst),
3475 (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3476 (shl (i32 IntRegs:$src2), (i32 16))))]>,
3479 // Unsigned half compare rr (.gtu).
3480 // Pd=cmph.gtu(Rs,Rt)
3481 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3482 InputType = "reg" in
3483 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
3484 (ins IntRegs:$src1, IntRegs:$src2),
3485 "$dst = cmph.gtu($src1, $src2)",
3486 [(set (i1 PredRegs:$dst),
3487 (setugt (and (i32 IntRegs:$src1), 65535),
3488 (and (i32 IntRegs:$src2), 65535)))]>,
3489 Requires<[HasV4T]>, ImmRegRel;
3491 // Unsigned half compare ri (.gtu).
3492 // Pd=cmph.gtu(Rs,#u7)
3493 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3494 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3495 InputType = "imm" in
3496 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
3497 (ins IntRegs:$src1, u7Ext:$src2),
3498 "$dst = cmph.gtu($src1, #$src2)",
3499 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
3500 u7ExtPred:$src2))]>,
3501 Requires<[HasV4T]>, ImmRegRel;
3503 let validSubTargets = HasV4SubT in
3504 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
3505 "$dst = !tstbit($src1, $src2)",
3506 [(set (i1 PredRegs:$dst),
3507 (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
3510 let validSubTargets = HasV4SubT in
3511 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
3512 "$dst = !tstbit($src1, $src2)",
3513 [(set (i1 PredRegs:$dst),
3514 (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
3517 //===----------------------------------------------------------------------===//
3519 //===----------------------------------------------------------------------===//
3521 //Deallocate frame and return.
3523 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
3524 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
3525 def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
3531 // Restore registers and dealloc return function call.
3532 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3533 Defs = [R29, R30, R31, PC] in {
3534 def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
3535 (ins calltarget:$dst),
3536 "jump $dst // Restore_and_dealloc_return",
3541 // Restore registers and dealloc frame before a tail call.
3542 let isCall = 1, isBarrier = 1,
3543 Defs = [R29, R30, R31, PC] in {
3544 def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
3545 (ins calltarget:$dst),
3546 "call $dst // Restore_and_dealloc_before_tailcall",
3551 // Save registers function call.
3552 let isCall = 1, isBarrier = 1,
3553 Uses = [R29, R31] in {
3554 def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
3555 (ins calltarget:$dst),
3556 "call $dst // Save_calle_saved_registers",
3561 // if (Ps) dealloc_return
3562 let isReturn = 1, isTerminator = 1,
3563 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3564 isPredicated = 1 in {
3565 def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
3566 (ins PredRegs:$src1, i32imm:$amt1),
3567 "if ($src1) dealloc_return",
3572 // if (!Ps) dealloc_return
3573 let isReturn = 1, isTerminator = 1,
3574 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3575 isPredicated = 1 in {
3576 def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3578 "if (!$src1) dealloc_return",
3583 // if (Ps.new) dealloc_return:nt
3584 let isReturn = 1, isTerminator = 1,
3585 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3586 isPredicated = 1 in {
3587 def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3589 "if ($src1.new) dealloc_return:nt",
3594 // if (!Ps.new) dealloc_return:nt
3595 let isReturn = 1, isTerminator = 1,
3596 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3597 isPredicated = 1 in {
3598 def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3600 "if (!$src1.new) dealloc_return:nt",
3605 // if (Ps.new) dealloc_return:t
3606 let isReturn = 1, isTerminator = 1,
3607 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3608 isPredicated = 1 in {
3609 def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3611 "if ($src1.new) dealloc_return:t",
3616 // if (!Ps.new) dealloc_return:nt
3617 let isReturn = 1, isTerminator = 1,
3618 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3619 isPredicated = 1 in {
3620 def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3622 "if (!$src1.new) dealloc_return:t",
3627 // Load/Store with absolute addressing mode
3630 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3632 let PNewValue = !if(isPredNew, "new", "") in
3633 def NAME#_V4 : STInst2<(outs),
3634 (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3635 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3636 ") ")#mnemonic#"(##$absaddr) = $src2",
3641 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3642 let PredSense = !if(PredNot, "false", "true") in {
3643 defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3645 defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3649 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
3650 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3651 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3652 let opExtendable = 0, isPredicable = 1 in
3653 def NAME#_V4 : STInst2<(outs),
3654 (ins globaladdressExt:$absaddr, RC:$src),
3655 mnemonic#"(##$absaddr) = $src",
3659 let opExtendable = 1, isPredicated = 1 in {
3660 defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
3661 defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
3666 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
3668 let PNewValue = !if(isPredNew, "new", "") in
3669 def NAME#_nv_V4 : NVInst_V4<(outs),
3670 (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3671 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3672 ") ")#mnemonic#"(##$absaddr) = $src2.new",
3677 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
3678 let PredSense = !if(PredNot, "false", "true") in {
3679 defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
3681 defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
3685 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
3686 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
3687 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3688 let opExtendable = 0, isPredicable = 1 in
3689 def NAME#_nv_V4 : NVInst_V4<(outs),
3690 (ins globaladdressExt:$absaddr, RC:$src),
3691 mnemonic#"(##$absaddr) = $src.new",
3695 let opExtendable = 1, isPredicated = 1 in {
3696 defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
3697 defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
3702 let addrMode = Absolute in {
3703 defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
3704 ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
3706 defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
3707 ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
3709 defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
3710 ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
3712 let isNVStorable = 0 in
3713 defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
3716 let Predicates = [HasV4T], AddedComplexity = 30 in {
3717 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
3718 (HexagonCONST32 tglobaladdr:$absaddr)),
3719 (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3721 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
3722 (HexagonCONST32 tglobaladdr:$absaddr)),
3723 (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3725 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
3726 (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3728 def : Pat<(store (i64 DoubleRegs:$src1),
3729 (HexagonCONST32 tglobaladdr:$absaddr)),
3730 (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
3733 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3735 let PNewValue = !if(isPredNew, "new", "") in
3736 def NAME : LDInst2<(outs RC:$dst),
3737 (ins PredRegs:$src1, globaladdressExt:$absaddr),
3738 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3739 ") ")#"$dst = "#mnemonic#"(##$absaddr)",
3744 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3745 let PredSense = !if(PredNot, "false", "true") in {
3746 defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3748 defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3752 let isExtended = 1, neverHasSideEffects = 1 in
3753 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3754 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3755 let opExtendable = 1, isPredicable = 1 in
3756 def NAME#_V4 : LDInst2<(outs RC:$dst),
3757 (ins globaladdressExt:$absaddr),
3758 "$dst = "#mnemonic#"(##$absaddr)",
3762 let opExtendable = 2, isPredicated = 1 in {
3763 defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3764 defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3769 let addrMode = Absolute in {
3770 defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3771 defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
3772 defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3773 defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
3774 defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
3775 defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
3778 let Predicates = [HasV4T], AddedComplexity = 30 in
3779 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3780 (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3782 let Predicates = [HasV4T], AddedComplexity=30 in
3783 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3784 (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3786 let Predicates = [HasV4T], AddedComplexity=30 in
3787 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3788 (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3790 let Predicates = [HasV4T], AddedComplexity=30 in
3791 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3792 (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3794 let Predicates = [HasV4T], AddedComplexity=30 in
3795 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3796 (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
3798 // Transfer global address into a register
3799 let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
3800 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
3802 [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3805 // Transfer a block address into a register
3806 def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
3807 (TFRI_V4 tblockaddress:$src1)>,
3810 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3811 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3812 (ins PredRegs:$src1, globaladdress:$src2),
3813 "if($src1) $dst = ##$src2",
3817 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3818 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3819 (ins PredRegs:$src1, globaladdress:$src2),
3820 "if(!$src1) $dst = ##$src2",
3824 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3825 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3826 (ins PredRegs:$src1, globaladdress:$src2),
3827 "if($src1.new) $dst = ##$src2",
3831 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3832 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3833 (ins PredRegs:$src1, globaladdress:$src2),
3834 "if(!$src1.new) $dst = ##$src2",
3838 let AddedComplexity = 50, Predicates = [HasV4T] in
3839 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3840 (TFRI_V4 tglobaladdr:$src1)>;
3843 // Load - Indirect with long offset: These instructions take global address
3845 let AddedComplexity = 10 in
3846 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3847 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3848 "$dst=memd($src1<<#$src2+##$offset)",
3849 [(set (i64 DoubleRegs:$dst),
3850 (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3851 (HexagonCONST32 tglobaladdr:$offset))))]>,
3854 let AddedComplexity = 10 in
3855 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3856 def _lo_V4 : LDInst<(outs IntRegs:$dst),
3857 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3858 !strconcat("$dst = ",
3859 !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3861 (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3862 (HexagonCONST32 tglobaladdr:$offset)))))]>,
3866 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3867 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3868 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3869 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3870 defm LDriw_ind : LD_indirect_lo<"memw", load>;
3872 // Store - Indirect with long offset: These instructions take global address
3874 let AddedComplexity = 10 in
3875 def STrid_ind_lo_V4 : STInst<(outs),
3876 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3878 "memd($src1<<#$src2+#$src3) = $src4",
3879 [(store (i64 DoubleRegs:$src4),
3880 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3881 (HexagonCONST32 tglobaladdr:$src3)))]>,
3884 let AddedComplexity = 10 in
3885 multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
3886 def _lo_V4 : STInst<(outs),
3887 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3889 !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
3890 [(OpNode (i32 IntRegs:$src4),
3891 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3892 (HexagonCONST32 tglobaladdr:$src3)))]>,
3896 defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
3897 defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
3898 defm STriw_ind : ST_indirect_lo<"memw", store>;
3900 // Store - absolute addressing mode: These instruction take constant
3901 // value as the extended operand.
3902 multiclass ST_absimm<string OpcStr> {
3903 let isExtended = 1, opExtendable = 0, isPredicable = 1,
3904 validSubTargets = HasV4SubT in
3905 def _abs_V4 : STInst2<(outs),
3906 (ins u0AlwaysExt:$src1, IntRegs:$src2),
3907 !strconcat(OpcStr, "(##$src1) = $src2"),
3911 let isExtended = 1, opExtendable = 1, isPredicated = 1,
3912 validSubTargets = HasV4SubT in {
3913 def _abs_cPt_V4 : STInst2<(outs),
3914 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3915 !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3919 def _abs_cNotPt_V4 : STInst2<(outs),
3920 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3921 !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3925 def _abs_cdnPt_V4 : STInst2<(outs),
3926 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3927 !strconcat("if ($src1.new)",
3928 !strconcat(OpcStr, "(##$src2) = $src3")),
3932 def _abs_cdnNotPt_V4 : STInst2<(outs),
3933 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3934 !strconcat("if (!$src1.new)",
3935 !strconcat(OpcStr, "(##$src2) = $src3")),
3940 let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
3941 validSubTargets = HasV4SubT in
3942 def _abs_nv_V4 : NVInst_V4<(outs),
3943 (ins u0AlwaysExt:$src1, IntRegs:$src2),
3944 !strconcat(OpcStr, "(##$src1) = $src2.new"),
3948 let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
3949 isNVStore = 1, validSubTargets = HasV4SubT in {
3950 def _abs_cPt_nv_V4 : NVInst_V4<(outs),
3951 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3952 !strconcat("if ($src1)",
3953 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3957 def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
3958 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3959 !strconcat("if (!$src1)",
3960 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3964 def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
3965 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3966 !strconcat("if ($src1.new)",
3967 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3971 def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
3972 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3973 !strconcat("if (!$src1.new)",
3974 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3980 defm STrib_imm : ST_absimm<"memb">;
3981 defm STrih_imm : ST_absimm<"memh">;
3982 defm STriw_imm : ST_absimm<"memw">;
3984 let Predicates = [HasV4T], AddedComplexity = 30 in {
3985 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3986 (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3988 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3989 (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3991 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3992 (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3995 // Load - absolute addressing mode: These instruction take constant
3996 // value as the extended operand
3998 multiclass LD_absimm<string OpcStr> {
3999 let isExtended = 1, opExtendable = 1, isPredicable = 1,
4000 validSubTargets = HasV4SubT in
4001 def _abs_V4 : LDInst2<(outs IntRegs:$dst),
4002 (ins u0AlwaysExt:$src),
4003 !strconcat("$dst = ",
4004 !strconcat(OpcStr, "(##$src)")),
4008 let isExtended = 1, opExtendable = 2, isPredicated = 1,
4009 validSubTargets = HasV4SubT in {
4010 def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
4011 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4012 !strconcat("if ($src1) $dst = ",
4013 !strconcat(OpcStr, "(##$src2)")),
4017 def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4018 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4019 !strconcat("if (!$src1) $dst = ",
4020 !strconcat(OpcStr, "(##$src2)")),
4024 def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
4025 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4026 !strconcat("if ($src1.new) $dst = ",
4027 !strconcat(OpcStr, "(##$src2)")),
4031 def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4032 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4033 !strconcat("if (!$src1.new) $dst = ",
4034 !strconcat(OpcStr, "(##$src2)")),
4040 defm LDrib_imm : LD_absimm<"memb">;
4041 defm LDriub_imm : LD_absimm<"memub">;
4042 defm LDrih_imm : LD_absimm<"memh">;
4043 defm LDriuh_imm : LD_absimm<"memuh">;
4044 defm LDriw_imm : LD_absimm<"memw">;
4046 let Predicates = [HasV4T], AddedComplexity = 30 in {
4047 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
4048 (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
4050 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
4051 (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
4053 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
4054 (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
4056 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
4057 (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
4059 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
4060 (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
4063 // Indexed store double word - global address.
4064 // memw(Rs+#u6:2)=#S8
4065 let AddedComplexity = 10 in
4066 def STriw_offset_ext_V4 : STInst<(outs),
4067 (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
4068 "memw($src1+#$src2) = ##$src3",
4069 [(store (HexagonCONST32 tglobaladdr:$src3),
4070 (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
4074 // Indexed store double word - global address.
4075 // memw(Rs+#u6:2)=#S8
4076 let AddedComplexity = 10 in
4077 def STrih_offset_ext_V4 : STInst<(outs),
4078 (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
4079 "memh($src1+#$src2) = ##$src3",
4080 [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
4081 (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
4083 // Map from store(globaladdress + x) -> memd(#foo + x)
4084 let AddedComplexity = 100 in
4085 def : Pat<(store (i64 DoubleRegs:$src1),
4086 FoldGlobalAddrGP:$addr),
4087 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4090 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
4091 (i64 DoubleRegs:$src1)),
4092 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4095 // Map from store(globaladdress + x) -> memb(#foo + x)
4096 let AddedComplexity = 100 in
4097 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4098 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4101 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4102 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4105 // Map from store(globaladdress + x) -> memh(#foo + x)
4106 let AddedComplexity = 100 in
4107 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4108 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4111 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4112 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4115 // Map from store(globaladdress + x) -> memw(#foo + x)
4116 let AddedComplexity = 100 in
4117 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4118 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4121 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4122 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4125 // Map from load(globaladdress + x) -> memd(#foo + x)
4126 let AddedComplexity = 100 in
4127 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
4128 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4131 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
4132 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4135 // Map from load(globaladdress + x) -> memb(#foo + x)
4136 let AddedComplexity = 100 in
4137 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
4138 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4141 // Map from load(globaladdress + x) -> memb(#foo + x)
4142 let AddedComplexity = 100 in
4143 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
4144 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4147 //let AddedComplexity = 100 in
4148 let AddedComplexity = 100 in
4149 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
4150 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4153 // Map from load(globaladdress + x) -> memh(#foo + x)
4154 let AddedComplexity = 100 in
4155 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
4156 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4159 // Map from load(globaladdress + x) -> memuh(#foo + x)
4160 let AddedComplexity = 100 in
4161 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
4162 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4165 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
4166 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4169 // Map from load(globaladdress + x) -> memub(#foo + x)
4170 let AddedComplexity = 100 in
4171 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
4172 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4175 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
4176 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4179 // Map from load(globaladdress + x) -> memw(#foo + x)
4180 let AddedComplexity = 100 in
4181 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
4182 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4185 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
4186 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,