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 (zextloadi16 ADDRriS11_1:$src1)),
945 (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
948 let AddedComplexity = 20 in
949 def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
950 s11_1ExtPred:$offset))),
951 (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
952 s11_1ExtPred:$offset)))>,
956 def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
957 (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
960 let AddedComplexity = 20 in
961 def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
962 s11_1ExtPred:$offset))),
963 (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
964 s11_1ExtPred:$offset)))>,
968 def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
969 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
972 let AddedComplexity = 100 in
973 def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
974 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
975 s11_2ExtPred:$offset)))>,
979 def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
980 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
983 let AddedComplexity = 100 in
984 def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
985 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
986 s11_2ExtPred:$offset)))>,
991 //===----------------------------------------------------------------------===//
993 //===----------------------------------------------------------------------===//
995 //===----------------------------------------------------------------------===//
997 //===----------------------------------------------------------------------===//
999 /// Assumptions::: ****** DO NOT IGNORE ********
1000 /// 1. Make sure that in post increment store, the zero'th operand is always the
1001 /// post increment operand.
1002 /// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
1007 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1008 def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1009 (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
1010 "memd($dst1=##$src2) = $src1",
1015 def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1016 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1017 "memb($dst1=##$src2) = $src1",
1022 def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1023 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1024 "memh($dst1=##$src2) = $src1",
1029 def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
1030 (ins IntRegs:$src1, u0AlwaysExt:$src2),
1031 "memw($dst1=##$src2) = $src1",
1037 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
1038 def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1039 (ins DoubleRegs:$src1, globaladdressExt:$src2),
1040 "memd($dst1=##$src2) = $src1",
1045 def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1046 (ins IntRegs:$src1, globaladdressExt:$src2),
1047 "memb($dst1=##$src2) = $src1",
1052 def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1053 (ins IntRegs:$src1, globaladdressExt:$src2),
1054 "memh($dst1=##$src2) = $src1",
1059 def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
1060 (ins IntRegs:$src1, globaladdressExt:$src2),
1061 "memw($dst1=##$src2) = $src1",
1066 // multiclass for store instructions with base + register offset addressing
1068 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
1070 let PNewValue = !if(isPredNew, "new", "") in
1071 def NAME : STInst2<(outs),
1072 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1074 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1075 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
1080 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
1081 let PredSense = !if(PredNot, "false", "true") in {
1082 defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
1084 defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
1088 let isNVStorable = 1 in
1089 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
1090 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1091 let isPredicable = 1 in
1092 def NAME#_V4 : STInst2<(outs),
1093 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1094 mnemonic#"($src1+$src2<<#$src3) = $src4",
1098 let isPredicated = 1 in {
1099 defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
1100 defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
1105 // multiclass for new-value store instructions with base + register offset
1107 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1109 let PNewValue = !if(isPredNew, "new", "") in
1110 def NAME#_nv_V4 : NVInst_V4<(outs),
1111 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
1113 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1114 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
1119 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1120 let PredSense = !if(PredNot, "false", "true") in {
1121 defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
1123 defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
1127 let mayStore = 1, isNVStore = 1 in
1128 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
1129 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
1130 let isPredicable = 1 in
1131 def NAME#_nv_V4 : NVInst_V4<(outs),
1132 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
1133 mnemonic#"($src1+$src2<<#$src3) = $src4.new",
1137 let isPredicated = 1 in {
1138 defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
1139 defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
1144 let addrMode = BaseRegOffset, neverHasSideEffects = 1,
1145 validSubTargets = HasV4SubT in {
1146 defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
1147 ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
1149 defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
1150 ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
1152 defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
1153 ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
1155 let isNVStorable = 0 in
1156 defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
1159 let Predicates = [HasV4T], AddedComplexity = 10 in {
1160 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
1161 (add IntRegs:$src1, (shl IntRegs:$src2,
1163 (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1164 u2ImmPred:$src3, IntRegs:$src4)>;
1166 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
1167 (add IntRegs:$src1, (shl IntRegs:$src2,
1169 (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1170 u2ImmPred:$src3, IntRegs:$src4)>;
1172 def : Pat<(store (i32 IntRegs:$src4),
1173 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1174 (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1175 u2ImmPred:$src3, IntRegs:$src4)>;
1177 def : Pat<(store (i64 DoubleRegs:$src4),
1178 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
1179 (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
1180 u2ImmPred:$src3, DoubleRegs:$src4)>;
1183 // memd(Ru<<#u2+#U6)=Rtt
1184 let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
1185 validSubTargets = HasV4SubT in
1186 def STrid_shl_V4 : STInst<(outs),
1187 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
1188 "memd($src1<<#$src2+#$src3) = $src4",
1189 [(store (i64 DoubleRegs:$src4),
1190 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1191 u0AlwaysExtPred:$src3))]>,
1194 // memd(Rx++#s4:3)=Rtt
1195 // memd(Rx++#s4:3:circ(Mu))=Rtt
1196 // memd(Rx++I:circ(Mu))=Rtt
1198 // memd(Rx++Mu:brev)=Rtt
1199 // memd(gp+#u16:3)=Rtt
1201 // Store doubleword conditionally.
1202 // if ([!]Pv[.new]) memd(#u6)=Rtt
1203 // TODO: needs to be implemented.
1205 //===----------------------------------------------------------------------===//
1206 // multiclass for store instructions with base + immediate offset
1207 // addressing mode and immediate stored value.
1208 // mem[bhw](Rx++#s4:3)=#s8
1209 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
1210 //===----------------------------------------------------------------------===//
1211 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
1213 let PNewValue = !if(isPredNew, "new", "") in
1214 def NAME : STInst2<(outs),
1215 (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
1216 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1217 ") ")#mnemonic#"($src2+#$src3) = #$src4",
1222 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
1223 let PredSense = !if(PredNot, "false", "true") in {
1224 defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
1226 defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
1230 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
1231 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
1232 let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
1233 let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
1234 def NAME#_V4 : STInst2<(outs),
1235 (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
1236 mnemonic#"($src1+#$src2) = #$src3",
1240 let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
1241 defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
1242 defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
1247 let addrMode = BaseImmOffset, InputType = "imm",
1248 validSubTargets = HasV4SubT in {
1249 defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
1250 defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
1251 defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
1254 let Predicates = [HasV4T], AddedComplexity = 10 in {
1255 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
1256 (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
1258 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
1259 u6_1ImmPred:$src2)),
1260 (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
1262 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
1263 (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
1266 let AddedComplexity = 6 in
1267 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1268 (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1271 // memb(Ru<<#u2+#U6)=Rt
1272 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1273 validSubTargets = HasV4SubT in
1274 def STrib_shl_V4 : STInst<(outs),
1275 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1276 "memb($src1<<#$src2+#$src3) = $src4",
1277 [(truncstorei8 (i32 IntRegs:$src4),
1278 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1279 u0AlwaysExtPred:$src3))]>,
1282 // memb(Rx++#s4:0:circ(Mu))=Rt
1283 // memb(Rx++I:circ(Mu))=Rt
1285 // memb(Rx++Mu:brev)=Rt
1286 // memb(gp+#u16:0)=Rt
1290 // TODO: needs to be implemented
1291 // memh(Re=#U6)=Rt.H
1292 // memh(Rs+#s11:1)=Rt.H
1293 let AddedComplexity = 6 in
1294 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
1295 (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1298 // memh(Rs+Ru<<#u2)=Rt.H
1299 // TODO: needs to be implemented.
1301 // memh(Ru<<#u2+#U6)=Rt.H
1302 // memh(Ru<<#u2+#U6)=Rt
1303 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1304 validSubTargets = HasV4SubT in
1305 def STrih_shl_V4 : STInst<(outs),
1306 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1307 "memh($src1<<#$src2+#$src3) = $src4",
1308 [(truncstorei16 (i32 IntRegs:$src4),
1309 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1310 u0AlwaysExtPred:$src3))]>,
1313 // memh(Rx++#s4:1:circ(Mu))=Rt.H
1314 // memh(Rx++#s4:1:circ(Mu))=Rt
1315 // memh(Rx++I:circ(Mu))=Rt.H
1316 // memh(Rx++I:circ(Mu))=Rt
1317 // memh(Rx++Mu)=Rt.H
1319 // memh(Rx++Mu:brev)=Rt.H
1320 // memh(Rx++Mu:brev)=Rt
1321 // memh(gp+#u16:1)=Rt
1322 // if ([!]Pv[.new]) memh(#u6)=Rt.H
1323 // if ([!]Pv[.new]) memh(#u6)=Rt
1326 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
1327 // TODO: needs to be implemented.
1329 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
1330 // TODO: Needs to be implemented.
1334 // TODO: Needs to be implemented.
1337 let neverHasSideEffects = 1 in
1338 def STriw_pred_V4 : STInst2<(outs),
1339 (ins MEMri:$addr, PredRegs:$src1),
1340 "Error; should not emit",
1344 let AddedComplexity = 6 in
1345 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
1346 (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
1349 // memw(Ru<<#u2+#U6)=Rt
1350 let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
1351 validSubTargets = HasV4SubT in
1352 def STriw_shl_V4 : STInst<(outs),
1353 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1354 "memw($src1<<#$src2+#$src3) = $src4",
1355 [(store (i32 IntRegs:$src4),
1356 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
1357 u0AlwaysExtPred:$src3))]>,
1360 // memw(Rx++#s4:2)=Rt
1361 // memw(Rx++#s4:2:circ(Mu))=Rt
1362 // memw(Rx++I:circ(Mu))=Rt
1364 // memw(Rx++Mu:brev)=Rt
1365 // memw(gp+#u16:2)=Rt
1368 // memd(#global)=Rtt
1369 let isPredicable = 1, neverHasSideEffects = 1 in
1370 def STd_GP_V4 : STInst2<(outs),
1371 (ins globaladdress:$global, DoubleRegs:$src),
1372 "memd(#$global) = $src",
1376 // if (Pv) memd(##global) = Rtt
1377 let neverHasSideEffects = 1, isPredicated = 1 in
1378 def STd_GP_cPt_V4 : STInst2<(outs),
1379 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1380 "if ($src1) memd(##$global) = $src2",
1384 // if (!Pv) memd(##global) = Rtt
1385 let neverHasSideEffects = 1, isPredicated = 1 in
1386 def STd_GP_cNotPt_V4 : STInst2<(outs),
1387 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1388 "if (!$src1) memd(##$global) = $src2",
1392 // if (Pv) memd(##global) = Rtt
1393 let neverHasSideEffects = 1, isPredicated = 1 in
1394 def STd_GP_cdnPt_V4 : STInst2<(outs),
1395 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1396 "if ($src1.new) memd(##$global) = $src2",
1400 // if (!Pv) memd(##global) = Rtt
1401 let neverHasSideEffects = 1, isPredicated = 1 in
1402 def STd_GP_cdnNotPt_V4 : STInst2<(outs),
1403 (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
1404 "if (!$src1.new) memd(##$global) = $src2",
1409 let isPredicable = 1, neverHasSideEffects = 1 in
1410 def STb_GP_V4 : STInst2<(outs),
1411 (ins globaladdress:$global, IntRegs:$src),
1412 "memb(#$global) = $src",
1416 // if (Pv) memb(##global) = Rt
1417 let neverHasSideEffects = 1, isPredicated = 1 in
1418 def STb_GP_cPt_V4 : STInst2<(outs),
1419 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1420 "if ($src1) memb(##$global) = $src2",
1424 // if (!Pv) memb(##global) = Rt
1425 let neverHasSideEffects = 1, isPredicated = 1 in
1426 def STb_GP_cNotPt_V4 : STInst2<(outs),
1427 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1428 "if (!$src1) memb(##$global) = $src2",
1432 // if (Pv) memb(##global) = Rt
1433 let neverHasSideEffects = 1, isPredicated = 1 in
1434 def STb_GP_cdnPt_V4 : STInst2<(outs),
1435 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1436 "if ($src1.new) memb(##$global) = $src2",
1440 // if (!Pv) memb(##global) = Rt
1441 let neverHasSideEffects = 1, isPredicated = 1 in
1442 def STb_GP_cdnNotPt_V4 : STInst2<(outs),
1443 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1444 "if (!$src1.new) memb(##$global) = $src2",
1449 let isPredicable = 1, neverHasSideEffects = 1 in
1450 def STh_GP_V4 : STInst2<(outs),
1451 (ins globaladdress:$global, IntRegs:$src),
1452 "memh(#$global) = $src",
1456 // if (Pv) memh(##global) = Rt
1457 let neverHasSideEffects = 1, isPredicated = 1 in
1458 def STh_GP_cPt_V4 : STInst2<(outs),
1459 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1460 "if ($src1) memh(##$global) = $src2",
1464 // if (!Pv) memh(##global) = Rt
1465 let neverHasSideEffects = 1, isPredicated = 1 in
1466 def STh_GP_cNotPt_V4 : STInst2<(outs),
1467 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1468 "if (!$src1) memh(##$global) = $src2",
1472 // if (Pv) memh(##global) = Rt
1473 let neverHasSideEffects = 1, isPredicated = 1 in
1474 def STh_GP_cdnPt_V4 : STInst2<(outs),
1475 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1476 "if ($src1.new) memh(##$global) = $src2",
1480 // if (!Pv) memh(##global) = Rt
1481 let neverHasSideEffects = 1, isPredicated = 1 in
1482 def STh_GP_cdnNotPt_V4 : STInst2<(outs),
1483 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1484 "if (!$src1.new) memh(##$global) = $src2",
1489 let isPredicable = 1, neverHasSideEffects = 1 in
1490 def STw_GP_V4 : STInst2<(outs),
1491 (ins globaladdress:$global, IntRegs:$src),
1492 "memw(#$global) = $src",
1496 // if (Pv) memw(##global) = Rt
1497 let neverHasSideEffects = 1, isPredicated = 1 in
1498 def STw_GP_cPt_V4 : STInst2<(outs),
1499 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1500 "if ($src1) memw(##$global) = $src2",
1504 // if (!Pv) memw(##global) = Rt
1505 let neverHasSideEffects = 1, isPredicated = 1 in
1506 def STw_GP_cNotPt_V4 : STInst2<(outs),
1507 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1508 "if (!$src1) memw(##$global) = $src2",
1512 // if (Pv) memw(##global) = Rt
1513 let neverHasSideEffects = 1, isPredicated = 1 in
1514 def STw_GP_cdnPt_V4 : STInst2<(outs),
1515 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1516 "if ($src1.new) memw(##$global) = $src2",
1520 // if (!Pv) memw(##global) = Rt
1521 let neverHasSideEffects = 1, isPredicated = 1 in
1522 def STw_GP_cdnNotPt_V4 : STInst2<(outs),
1523 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1524 "if (!$src1.new) memw(##$global) = $src2",
1528 // 64 bit atomic store
1529 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
1530 (i64 DoubleRegs:$src1)),
1531 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1534 // Map from store(globaladdress) -> memd(#foo)
1535 let AddedComplexity = 100 in
1536 def : Pat <(store (i64 DoubleRegs:$src1),
1537 (HexagonCONST32_GP tglobaladdr:$global)),
1538 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
1541 // 8 bit atomic store
1542 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
1543 (i32 IntRegs:$src1)),
1544 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1547 // Map from store(globaladdress) -> memb(#foo)
1548 let AddedComplexity = 100 in
1549 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
1550 (HexagonCONST32_GP tglobaladdr:$global)),
1551 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1554 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
1555 // to "r0 = 1; memw(#foo) = r0"
1556 let AddedComplexity = 100 in
1557 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
1558 (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
1561 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
1562 (i32 IntRegs:$src1)),
1563 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1566 // Map from store(globaladdress) -> memh(#foo)
1567 let AddedComplexity = 100 in
1568 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
1569 (HexagonCONST32_GP tglobaladdr:$global)),
1570 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1573 // 32 bit atomic store
1574 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
1575 (i32 IntRegs:$src1)),
1576 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1579 // Map from store(globaladdress) -> memw(#foo)
1580 let AddedComplexity = 100 in
1581 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
1582 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
1585 //===----------------------------------------------------------------------===
1587 //===----------------------------------------------------------------------===
1590 //===----------------------------------------------------------------------===//
1592 //===----------------------------------------------------------------------===//
1594 // multiclass for new-value store instructions with base + immediate offset.
1596 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
1597 Operand predImmOp, bit isNot, bit isPredNew> {
1598 let PNewValue = !if(isPredNew, "new", "") in
1599 def NAME#_nv_V4 : NVInst_V4<(outs),
1600 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
1601 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1602 ") ")#mnemonic#"($src2+#$src3) = $src4.new",
1607 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
1609 let PredSense = !if(PredNot, "false", "true") in {
1610 defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
1612 defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
1616 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
1617 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
1618 Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
1619 bits<5> PredImmBits> {
1621 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
1622 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1624 def NAME#_nv_V4 : NVInst_V4<(outs),
1625 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
1626 mnemonic#"($src1+#$src2) = $src3.new",
1630 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1631 isPredicated = 1 in {
1632 defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
1633 defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
1638 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
1639 defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
1640 u6_0Ext, 11, 6>, AddrModeRel;
1641 defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
1642 u6_1Ext, 12, 7>, AddrModeRel;
1643 defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
1644 u6_2Ext, 13, 8>, AddrModeRel;
1647 // multiclass for new-value store instructions with base + immediate offset.
1648 // and MEMri operand.
1649 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
1651 let PNewValue = !if(isPredNew, "new", "") in
1652 def NAME#_nv_V4 : NVInst_V4<(outs),
1653 (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
1654 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1655 ") ")#mnemonic#"($addr) = $src2.new",
1660 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
1661 let PredSense = !if(PredNot, "false", "true") in {
1662 defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
1665 defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
1669 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
1670 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
1671 bits<5> ImmBits, bits<5> PredImmBits> {
1673 let CextOpcode = CextOp, BaseOpcode = CextOp in {
1674 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
1676 def NAME#_nv_V4 : NVInst_V4<(outs),
1677 (ins MEMri:$addr, RC:$src),
1678 mnemonic#"($addr) = $src.new",
1682 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
1683 neverHasSideEffects = 1, isPredicated = 1 in {
1684 defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
1685 defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
1690 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1692 defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1693 defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1694 defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1697 // memb(Ru<<#u2+#U6)=Nt.new
1698 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1699 isNVStore = 1, validSubTargets = HasV4SubT in
1700 def STrib_shl_nv_V4 : NVInst_V4<(outs),
1701 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1702 "memb($src1<<#$src2+#$src3) = $src4.new",
1706 //===----------------------------------------------------------------------===//
1707 // Post increment store
1708 // mem[bhwd](Rx++#s4:[0123])=Nt.new
1709 //===----------------------------------------------------------------------===//
1711 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
1712 bit isNot, bit isPredNew> {
1713 let PNewValue = !if(isPredNew, "new", "") in
1714 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1715 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
1716 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
1717 ") ")#mnemonic#"($src2++#$offset) = $src3.new",
1723 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
1724 Operand ImmOp, bit PredNot> {
1725 let PredSense = !if(PredNot, "false", "true") in {
1726 defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
1728 let Predicates = [HasV4T], validSubTargets = HasV4SubT in
1729 defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
1733 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
1734 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
1737 let BaseOpcode = "POST_"#BaseOp in {
1738 let isPredicable = 1 in
1739 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
1740 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
1741 mnemonic#"($src1++#$offset) = $src2.new",
1746 let isPredicated = 1 in {
1747 defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
1748 defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
1753 let validSubTargets = HasV4SubT in {
1754 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1755 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1756 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1759 // memb(Rx++#s4:0:circ(Mu))=Nt.new
1760 // memb(Rx++I:circ(Mu))=Nt.new
1761 // memb(Rx++Mu)=Nt.new
1762 // memb(Rx++Mu:brev)=Nt.new
1764 // memb(#global)=Nt.new
1765 let mayStore = 1, neverHasSideEffects = 1 in
1766 def STb_GP_nv_V4 : NVInst_V4<(outs),
1767 (ins globaladdress:$global, IntRegs:$src),
1768 "memb(#$global) = $src.new",
1772 // memh(Ru<<#u2+#U6)=Nt.new
1773 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1774 isNVStore = 1, validSubTargets = HasV4SubT in
1775 def STrih_shl_nv_V4 : NVInst_V4<(outs),
1776 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1777 "memh($src1<<#$src2+#$src3) = $src4.new",
1781 // memh(Rx++#s4:1:circ(Mu))=Nt.new
1782 // memh(Rx++I:circ(Mu))=Nt.new
1783 // memh(Rx++Mu)=Nt.new
1784 // memh(Rx++Mu:brev)=Nt.new
1786 // memh(#global)=Nt.new
1787 let mayStore = 1, neverHasSideEffects = 1 in
1788 def STh_GP_nv_V4 : NVInst_V4<(outs),
1789 (ins globaladdress:$global, IntRegs:$src),
1790 "memh(#$global) = $src.new",
1794 // memw(Ru<<#u2+#U6)=Nt.new
1795 let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1796 isNVStore = 1, validSubTargets = HasV4SubT in
1797 def STriw_shl_nv_V4 : NVInst_V4<(outs),
1798 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1799 "memw($src1<<#$src2+#$src3) = $src4.new",
1803 // memw(Rx++#s4:2:circ(Mu))=Nt.new
1804 // memw(Rx++I:circ(Mu))=Nt.new
1805 // memw(Rx++Mu)=Nt.new
1806 // memw(Rx++Mu:brev)=Nt.new
1807 // memw(gp+#u16:2)=Nt.new
1809 let mayStore = 1, neverHasSideEffects = 1 in
1810 def STw_GP_nv_V4 : NVInst_V4<(outs),
1811 (ins globaladdress:$global, IntRegs:$src),
1812 "memw(#$global) = $src.new",
1816 // if (Pv) memb(##global) = Rt
1817 let mayStore = 1, neverHasSideEffects = 1 in
1818 def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
1819 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1820 "if ($src1) memb(##$global) = $src2.new",
1824 // if (!Pv) memb(##global) = Rt
1825 let mayStore = 1, neverHasSideEffects = 1 in
1826 def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1827 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1828 "if (!$src1) memb(##$global) = $src2.new",
1832 // if (Pv) memb(##global) = Rt
1833 let mayStore = 1, neverHasSideEffects = 1 in
1834 def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1835 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1836 "if ($src1.new) memb(##$global) = $src2.new",
1840 // if (!Pv) memb(##global) = Rt
1841 let mayStore = 1, neverHasSideEffects = 1 in
1842 def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1843 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1844 "if (!$src1.new) memb(##$global) = $src2.new",
1848 // if (Pv) memh(##global) = Rt
1849 let mayStore = 1, neverHasSideEffects = 1 in
1850 def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
1851 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1852 "if ($src1) memh(##$global) = $src2.new",
1856 // if (!Pv) memh(##global) = Rt
1857 let mayStore = 1, neverHasSideEffects = 1 in
1858 def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1859 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1860 "if (!$src1) memh(##$global) = $src2.new",
1864 // if (Pv) memh(##global) = Rt
1865 let mayStore = 1, neverHasSideEffects = 1 in
1866 def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1867 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1868 "if ($src1.new) memh(##$global) = $src2.new",
1872 // if (!Pv) memh(##global) = Rt
1873 let mayStore = 1, neverHasSideEffects = 1 in
1874 def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1875 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1876 "if (!$src1.new) memh(##$global) = $src2.new",
1880 // if (Pv) memw(##global) = Rt
1881 let mayStore = 1, neverHasSideEffects = 1 in
1882 def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
1883 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1884 "if ($src1) memw(##$global) = $src2.new",
1888 // if (!Pv) memw(##global) = Rt
1889 let mayStore = 1, neverHasSideEffects = 1 in
1890 def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
1891 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1892 "if (!$src1) memw(##$global) = $src2.new",
1896 // if (Pv) memw(##global) = Rt
1897 let mayStore = 1, neverHasSideEffects = 1 in
1898 def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
1899 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1900 "if ($src1.new) memw(##$global) = $src2.new",
1904 // if (!Pv) memw(##global) = Rt
1905 let mayStore = 1, neverHasSideEffects = 1 in
1906 def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
1907 (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
1908 "if (!$src1.new) memw(##$global) = $src2.new",
1912 //===----------------------------------------------------------------------===//
1914 //===----------------------------------------------------------------------===//
1916 //===----------------------------------------------------------------------===//
1918 //===----------------------------------------------------------------------===//
1920 multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
1921 def _ie_nv_V4 : NVInst_V4<(outs),
1922 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1923 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1924 !strconcat("($src1.new, $src2)) jump:",
1925 !strconcat(TakenStr, " $offset"))))),
1929 def _nv_V4 : NVInst_V4<(outs),
1930 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1931 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1932 !strconcat("($src1.new, $src2)) jump:",
1933 !strconcat(TakenStr, " $offset"))))),
1938 multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
1940 def _ie_nv_V4 : NVInst_V4<(outs),
1941 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1942 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1943 !strconcat("($src1, $src2.new)) jump:",
1944 !strconcat(TakenStr, " $offset"))))),
1948 def _nv_V4 : NVInst_V4<(outs),
1949 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1950 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1951 !strconcat("($src1, $src2.new)) jump:",
1952 !strconcat(TakenStr, " $offset"))))),
1957 multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
1958 def _ie_nv_V4 : NVInst_V4<(outs),
1959 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1960 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1961 !strconcat("($src1.new, #$src2)) jump:",
1962 !strconcat(TakenStr, " $offset"))))),
1966 def _nv_V4 : NVInst_V4<(outs),
1967 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1968 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1969 !strconcat("($src1.new, #$src2)) jump:",
1970 !strconcat(TakenStr, " $offset"))))),
1975 multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
1976 def _ie_nv_V4 : NVInst_V4<(outs),
1977 (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1978 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1979 !strconcat("($src1.new, #$src2)) jump:",
1980 !strconcat(TakenStr, " $offset"))))),
1984 def _nv_V4 : NVInst_V4<(outs),
1985 (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1986 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1987 !strconcat("($src1.new, #$src2)) jump:",
1988 !strconcat(TakenStr, " $offset"))))),
1993 multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
1995 def _ie_nv_V4 : NVInst_V4<(outs),
1996 (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
1997 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1998 !strconcat("($src1.new, #$src2)) jump:",
1999 !strconcat(TakenStr, " $offset"))))),
2003 def _nv_V4 : NVInst_V4<(outs),
2004 (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
2005 !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
2006 !strconcat("($src1.new, #$src2)) jump:",
2007 !strconcat(TakenStr, " $offset"))))),
2012 // Multiclass for regular dot new of Ist operand register.
2013 multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> {
2014 defm Pt : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
2015 defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
2018 // Multiclass for dot new of 2nd operand register.
2019 multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
2020 defm Pt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
2021 defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
2024 // Multiclass for 2nd operand immediate, including -1.
2025 multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
2026 defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2027 defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2028 defm Ptneg : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
2029 defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
2032 // Multiclass for 2nd operand immediate, excluding -1.
2033 multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
2034 defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
2035 defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
2038 // Multiclass for tstbit, where 2nd operand is always #0.
2039 multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
2040 defm Pt : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
2041 defm Pnt : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
2044 // Multiclass for GT.
2045 multiclass NVJ_type_rr_ri<string OpcStr> {
2046 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2047 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2048 defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2049 defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>;
2050 defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>;
2051 defm ri : NVJ_type_br_pred_imm<"", OpcStr>;
2054 // Multiclass for EQ.
2055 multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> {
2056 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2057 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2058 defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>;
2059 defm ri : NVJ_type_br_pred_imm<"", OpcStr>;
2062 // Multiclass for GTU.
2063 multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> {
2064 defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>;
2065 defm rr : NVJ_type_br_pred_reg<"", OpcStr>;
2066 defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
2067 defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>;
2068 defm riNot : NVJ_type_br_pred_imm_only<"!", OpcStr>;
2069 defm ri : NVJ_type_br_pred_imm_only<"", OpcStr>;
2072 // Multiclass for tstbit.
2073 multiclass NVJ_type_r0<string OpcStr> {
2074 defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
2075 defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>;
2078 // Base Multiclass for New Value Jump.
2079 multiclass NVJ_type {
2080 defm GT : NVJ_type_rr_ri<"cmp.gt">;
2081 defm EQ : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
2082 defm GTU : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
2083 defm TSTBIT : NVJ_type_r0<"tstbit">;
2086 let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
2087 defm JMP_ : NVJ_type;
2090 //===----------------------------------------------------------------------===//
2092 //===----------------------------------------------------------------------===//
2094 //===----------------------------------------------------------------------===//
2096 //===----------------------------------------------------------------------===//
2098 // Add and accumulate.
2099 // Rd=add(Rs,add(Ru,#s6))
2100 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
2101 validSubTargets = HasV4SubT in
2102 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
2103 (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
2104 "$dst = add($src1, add($src2, #$src3))",
2105 [(set (i32 IntRegs:$dst),
2106 (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
2107 s6_16ExtPred:$src3)))]>,
2110 // Rd=add(Rs,sub(#s6,Ru))
2111 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2112 validSubTargets = HasV4SubT in
2113 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
2114 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2115 "$dst = add($src1, sub(#$src2, $src3))",
2116 [(set (i32 IntRegs:$dst),
2117 (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
2118 (i32 IntRegs:$src3))))]>,
2121 // Generates the same instruction as ADDr_SUBri_V4 but matches different
2123 // Rd=add(Rs,sub(#s6,Ru))
2124 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
2125 validSubTargets = HasV4SubT in
2126 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
2127 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
2128 "$dst = add($src1, sub(#$src2, $src3))",
2129 [(set (i32 IntRegs:$dst),
2130 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
2131 (i32 IntRegs:$src3)))]>,
2135 // Add or subtract doublewords with carry.
2137 // Rdd=add(Rss,Rtt,Px):carry
2139 // Rdd=sub(Rss,Rtt,Px):carry
2142 // Logical doublewords.
2143 // Rdd=and(Rtt,~Rss)
2144 let validSubTargets = HasV4SubT in
2145 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2146 (ins DoubleRegs:$src1, DoubleRegs:$src2),
2147 "$dst = and($src1, ~$src2)",
2148 [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
2149 (not (i64 DoubleRegs:$src2))))]>,
2153 let validSubTargets = HasV4SubT in
2154 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
2155 (ins DoubleRegs:$src1, DoubleRegs:$src2),
2156 "$dst = or($src1, ~$src2)",
2157 [(set (i64 DoubleRegs:$dst),
2158 (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
2162 // Logical-logical doublewords.
2163 // Rxx^=xor(Rss,Rtt)
2164 let validSubTargets = HasV4SubT in
2165 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
2166 (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
2167 "$dst ^= xor($src2, $src3)",
2168 [(set (i64 DoubleRegs:$dst),
2169 (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
2170 (i64 DoubleRegs:$src3))))],
2175 // Logical-logical words.
2176 // Rx=or(Ru,and(Rx,#s10))
2177 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2178 validSubTargets = HasV4SubT in
2179 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
2180 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2181 "$dst = or($src1, and($src2, #$src3))",
2182 [(set (i32 IntRegs:$dst),
2183 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2184 s10ExtPred:$src3)))],
2188 // Rx[&|^]=and(Rs,Rt)
2190 let validSubTargets = HasV4SubT in
2191 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2192 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2193 "$dst &= and($src2, $src3)",
2194 [(set (i32 IntRegs:$dst),
2195 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2196 (i32 IntRegs:$src3))))],
2201 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
2202 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2203 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2204 "$dst |= and($src2, $src3)",
2205 [(set (i32 IntRegs:$dst),
2206 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2207 (i32 IntRegs:$src3))))],
2209 Requires<[HasV4T]>, ImmRegRel;
2212 let validSubTargets = HasV4SubT in
2213 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
2214 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2215 "$dst ^= and($src2, $src3)",
2216 [(set (i32 IntRegs:$dst),
2217 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2218 (i32 IntRegs:$src3))))],
2222 // Rx[&|^]=and(Rs,~Rt)
2224 let validSubTargets = HasV4SubT in
2225 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2226 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2227 "$dst &= and($src2, ~$src3)",
2228 [(set (i32 IntRegs:$dst),
2229 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2230 (not (i32 IntRegs:$src3)))))],
2235 let validSubTargets = HasV4SubT in
2236 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2237 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2238 "$dst |= and($src2, ~$src3)",
2239 [(set (i32 IntRegs:$dst),
2240 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2241 (not (i32 IntRegs:$src3)))))],
2246 let validSubTargets = HasV4SubT in
2247 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
2248 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2249 "$dst ^= and($src2, ~$src3)",
2250 [(set (i32 IntRegs:$dst),
2251 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2252 (not (i32 IntRegs:$src3)))))],
2256 // Rx[&|^]=or(Rs,Rt)
2258 let validSubTargets = HasV4SubT in
2259 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2260 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2261 "$dst &= or($src2, $src3)",
2262 [(set (i32 IntRegs:$dst),
2263 (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2264 (i32 IntRegs:$src3))))],
2269 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
2270 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2271 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2272 "$dst |= or($src2, $src3)",
2273 [(set (i32 IntRegs:$dst),
2274 (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2275 (i32 IntRegs:$src3))))],
2277 Requires<[HasV4T]>, ImmRegRel;
2280 let validSubTargets = HasV4SubT in
2281 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2282 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2283 "$dst ^= or($src2, $src3)",
2284 [(set (i32 IntRegs:$dst),
2285 (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
2286 (i32 IntRegs:$src3))))],
2290 // Rx[&|^]=xor(Rs,Rt)
2292 let validSubTargets = HasV4SubT in
2293 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2294 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2295 "$dst &= xor($src2, $src3)",
2296 [(set (i32 IntRegs:$dst),
2297 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2298 (i32 IntRegs:$src3))))],
2303 let validSubTargets = HasV4SubT in
2304 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2305 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2306 "$dst |= xor($src2, $src3)",
2307 [(set (i32 IntRegs:$dst),
2308 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2309 (i32 IntRegs:$src3))))],
2314 let validSubTargets = HasV4SubT in
2315 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
2316 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
2317 "$dst ^= xor($src2, $src3)",
2318 [(set (i32 IntRegs:$dst),
2319 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
2320 (i32 IntRegs:$src3))))],
2325 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2326 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
2327 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
2328 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2329 "$dst |= and($src2, #$src3)",
2330 [(set (i32 IntRegs:$dst),
2331 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2332 s10ExtPred:$src3)))],
2334 Requires<[HasV4T]>, ImmRegRel;
2337 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
2338 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
2339 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
2340 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
2341 "$dst |= or($src2, #$src3)",
2342 [(set (i32 IntRegs:$dst),
2343 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
2344 s10ExtPred:$src3)))],
2346 Requires<[HasV4T]>, ImmRegRel;
2350 // Rd=modwrap(Rs,Rt)
2352 // Rd=cround(Rs,#u5)
2354 // Rd=round(Rs,#u5)[:sat]
2355 // Rd=round(Rs,Rt)[:sat]
2356 // Vector reduce add unsigned halfwords
2357 // Rd=vraddh(Rss,Rtt)
2359 // Rdd=vaddb(Rss,Rtt)
2360 // Vector conditional negate
2361 // Rdd=vcnegh(Rss,Rt)
2362 // Rxx+=vrcnegh(Rss,Rt)
2363 // Vector maximum bytes
2364 // Rdd=vmaxb(Rtt,Rss)
2365 // Vector reduce maximum halfwords
2366 // Rxx=vrmaxh(Rss,Ru)
2367 // Rxx=vrmaxuh(Rss,Ru)
2368 // Vector reduce maximum words
2369 // Rxx=vrmaxuw(Rss,Ru)
2370 // Rxx=vrmaxw(Rss,Ru)
2371 // Vector minimum bytes
2372 // Rdd=vminb(Rtt,Rss)
2373 // Vector reduce minimum halfwords
2374 // Rxx=vrminh(Rss,Ru)
2375 // Rxx=vrminuh(Rss,Ru)
2376 // Vector reduce minimum words
2377 // Rxx=vrminuw(Rss,Ru)
2378 // Rxx=vrminw(Rss,Ru)
2379 // Vector subtract bytes
2380 // Rdd=vsubb(Rss,Rtt)
2382 //===----------------------------------------------------------------------===//
2384 //===----------------------------------------------------------------------===//
2387 //===----------------------------------------------------------------------===//
2389 //===----------------------------------------------------------------------===//
2391 // Multiply and user lower result.
2392 // Rd=add(#u6,mpyi(Rs,#U6))
2393 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2394 validSubTargets = HasV4SubT in
2395 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
2396 (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
2397 "$dst = add(#$src1, mpyi($src2, #$src3))",
2398 [(set (i32 IntRegs:$dst),
2399 (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2400 u6ExtPred:$src1))]>,
2403 // Rd=add(##,mpyi(Rs,#U6))
2404 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
2405 (HexagonCONST32 tglobaladdr:$src1)),
2406 (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
2409 // Rd=add(#u6,mpyi(Rs,Rt))
2410 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
2411 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2412 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
2413 (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
2414 "$dst = add(#$src1, mpyi($src2, $src3))",
2415 [(set (i32 IntRegs:$dst),
2416 (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2417 u6ExtPred:$src1))]>,
2418 Requires<[HasV4T]>, ImmRegRel;
2420 // Rd=add(##,mpyi(Rs,Rt))
2421 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
2422 (HexagonCONST32 tglobaladdr:$src1)),
2423 (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
2426 // Rd=add(Ru,mpyi(#u6:2,Rs))
2427 let validSubTargets = HasV4SubT in
2428 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
2429 (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
2430 "$dst = add($src1, mpyi(#$src2, $src3))",
2431 [(set (i32 IntRegs:$dst),
2432 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
2433 u6_2ImmPred:$src2)))]>,
2436 // Rd=add(Ru,mpyi(Rs,#u6))
2437 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
2438 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
2439 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
2440 (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
2441 "$dst = add($src1, mpyi($src2, #$src3))",
2442 [(set (i32 IntRegs:$dst),
2443 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2444 u6ExtPred:$src3)))]>,
2445 Requires<[HasV4T]>, ImmRegRel;
2447 // Rx=add(Ru,mpyi(Rx,Rs))
2448 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
2449 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
2450 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
2451 "$dst = add($src1, mpyi($src2, $src3))",
2452 [(set (i32 IntRegs:$dst),
2453 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
2454 (i32 IntRegs:$src3))))],
2456 Requires<[HasV4T]>, ImmRegRel;
2459 // Polynomial multiply words
2461 // Rxx^=pmpyw(Rs,Rt)
2463 // Vector reduce multiply word by signed half (32x16)
2464 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
2465 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
2466 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
2467 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
2469 // Multiply and use upper result
2470 // Rd=mpy(Rs,Rt.H):<<1:sat
2471 // Rd=mpy(Rs,Rt.L):<<1:sat
2472 // Rd=mpy(Rs,Rt):<<1
2473 // Rd=mpy(Rs,Rt):<<1:sat
2475 // Rx+=mpy(Rs,Rt):<<1:sat
2476 // Rx-=mpy(Rs,Rt):<<1:sat
2478 // Vector multiply bytes
2479 // Rdd=vmpybsu(Rs,Rt)
2480 // Rdd=vmpybu(Rs,Rt)
2481 // Rxx+=vmpybsu(Rs,Rt)
2482 // Rxx+=vmpybu(Rs,Rt)
2484 // Vector polynomial multiply halfwords
2485 // Rdd=vpmpyh(Rs,Rt)
2486 // Rxx^=vpmpyh(Rs,Rt)
2488 //===----------------------------------------------------------------------===//
2490 //===----------------------------------------------------------------------===//
2493 //===----------------------------------------------------------------------===//
2495 //===----------------------------------------------------------------------===//
2497 // Shift by immediate and accumulate.
2498 // Rx=add(#u8,asl(Rx,#U5))
2499 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2500 validSubTargets = HasV4SubT in
2501 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2502 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2503 "$dst = add(#$src1, asl($src2, #$src3))",
2504 [(set (i32 IntRegs:$dst),
2505 (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2510 // Rx=add(#u8,lsr(Rx,#U5))
2511 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2512 validSubTargets = HasV4SubT in
2513 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2514 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2515 "$dst = add(#$src1, lsr($src2, #$src3))",
2516 [(set (i32 IntRegs:$dst),
2517 (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2522 // Rx=sub(#u8,asl(Rx,#U5))
2523 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2524 validSubTargets = HasV4SubT in
2525 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2526 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2527 "$dst = sub(#$src1, asl($src2, #$src3))",
2528 [(set (i32 IntRegs:$dst),
2529 (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2534 // Rx=sub(#u8,lsr(Rx,#U5))
2535 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2536 validSubTargets = HasV4SubT in
2537 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2538 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2539 "$dst = sub(#$src1, lsr($src2, #$src3))",
2540 [(set (i32 IntRegs:$dst),
2541 (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2547 //Shift by immediate and logical.
2548 //Rx=and(#u8,asl(Rx,#U5))
2549 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2550 validSubTargets = HasV4SubT in
2551 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2552 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2553 "$dst = and(#$src1, asl($src2, #$src3))",
2554 [(set (i32 IntRegs:$dst),
2555 (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2560 //Rx=and(#u8,lsr(Rx,#U5))
2561 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2562 validSubTargets = HasV4SubT in
2563 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2564 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2565 "$dst = and(#$src1, lsr($src2, #$src3))",
2566 [(set (i32 IntRegs:$dst),
2567 (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2572 //Rx=or(#u8,asl(Rx,#U5))
2573 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2574 AddedComplexity = 30, validSubTargets = HasV4SubT in
2575 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
2576 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2577 "$dst = or(#$src1, asl($src2, #$src3))",
2578 [(set (i32 IntRegs:$dst),
2579 (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
2584 //Rx=or(#u8,lsr(Rx,#U5))
2585 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
2586 AddedComplexity = 30, validSubTargets = HasV4SubT in
2587 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
2588 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
2589 "$dst = or(#$src1, lsr($src2, #$src3))",
2590 [(set (i32 IntRegs:$dst),
2591 (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
2597 //Shift by register.
2599 let validSubTargets = HasV4SubT in {
2600 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
2601 "$dst = lsl(#$src1, $src2)",
2602 [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
2603 (i32 IntRegs:$src2)))]>,
2607 //Shift by register and logical.
2609 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2610 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2611 "$dst ^= asl($src2, $src3)",
2612 [(set (i64 DoubleRegs:$dst),
2613 (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
2614 (i32 IntRegs:$src3))))],
2619 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2620 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2621 "$dst ^= asr($src2, $src3)",
2622 [(set (i64 DoubleRegs:$dst),
2623 (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
2624 (i32 IntRegs:$src3))))],
2629 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2630 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2631 "$dst ^= lsl($src2, $src3)",
2632 [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
2633 (shl (i64 DoubleRegs:$src2),
2634 (i32 IntRegs:$src3))))],
2639 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
2640 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
2641 "$dst ^= lsr($src2, $src3)",
2642 [(set (i64 DoubleRegs:$dst),
2643 (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
2644 (i32 IntRegs:$src3))))],
2649 //===----------------------------------------------------------------------===//
2651 //===----------------------------------------------------------------------===//
2653 //===----------------------------------------------------------------------===//
2654 // MEMOP: Word, Half, Byte
2655 //===----------------------------------------------------------------------===//
2657 //===----------------------------------------------------------------------===//
2661 // MEMw_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
2662 // MEMw_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
2663 // MEMw_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
2664 // MEMw_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
2665 // MEMw_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
2666 // MEMw_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
2667 // MEMw_ADDi_V4 : memw(Rs+#u6:2)+=#U5
2668 // MEMw_SUBi_V4 : memw(Rs+#u6:2)-=#U5
2669 // MEMw_ADDr_V4 : memw(Rs+#u6:2)+=Rt
2670 // MEMw_SUBr_V4 : memw(Rs+#u6:2)-=Rt
2671 // MEMw_CLRr_V4 : memw(Rs+#u6:2)&=Rt
2672 // MEMw_SETr_V4 : memw(Rs+#u6:2)|=Rt
2675 // MEMw_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2676 // MEMw_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
2677 // MEMw_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2678 // MEMw_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
2679 //===----------------------------------------------------------------------===//
2683 // memw(Rs+#u6:2) += #U5
2684 let AddedComplexity = 30 in
2685 def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2686 (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
2687 "memw($base+#$offset) += #$addend",
2689 Requires<[HasV4T, UseMEMOP]>;
2691 // memw(Rs+#u6:2) -= #U5
2692 let AddedComplexity = 30 in
2693 def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2694 (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
2695 "memw($base+#$offset) -= #$subend",
2697 Requires<[HasV4T, UseMEMOP]>;
2699 // memw(Rs+#u6:2) += Rt
2700 let AddedComplexity = 30 in
2701 def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2702 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
2703 "memw($base+#$offset) += $addend",
2704 [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2705 (i32 IntRegs:$addend)),
2706 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2707 Requires<[HasV4T, UseMEMOP]>;
2709 // memw(Rs+#u6:2) -= Rt
2710 let AddedComplexity = 30 in
2711 def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2712 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
2713 "memw($base+#$offset) -= $subend",
2714 [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2715 (i32 IntRegs:$subend)),
2716 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2717 Requires<[HasV4T, UseMEMOP]>;
2719 // memw(Rs+#u6:2) &= Rt
2720 let AddedComplexity = 30 in
2721 def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2722 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
2723 "memw($base+#$offset) &= $andend",
2724 [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2725 (i32 IntRegs:$andend)),
2726 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2727 Requires<[HasV4T, UseMEMOP]>;
2729 // memw(Rs+#u6:2) |= Rt
2730 let AddedComplexity = 30 in
2731 def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2732 (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
2733 "memw($base+#$offset) |= $orend",
2734 [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
2735 (i32 IntRegs:$orend)),
2736 (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
2737 Requires<[HasV4T, UseMEMOP]>;
2739 // memw(Rs+#u6:2) += #U5
2740 let AddedComplexity = 30 in
2741 def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
2742 (ins MEMri:$addr, u5Imm:$addend),
2743 "memw($addr) += $addend",
2745 Requires<[HasV4T, UseMEMOP]>;
2747 // memw(Rs+#u6:2) -= #U5
2748 let AddedComplexity = 30 in
2749 def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
2750 (ins MEMri:$addr, u5Imm:$subend),
2751 "memw($addr) -= $subend",
2753 Requires<[HasV4T, UseMEMOP]>;
2755 // memw(Rs+#u6:2) += Rt
2756 let AddedComplexity = 30 in
2757 def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
2758 (ins MEMri:$addr, IntRegs:$addend),
2759 "memw($addr) += $addend",
2760 [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
2761 ADDRriU6_2:$addr)]>,
2762 Requires<[HasV4T, UseMEMOP]>;
2764 // memw(Rs+#u6:2) -= Rt
2765 let AddedComplexity = 30 in
2766 def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
2767 (ins MEMri:$addr, IntRegs:$subend),
2768 "memw($addr) -= $subend",
2769 [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
2770 ADDRriU6_2:$addr)]>,
2771 Requires<[HasV4T, UseMEMOP]>;
2773 // memw(Rs+#u6:2) &= Rt
2774 let AddedComplexity = 30 in
2775 def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
2776 (ins MEMri:$addr, IntRegs:$andend),
2777 "memw($addr) &= $andend",
2778 [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
2779 ADDRriU6_2:$addr)]>,
2780 Requires<[HasV4T, UseMEMOP]>;
2782 // memw(Rs+#u6:2) |= Rt
2783 let AddedComplexity = 30 in
2784 def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
2785 (ins MEMri:$addr, IntRegs:$orend),
2786 "memw($addr) |= $orend",
2787 [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
2788 ADDRriU6_2:$addr)]>,
2789 Requires<[HasV4T, UseMEMOP]>;
2791 //===----------------------------------------------------------------------===//
2795 // MEMh_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
2796 // MEMh_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
2797 // MEMh_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
2798 // MEMh_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
2799 // MEMh_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
2800 // MEMh_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
2801 // MEMh_ADDi_V4 : memw(Rs+#u6:2)+=#U5
2802 // MEMh_SUBi_V4 : memw(Rs+#u6:2)-=#U5
2803 // MEMh_ADDr_V4 : memw(Rs+#u6:2)+=Rt
2804 // MEMh_SUBr_V4 : memw(Rs+#u6:2)-=Rt
2805 // MEMh_CLRr_V4 : memw(Rs+#u6:2)&=Rt
2806 // MEMh_SETr_V4 : memw(Rs+#u6:2)|=Rt
2809 // MEMh_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2810 // MEMh_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
2811 // MEMh_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
2812 // MEMh_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
2813 //===----------------------------------------------------------------------===//
2816 // memh(Rs+#u6:1) += #U5
2817 let AddedComplexity = 30 in
2818 def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2819 (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
2820 "memh($base+#$offset) += $addend",
2822 Requires<[HasV4T, UseMEMOP]>;
2824 // memh(Rs+#u6:1) -= #U5
2825 let AddedComplexity = 30 in
2826 def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2827 (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
2828 "memh($base+#$offset) -= $subend",
2830 Requires<[HasV4T, UseMEMOP]>;
2832 // memh(Rs+#u6:1) += Rt
2833 let AddedComplexity = 30 in
2834 def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2835 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
2836 "memh($base+#$offset) += $addend",
2837 [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
2838 u6_1ImmPred:$offset)),
2839 (i32 IntRegs:$addend)),
2840 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2841 Requires<[HasV4T, UseMEMOP]>;
2843 // memh(Rs+#u6:1) -= Rt
2844 let AddedComplexity = 30 in
2845 def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2846 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
2847 "memh($base+#$offset) -= $subend",
2848 [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
2849 u6_1ImmPred:$offset)),
2850 (i32 IntRegs:$subend)),
2851 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2852 Requires<[HasV4T, UseMEMOP]>;
2854 // memh(Rs+#u6:1) &= Rt
2855 let AddedComplexity = 30 in
2856 def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2857 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
2858 "memh($base+#$offset) += $andend",
2859 [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
2860 u6_1ImmPred:$offset)),
2861 (i32 IntRegs:$andend)),
2862 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2863 Requires<[HasV4T, UseMEMOP]>;
2865 // memh(Rs+#u6:1) |= Rt
2866 let AddedComplexity = 30 in
2867 def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
2868 (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
2869 "memh($base+#$offset) |= $orend",
2870 [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
2871 u6_1ImmPred:$offset)),
2872 (i32 IntRegs:$orend)),
2873 (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
2874 Requires<[HasV4T, UseMEMOP]>;
2876 // memh(Rs+#u6:1) += #U5
2877 let AddedComplexity = 30 in
2878 def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
2879 (ins MEMri:$addr, u5Imm:$addend),
2880 "memh($addr) += $addend",
2882 Requires<[HasV4T, UseMEMOP]>;
2884 // memh(Rs+#u6:1) -= #U5
2885 let AddedComplexity = 30 in
2886 def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
2887 (ins MEMri:$addr, u5Imm:$subend),
2888 "memh($addr) -= $subend",
2890 Requires<[HasV4T, UseMEMOP]>;
2892 // memh(Rs+#u6:1) += Rt
2893 let AddedComplexity = 30 in
2894 def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
2895 (ins MEMri:$addr, IntRegs:$addend),
2896 "memh($addr) += $addend",
2897 [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
2898 (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
2899 Requires<[HasV4T, UseMEMOP]>;
2901 // memh(Rs+#u6:1) -= Rt
2902 let AddedComplexity = 30 in
2903 def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
2904 (ins MEMri:$addr, IntRegs:$subend),
2905 "memh($addr) -= $subend",
2906 [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
2907 (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
2908 Requires<[HasV4T, UseMEMOP]>;
2910 // memh(Rs+#u6:1) &= Rt
2911 let AddedComplexity = 30 in
2912 def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
2913 (ins MEMri:$addr, IntRegs:$andend),
2914 "memh($addr) &= $andend",
2915 [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
2916 (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
2917 Requires<[HasV4T, UseMEMOP]>;
2919 // memh(Rs+#u6:1) |= Rt
2920 let AddedComplexity = 30 in
2921 def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
2922 (ins MEMri:$addr, IntRegs:$orend),
2923 "memh($addr) |= $orend",
2924 [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
2925 (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
2926 Requires<[HasV4T, UseMEMOP]>;
2929 //===----------------------------------------------------------------------===//
2933 // MEMb_ADDi_indexed_V4 : memb(Rs+#u6:0)+=#U5
2934 // MEMb_SUBi_indexed_V4 : memb(Rs+#u6:0)-=#U5
2935 // MEMb_ADDr_indexed_V4 : memb(Rs+#u6:0)+=Rt
2936 // MEMb_SUBr_indexed_V4 : memb(Rs+#u6:0)-=Rt
2937 // MEMb_CLRr_indexed_V4 : memb(Rs+#u6:0)&=Rt
2938 // MEMb_SETr_indexed_V4 : memb(Rs+#u6:0)|=Rt
2939 // MEMb_ADDi_V4 : memb(Rs+#u6:0)+=#U5
2940 // MEMb_SUBi_V4 : memb(Rs+#u6:0)-=#U5
2941 // MEMb_ADDr_V4 : memb(Rs+#u6:0)+=Rt
2942 // MEMb_SUBr_V4 : memb(Rs+#u6:0)-=Rt
2943 // MEMb_CLRr_V4 : memb(Rs+#u6:0)&=Rt
2944 // MEMb_SETr_V4 : memb(Rs+#u6:0)|=Rt
2947 // MEMb_CLRi_indexed_V4 : memb(Rs+#u6:0)=clrbit(#U5)
2948 // MEMb_SETi_indexed_V4 : memb(Rs+#u6:0)=setbit(#U5)
2949 // MEMb_CLRi_V4 : memb(Rs+#u6:0)=clrbit(#U5)
2950 // MEMb_SETi_V4 : memb(Rs+#u6:0)=setbit(#U5)
2951 //===----------------------------------------------------------------------===//
2953 // memb(Rs+#u6:0) += #U5
2954 let AddedComplexity = 30 in
2955 def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
2956 (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
2957 "memb($base+#$offset) += $addend",
2959 Requires<[HasV4T, UseMEMOP]>;
2961 // memb(Rs+#u6:0) -= #U5
2962 let AddedComplexity = 30 in
2963 def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
2964 (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
2965 "memb($base+#$offset) -= $subend",
2967 Requires<[HasV4T, UseMEMOP]>;
2969 // memb(Rs+#u6:0) += Rt
2970 let AddedComplexity = 30 in
2971 def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2972 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
2973 "memb($base+#$offset) += $addend",
2974 [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
2975 u6_0ImmPred:$offset)),
2976 (i32 IntRegs:$addend)),
2977 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2978 Requires<[HasV4T, UseMEMOP]>;
2980 // memb(Rs+#u6:0) -= Rt
2981 let AddedComplexity = 30 in
2982 def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
2983 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
2984 "memb($base+#$offset) -= $subend",
2985 [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
2986 u6_0ImmPred:$offset)),
2987 (i32 IntRegs:$subend)),
2988 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
2989 Requires<[HasV4T, UseMEMOP]>;
2991 // memb(Rs+#u6:0) &= Rt
2992 let AddedComplexity = 30 in
2993 def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
2994 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
2995 "memb($base+#$offset) += $andend",
2996 [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
2997 u6_0ImmPred:$offset)),
2998 (i32 IntRegs:$andend)),
2999 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3000 Requires<[HasV4T, UseMEMOP]>;
3002 // memb(Rs+#u6:0) |= Rt
3003 let AddedComplexity = 30 in
3004 def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
3005 (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
3006 "memb($base+#$offset) |= $orend",
3007 [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
3008 u6_0ImmPred:$offset)),
3009 (i32 IntRegs:$orend)),
3010 (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
3011 Requires<[HasV4T, UseMEMOP]>;
3013 // memb(Rs+#u6:0) += #U5
3014 let AddedComplexity = 30 in
3015 def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
3016 (ins MEMri:$addr, u5Imm:$addend),
3017 "memb($addr) += $addend",
3019 Requires<[HasV4T, UseMEMOP]>;
3021 // memb(Rs+#u6:0) -= #U5
3022 let AddedComplexity = 30 in
3023 def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
3024 (ins MEMri:$addr, u5Imm:$subend),
3025 "memb($addr) -= $subend",
3027 Requires<[HasV4T, UseMEMOP]>;
3029 // memb(Rs+#u6:0) += Rt
3030 let AddedComplexity = 30 in
3031 def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
3032 (ins MEMri:$addr, IntRegs:$addend),
3033 "memb($addr) += $addend",
3034 [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
3035 (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
3036 Requires<[HasV4T, UseMEMOP]>;
3038 // memb(Rs+#u6:0) -= Rt
3039 let AddedComplexity = 30 in
3040 def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
3041 (ins MEMri:$addr, IntRegs:$subend),
3042 "memb($addr) -= $subend",
3043 [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
3044 (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
3045 Requires<[HasV4T, UseMEMOP]>;
3047 // memb(Rs+#u6:0) &= Rt
3048 let AddedComplexity = 30 in
3049 def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
3050 (ins MEMri:$addr, IntRegs:$andend),
3051 "memb($addr) &= $andend",
3052 [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
3053 (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
3054 Requires<[HasV4T, UseMEMOP]>;
3056 // memb(Rs+#u6:0) |= Rt
3057 let AddedComplexity = 30 in
3058 def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
3059 (ins MEMri:$addr, IntRegs:$orend),
3060 "memb($addr) |= $orend",
3061 [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
3062 (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
3063 Requires<[HasV4T, UseMEMOP]>;
3066 //===----------------------------------------------------------------------===//
3068 //===----------------------------------------------------------------------===//
3070 // Hexagon V4 only supports these flavors of byte/half compare instructions:
3071 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
3072 // hardware. However, compiler can still implement these patterns through
3073 // appropriate patterns combinations based on current implemented patterns.
3074 // The implemented patterns are: EQ/GT/GTU.
3075 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
3077 // Following instruction is not being extended as it results into the
3078 // incorrect code for negative numbers.
3079 // Pd=cmpb.eq(Rs,#u8)
3082 let isCompare = 1, validSubTargets = HasV4SubT in
3083 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
3084 (ins IntRegs:$src1, IntRegs:$src2),
3085 "$dst = !cmp.eq($src1, $src2)",
3086 [(set (i1 PredRegs:$dst),
3087 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
3090 // p=!cmp.eq(r1,#s10)
3091 let isCompare = 1, validSubTargets = HasV4SubT in
3092 def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
3093 (ins IntRegs:$src1, s10Ext:$src2),
3094 "$dst = !cmp.eq($src1, #$src2)",
3095 [(set (i1 PredRegs:$dst),
3096 (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
3100 let isCompare = 1, validSubTargets = HasV4SubT in
3101 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
3102 (ins IntRegs:$src1, IntRegs:$src2),
3103 "$dst = !cmp.gt($src1, $src2)",
3104 [(set (i1 PredRegs:$dst),
3105 (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3108 // p=!cmp.gt(r1,#s10)
3109 let isCompare = 1, validSubTargets = HasV4SubT in
3110 def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
3111 (ins IntRegs:$src1, s10Ext:$src2),
3112 "$dst = !cmp.gt($src1, #$src2)",
3113 [(set (i1 PredRegs:$dst),
3114 (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
3117 // p=!cmp.gtu(r1,r2)
3118 let isCompare = 1, validSubTargets = HasV4SubT in
3119 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
3120 (ins IntRegs:$src1, IntRegs:$src2),
3121 "$dst = !cmp.gtu($src1, $src2)",
3122 [(set (i1 PredRegs:$dst),
3123 (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
3126 // p=!cmp.gtu(r1,#u9)
3127 let isCompare = 1, validSubTargets = HasV4SubT in
3128 def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
3129 (ins IntRegs:$src1, u9Ext:$src2),
3130 "$dst = !cmp.gtu($src1, #$src2)",
3131 [(set (i1 PredRegs:$dst),
3132 (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
3135 let isCompare = 1, validSubTargets = HasV4SubT in
3136 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
3137 (ins IntRegs:$src1, u8Imm:$src2),
3138 "$dst = cmpb.eq($src1, #$src2)",
3139 [(set (i1 PredRegs:$dst),
3140 (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
3143 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
3145 (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
3149 // Pd=cmpb.eq(Rs,Rt)
3150 let isCompare = 1, validSubTargets = HasV4SubT in
3151 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
3152 (ins IntRegs:$src1, IntRegs:$src2),
3153 "$dst = cmpb.eq($src1, $src2)",
3154 [(set (i1 PredRegs:$dst),
3155 (seteq (and (xor (i32 IntRegs:$src1),
3156 (i32 IntRegs:$src2)), 255), 0))]>,
3159 // Pd=cmpb.eq(Rs,Rt)
3160 let isCompare = 1, validSubTargets = HasV4SubT in
3161 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
3162 (ins IntRegs:$src1, IntRegs:$src2),
3163 "$dst = cmpb.eq($src1, $src2)",
3164 [(set (i1 PredRegs:$dst),
3165 (seteq (shl (i32 IntRegs:$src1), (i32 24)),
3166 (shl (i32 IntRegs:$src2), (i32 24))))]>,
3169 // Pd=cmpb.gt(Rs,Rt)
3170 let isCompare = 1, validSubTargets = HasV4SubT in
3171 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
3172 (ins IntRegs:$src1, IntRegs:$src2),
3173 "$dst = cmpb.gt($src1, $src2)",
3174 [(set (i1 PredRegs:$dst),
3175 (setgt (shl (i32 IntRegs:$src1), (i32 24)),
3176 (shl (i32 IntRegs:$src2), (i32 24))))]>,
3179 // Pd=cmpb.gtu(Rs,#u7)
3180 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3181 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
3182 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
3183 (ins IntRegs:$src1, u7Ext:$src2),
3184 "$dst = cmpb.gtu($src1, #$src2)",
3185 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3186 u7ExtPred:$src2))]>,
3187 Requires<[HasV4T]>, ImmRegRel;
3189 // SDNode for converting immediate C to C-1.
3190 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
3191 // Return the byte immediate const-1 as an SDNode.
3192 int32_t imm = N->getSExtValue();
3193 return XformU7ToU7M1Imm(imm);
3197 // zext( seteq ( and(Rs, 255), u8))
3199 // Pd=cmpb.eq(Rs, #u8)
3200 // if (Pd.new) Rd=#1
3201 // if (!Pd.new) Rd=#0
3202 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
3204 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3210 // zext( setne ( and(Rs, 255), u8))
3212 // Pd=cmpb.eq(Rs, #u8)
3213 // if (Pd.new) Rd=#0
3214 // if (!Pd.new) Rd=#1
3215 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
3217 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
3223 // zext( seteq (Rs, and(Rt, 255)))
3225 // Pd=cmpb.eq(Rs, Rt)
3226 // if (Pd.new) Rd=#1
3227 // if (!Pd.new) Rd=#0
3228 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
3229 (i32 (and (i32 IntRegs:$Rs), 255)))))),
3230 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3231 (i32 IntRegs:$Rt))),
3236 // zext( setne (Rs, and(Rt, 255)))
3238 // Pd=cmpb.eq(Rs, Rt)
3239 // if (Pd.new) Rd=#0
3240 // if (!Pd.new) Rd=#1
3241 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
3242 (i32 (and (i32 IntRegs:$Rs), 255)))))),
3243 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
3244 (i32 IntRegs:$Rt))),
3249 // zext( setugt ( and(Rs, 255), u8))
3251 // Pd=cmpb.gtu(Rs, #u8)
3252 // if (Pd.new) Rd=#1
3253 // if (!Pd.new) Rd=#0
3254 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
3256 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3262 // zext( setugt ( and(Rs, 254), u8))
3264 // Pd=cmpb.gtu(Rs, #u8)
3265 // if (Pd.new) Rd=#1
3266 // if (!Pd.new) Rd=#0
3267 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
3269 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
3275 // zext( setult ( Rs, Rt))
3277 // Pd=cmp.ltu(Rs, Rt)
3278 // if (Pd.new) Rd=#1
3279 // if (!Pd.new) Rd=#0
3280 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3281 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3282 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3283 (i32 IntRegs:$Rs))),
3288 // zext( setlt ( Rs, Rt))
3290 // Pd=cmp.lt(Rs, Rt)
3291 // if (Pd.new) Rd=#1
3292 // if (!Pd.new) Rd=#0
3293 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3294 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3295 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3296 (i32 IntRegs:$Rs))),
3301 // zext( setugt ( Rs, Rt))
3303 // Pd=cmp.gtu(Rs, Rt)
3304 // if (Pd.new) Rd=#1
3305 // if (!Pd.new) Rd=#0
3306 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3307 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3308 (i32 IntRegs:$Rt))),
3312 // This pattern interefers with coremark performance, not implementing at this
3315 // zext( setgt ( Rs, Rt))
3317 // Pd=cmp.gt(Rs, Rt)
3318 // if (Pd.new) Rd=#1
3319 // if (!Pd.new) Rd=#0
3322 // zext( setuge ( Rs, Rt))
3324 // Pd=cmp.ltu(Rs, Rt)
3325 // if (Pd.new) Rd=#0
3326 // if (!Pd.new) Rd=#1
3327 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
3328 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3329 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
3330 (i32 IntRegs:$Rs))),
3335 // zext( setge ( Rs, Rt))
3337 // Pd=cmp.lt(Rs, Rt)
3338 // if (Pd.new) Rd=#0
3339 // if (!Pd.new) Rd=#1
3340 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
3341 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3342 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
3343 (i32 IntRegs:$Rs))),
3348 // zext( setule ( Rs, Rt))
3350 // Pd=cmp.gtu(Rs, Rt)
3351 // if (Pd.new) Rd=#0
3352 // if (!Pd.new) Rd=#1
3353 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3354 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
3355 (i32 IntRegs:$Rt))),
3360 // zext( setle ( Rs, Rt))
3362 // Pd=cmp.gt(Rs, Rt)
3363 // if (Pd.new) Rd=#0
3364 // if (!Pd.new) Rd=#1
3365 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
3366 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
3367 (i32 IntRegs:$Rt))),
3372 // zext( setult ( and(Rs, 255), u8))
3373 // Use the isdigit transformation below
3375 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
3376 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
3377 // The isdigit transformation relies on two 'clever' aspects:
3378 // 1) The data type is unsigned which allows us to eliminate a zero test after
3379 // biasing the expression by 48. We are depending on the representation of
3380 // the unsigned types, and semantics.
3381 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
3384 // retval = ((c>='0') & (c<='9')) ? 1 : 0;
3385 // The code is transformed upstream of llvm into
3386 // retval = (c-48) < 10 ? 1 : 0;
3387 let AddedComplexity = 139 in
3388 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
3389 u7StrictPosImmPred:$src2)))),
3390 (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
3391 (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
3395 // Pd=cmpb.gtu(Rs,Rt)
3396 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
3397 InputType = "reg" in
3398 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
3399 (ins IntRegs:$src1, IntRegs:$src2),
3400 "$dst = cmpb.gtu($src1, $src2)",
3401 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
3402 (and (i32 IntRegs:$src2), 255)))]>,
3403 Requires<[HasV4T]>, ImmRegRel;
3405 // Following instruction is not being extended as it results into the incorrect
3406 // code for negative numbers.
3408 // Signed half compare(.eq) ri.
3409 // Pd=cmph.eq(Rs,#s8)
3410 let isCompare = 1, validSubTargets = HasV4SubT in
3411 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
3412 (ins IntRegs:$src1, s8Imm:$src2),
3413 "$dst = cmph.eq($src1, #$src2)",
3414 [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
3415 s8ImmPred:$src2))]>,
3418 // Signed half compare(.eq) rr.
3419 // Case 1: xor + and, then compare:
3421 // r0=and(r0,#0xffff)
3423 // Pd=cmph.eq(Rs,Rt)
3424 let isCompare = 1, validSubTargets = HasV4SubT in
3425 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
3426 (ins IntRegs:$src1, IntRegs:$src2),
3427 "$dst = cmph.eq($src1, $src2)",
3428 [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
3429 (i32 IntRegs:$src2)),
3433 // Signed half compare(.eq) rr.
3434 // Case 2: shift left 16 bits then compare:
3438 // Pd=cmph.eq(Rs,Rt)
3439 let isCompare = 1, validSubTargets = HasV4SubT in
3440 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
3441 (ins IntRegs:$src1, IntRegs:$src2),
3442 "$dst = cmph.eq($src1, $src2)",
3443 [(set (i1 PredRegs:$dst),
3444 (seteq (shl (i32 IntRegs:$src1), (i32 16)),
3445 (shl (i32 IntRegs:$src2), (i32 16))))]>,
3448 /* Incorrect Pattern -- immediate should be right shifted before being
3449 used in the cmph.gt instruction.
3450 // Signed half compare(.gt) ri.
3451 // Pd=cmph.gt(Rs,#s8)
3453 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
3454 isCompare = 1, validSubTargets = HasV4SubT in
3455 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
3456 (ins IntRegs:$src1, s8Ext:$src2),
3457 "$dst = cmph.gt($src1, #$src2)",
3458 [(set (i1 PredRegs:$dst),
3459 (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3460 s8ExtPred:$src2))]>,
3464 // Signed half compare(.gt) rr.
3465 // Pd=cmph.gt(Rs,Rt)
3466 let isCompare = 1, validSubTargets = HasV4SubT in
3467 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
3468 (ins IntRegs:$src1, IntRegs:$src2),
3469 "$dst = cmph.gt($src1, $src2)",
3470 [(set (i1 PredRegs:$dst),
3471 (setgt (shl (i32 IntRegs:$src1), (i32 16)),
3472 (shl (i32 IntRegs:$src2), (i32 16))))]>,
3475 // Unsigned half compare rr (.gtu).
3476 // Pd=cmph.gtu(Rs,Rt)
3477 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3478 InputType = "reg" in
3479 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
3480 (ins IntRegs:$src1, IntRegs:$src2),
3481 "$dst = cmph.gtu($src1, $src2)",
3482 [(set (i1 PredRegs:$dst),
3483 (setugt (and (i32 IntRegs:$src1), 65535),
3484 (and (i32 IntRegs:$src2), 65535)))]>,
3485 Requires<[HasV4T]>, ImmRegRel;
3487 // Unsigned half compare ri (.gtu).
3488 // Pd=cmph.gtu(Rs,#u7)
3489 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
3490 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
3491 InputType = "imm" in
3492 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
3493 (ins IntRegs:$src1, u7Ext:$src2),
3494 "$dst = cmph.gtu($src1, #$src2)",
3495 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
3496 u7ExtPred:$src2))]>,
3497 Requires<[HasV4T]>, ImmRegRel;
3499 let validSubTargets = HasV4SubT in
3500 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
3501 "$dst = !tstbit($src1, $src2)",
3502 [(set (i1 PredRegs:$dst),
3503 (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
3506 let validSubTargets = HasV4SubT in
3507 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
3508 "$dst = !tstbit($src1, $src2)",
3509 [(set (i1 PredRegs:$dst),
3510 (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
3513 //===----------------------------------------------------------------------===//
3515 //===----------------------------------------------------------------------===//
3517 //Deallocate frame and return.
3519 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
3520 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
3521 def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
3527 // Restore registers and dealloc return function call.
3528 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
3529 Defs = [R29, R30, R31, PC] in {
3530 def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
3531 (ins calltarget:$dst),
3532 "jump $dst // Restore_and_dealloc_return",
3537 // Restore registers and dealloc frame before a tail call.
3538 let isCall = 1, isBarrier = 1,
3539 Defs = [R29, R30, R31, PC] in {
3540 def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
3541 (ins calltarget:$dst),
3542 "call $dst // Restore_and_dealloc_before_tailcall",
3547 // Save registers function call.
3548 let isCall = 1, isBarrier = 1,
3549 Uses = [R29, R31] in {
3550 def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
3551 (ins calltarget:$dst),
3552 "call $dst // Save_calle_saved_registers",
3557 // if (Ps) dealloc_return
3558 let isReturn = 1, isTerminator = 1,
3559 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3560 isPredicated = 1 in {
3561 def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
3562 (ins PredRegs:$src1, i32imm:$amt1),
3563 "if ($src1) dealloc_return",
3568 // if (!Ps) dealloc_return
3569 let isReturn = 1, isTerminator = 1,
3570 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3571 isPredicated = 1 in {
3572 def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3574 "if (!$src1) dealloc_return",
3579 // if (Ps.new) dealloc_return:nt
3580 let isReturn = 1, isTerminator = 1,
3581 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3582 isPredicated = 1 in {
3583 def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3585 "if ($src1.new) dealloc_return:nt",
3590 // if (!Ps.new) dealloc_return:nt
3591 let isReturn = 1, isTerminator = 1,
3592 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3593 isPredicated = 1 in {
3594 def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3596 "if (!$src1.new) dealloc_return:nt",
3601 // if (Ps.new) dealloc_return:t
3602 let isReturn = 1, isTerminator = 1,
3603 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3604 isPredicated = 1 in {
3605 def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3607 "if ($src1.new) dealloc_return:t",
3612 // if (!Ps.new) dealloc_return:nt
3613 let isReturn = 1, isTerminator = 1,
3614 Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
3615 isPredicated = 1 in {
3616 def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
3618 "if (!$src1.new) dealloc_return:t",
3623 // Load/Store with absolute addressing mode
3626 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3628 let PNewValue = !if(isPredNew, "new", "") in
3629 def NAME#_V4 : STInst2<(outs),
3630 (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3631 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3632 ") ")#mnemonic#"(##$absaddr) = $src2",
3637 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3638 let PredSense = !if(PredNot, "false", "true") in {
3639 defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3641 defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3645 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
3646 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3647 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3648 let opExtendable = 0, isPredicable = 1 in
3649 def NAME#_V4 : STInst2<(outs),
3650 (ins globaladdressExt:$absaddr, RC:$src),
3651 mnemonic#"(##$absaddr) = $src",
3655 let opExtendable = 1, isPredicated = 1 in {
3656 defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
3657 defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
3662 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
3664 let PNewValue = !if(isPredNew, "new", "") in
3665 def NAME#_nv_V4 : NVInst_V4<(outs),
3666 (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
3667 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3668 ") ")#mnemonic#"(##$absaddr) = $src2.new",
3673 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
3674 let PredSense = !if(PredNot, "false", "true") in {
3675 defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
3677 defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
3681 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
3682 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
3683 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3684 let opExtendable = 0, isPredicable = 1 in
3685 def NAME#_nv_V4 : NVInst_V4<(outs),
3686 (ins globaladdressExt:$absaddr, RC:$src),
3687 mnemonic#"(##$absaddr) = $src.new",
3691 let opExtendable = 1, isPredicated = 1 in {
3692 defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
3693 defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
3698 let addrMode = Absolute in {
3699 defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
3700 ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
3702 defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
3703 ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
3705 defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
3706 ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
3708 let isNVStorable = 0 in
3709 defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
3712 let Predicates = [HasV4T], AddedComplexity = 30 in {
3713 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
3714 (HexagonCONST32 tglobaladdr:$absaddr)),
3715 (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3717 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
3718 (HexagonCONST32 tglobaladdr:$absaddr)),
3719 (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3721 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
3722 (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
3724 def : Pat<(store (i64 DoubleRegs:$src1),
3725 (HexagonCONST32 tglobaladdr:$absaddr)),
3726 (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
3729 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
3731 let PNewValue = !if(isPredNew, "new", "") in
3732 def NAME : LDInst2<(outs RC:$dst),
3733 (ins PredRegs:$src1, globaladdressExt:$absaddr),
3734 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
3735 ") ")#"$dst = "#mnemonic#"(##$absaddr)",
3740 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
3741 let PredSense = !if(PredNot, "false", "true") in {
3742 defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
3744 defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
3748 let isExtended = 1, neverHasSideEffects = 1 in
3749 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
3750 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
3751 let opExtendable = 1, isPredicable = 1 in
3752 def NAME#_V4 : LDInst2<(outs RC:$dst),
3753 (ins globaladdressExt:$absaddr),
3754 "$dst = "#mnemonic#"(##$absaddr)",
3758 let opExtendable = 2, isPredicated = 1 in {
3759 defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
3760 defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
3765 let addrMode = Absolute in {
3766 defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3767 defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
3768 defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3769 defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
3770 defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
3771 defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
3774 let Predicates = [HasV4T], AddedComplexity = 30 in
3775 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3776 (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3778 let Predicates = [HasV4T], AddedComplexity=30 in
3779 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3780 (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3782 let Predicates = [HasV4T], AddedComplexity=30 in
3783 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3784 (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3786 let Predicates = [HasV4T], AddedComplexity=30 in
3787 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3788 (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3790 let Predicates = [HasV4T], AddedComplexity=30 in
3791 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3792 (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
3794 // Transfer global address into a register
3795 let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
3796 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
3798 [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3801 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3802 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3803 (ins PredRegs:$src1, globaladdress:$src2),
3804 "if($src1) $dst = ##$src2",
3808 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3809 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3810 (ins PredRegs:$src1, globaladdress:$src2),
3811 "if(!$src1) $dst = ##$src2",
3815 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3816 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3817 (ins PredRegs:$src1, globaladdress:$src2),
3818 "if($src1.new) $dst = ##$src2",
3822 let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
3823 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3824 (ins PredRegs:$src1, globaladdress:$src2),
3825 "if(!$src1.new) $dst = ##$src2",
3829 let AddedComplexity = 50, Predicates = [HasV4T] in
3830 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3831 (TFRI_V4 tglobaladdr:$src1)>;
3834 // Load - Indirect with long offset: These instructions take global address
3836 let AddedComplexity = 10 in
3837 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3838 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3839 "$dst=memd($src1<<#$src2+##$offset)",
3840 [(set (i64 DoubleRegs:$dst),
3841 (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3842 (HexagonCONST32 tglobaladdr:$offset))))]>,
3845 let AddedComplexity = 10 in
3846 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
3847 def _lo_V4 : LDInst<(outs IntRegs:$dst),
3848 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
3849 !strconcat("$dst = ",
3850 !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3852 (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
3853 (HexagonCONST32 tglobaladdr:$offset)))))]>,
3857 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3858 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
3859 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3860 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
3861 defm LDriw_ind : LD_indirect_lo<"memw", load>;
3863 // Store - Indirect with long offset: These instructions take global address
3865 let AddedComplexity = 10 in
3866 def STrid_ind_lo_V4 : STInst<(outs),
3867 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3869 "memd($src1<<#$src2+#$src3) = $src4",
3870 [(store (i64 DoubleRegs:$src4),
3871 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3872 (HexagonCONST32 tglobaladdr:$src3)))]>,
3875 let AddedComplexity = 10 in
3876 multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
3877 def _lo_V4 : STInst<(outs),
3878 (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3880 !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
3881 [(OpNode (i32 IntRegs:$src4),
3882 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3883 (HexagonCONST32 tglobaladdr:$src3)))]>,
3887 defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
3888 defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
3889 defm STriw_ind : ST_indirect_lo<"memw", store>;
3891 // Store - absolute addressing mode: These instruction take constant
3892 // value as the extended operand.
3893 multiclass ST_absimm<string OpcStr> {
3894 let isExtended = 1, opExtendable = 0, isPredicable = 1,
3895 validSubTargets = HasV4SubT in
3896 def _abs_V4 : STInst2<(outs),
3897 (ins u0AlwaysExt:$src1, IntRegs:$src2),
3898 !strconcat(OpcStr, "(##$src1) = $src2"),
3902 let isExtended = 1, opExtendable = 1, isPredicated = 1,
3903 validSubTargets = HasV4SubT in {
3904 def _abs_cPt_V4 : STInst2<(outs),
3905 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3906 !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3910 def _abs_cNotPt_V4 : STInst2<(outs),
3911 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3912 !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3916 def _abs_cdnPt_V4 : STInst2<(outs),
3917 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3918 !strconcat("if ($src1.new)",
3919 !strconcat(OpcStr, "(##$src2) = $src3")),
3923 def _abs_cdnNotPt_V4 : STInst2<(outs),
3924 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3925 !strconcat("if (!$src1.new)",
3926 !strconcat(OpcStr, "(##$src2) = $src3")),
3931 let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
3932 validSubTargets = HasV4SubT in
3933 def _abs_nv_V4 : NVInst_V4<(outs),
3934 (ins u0AlwaysExt:$src1, IntRegs:$src2),
3935 !strconcat(OpcStr, "(##$src1) = $src2.new"),
3939 let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
3940 isNVStore = 1, validSubTargets = HasV4SubT in {
3941 def _abs_cPt_nv_V4 : NVInst_V4<(outs),
3942 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3943 !strconcat("if ($src1)",
3944 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3948 def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
3949 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3950 !strconcat("if (!$src1)",
3951 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3955 def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
3956 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3957 !strconcat("if ($src1.new)",
3958 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3962 def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
3963 (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3964 !strconcat("if (!$src1.new)",
3965 !strconcat(OpcStr, "(##$src2) = $src3.new")),
3971 defm STrib_imm : ST_absimm<"memb">;
3972 defm STrih_imm : ST_absimm<"memh">;
3973 defm STriw_imm : ST_absimm<"memw">;
3975 let Predicates = [HasV4T], AddedComplexity = 30 in {
3976 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3977 (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3979 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3980 (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3982 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3983 (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3986 // Load - absolute addressing mode: These instruction take constant
3987 // value as the extended operand
3989 multiclass LD_absimm<string OpcStr> {
3990 let isExtended = 1, opExtendable = 1, isPredicable = 1,
3991 validSubTargets = HasV4SubT in
3992 def _abs_V4 : LDInst2<(outs IntRegs:$dst),
3993 (ins u0AlwaysExt:$src),
3994 !strconcat("$dst = ",
3995 !strconcat(OpcStr, "(##$src)")),
3999 let isExtended = 1, opExtendable = 2, isPredicated = 1,
4000 validSubTargets = HasV4SubT in {
4001 def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
4002 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4003 !strconcat("if ($src1) $dst = ",
4004 !strconcat(OpcStr, "(##$src2)")),
4008 def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4009 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4010 !strconcat("if (!$src1) $dst = ",
4011 !strconcat(OpcStr, "(##$src2)")),
4015 def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
4016 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4017 !strconcat("if ($src1.new) $dst = ",
4018 !strconcat(OpcStr, "(##$src2)")),
4022 def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
4023 (ins PredRegs:$src1, u0AlwaysExt:$src2),
4024 !strconcat("if (!$src1.new) $dst = ",
4025 !strconcat(OpcStr, "(##$src2)")),
4031 defm LDrib_imm : LD_absimm<"memb">;
4032 defm LDriub_imm : LD_absimm<"memub">;
4033 defm LDrih_imm : LD_absimm<"memh">;
4034 defm LDriuh_imm : LD_absimm<"memuh">;
4035 defm LDriw_imm : LD_absimm<"memw">;
4037 let Predicates = [HasV4T], AddedComplexity = 30 in {
4038 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
4039 (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
4041 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
4042 (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
4044 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
4045 (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
4047 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
4048 (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
4050 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
4051 (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
4054 // Indexed store double word - global address.
4055 // memw(Rs+#u6:2)=#S8
4056 let AddedComplexity = 10 in
4057 def STriw_offset_ext_V4 : STInst<(outs),
4058 (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
4059 "memw($src1+#$src2) = ##$src3",
4060 [(store (HexagonCONST32 tglobaladdr:$src3),
4061 (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
4065 // Indexed store double word - global address.
4066 // memw(Rs+#u6:2)=#S8
4067 let AddedComplexity = 10 in
4068 def STrih_offset_ext_V4 : STInst<(outs),
4069 (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
4070 "memh($src1+#$src2) = ##$src3",
4071 [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
4072 (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
4074 // Map from store(globaladdress + x) -> memd(#foo + x)
4075 let AddedComplexity = 100 in
4076 def : Pat<(store (i64 DoubleRegs:$src1),
4077 FoldGlobalAddrGP:$addr),
4078 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4081 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
4082 (i64 DoubleRegs:$src1)),
4083 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
4086 // Map from store(globaladdress + x) -> memb(#foo + x)
4087 let AddedComplexity = 100 in
4088 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4089 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4092 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4093 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4096 // Map from store(globaladdress + x) -> memh(#foo + x)
4097 let AddedComplexity = 100 in
4098 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4099 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4102 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4103 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4106 // Map from store(globaladdress + x) -> memw(#foo + x)
4107 let AddedComplexity = 100 in
4108 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
4109 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4112 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
4113 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
4116 // Map from load(globaladdress + x) -> memd(#foo + x)
4117 let AddedComplexity = 100 in
4118 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
4119 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4122 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
4123 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
4126 // Map from load(globaladdress + x) -> memb(#foo + x)
4127 let AddedComplexity = 100 in
4128 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
4129 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4132 // Map from load(globaladdress + x) -> memb(#foo + x)
4133 let AddedComplexity = 100 in
4134 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
4135 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
4138 //let AddedComplexity = 100 in
4139 let AddedComplexity = 100 in
4140 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
4141 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4144 // Map from load(globaladdress + x) -> memh(#foo + x)
4145 let AddedComplexity = 100 in
4146 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
4147 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
4150 // Map from load(globaladdress + x) -> memuh(#foo + x)
4151 let AddedComplexity = 100 in
4152 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
4153 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4156 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
4157 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
4160 // Map from load(globaladdress + x) -> memub(#foo + x)
4161 let AddedComplexity = 100 in
4162 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
4163 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4166 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
4167 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
4170 // Map from load(globaladdress + x) -> memw(#foo + x)
4171 let AddedComplexity = 100 in
4172 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
4173 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
4176 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
4177 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,