summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAndrzej Warzynski <andrzej.warzynski@arm.com>2019-12-20 10:51:25 +0000
committerAndrzej Warzynski <andrzej.warzynski@arm.com>2019-12-20 11:09:40 +0000
commitbe2b7ea89ab43d6827634fbdbbd2661e1f242527 (patch)
tree68e105f9b40d5e62adfb158797d442c333a9c0eb /llvm/lib
parent3f9005eb89f70e6f5d72c69525abf427be5cbcb6 (diff)
downloadbcm5719-llvm-be2b7ea89ab43d6827634fbdbbd2661e1f242527.tar.gz
bcm5719-llvm-be2b7ea89ab43d6827634fbdbbd2661e1f242527.zip
[AArch64][SVE] Add intrnisics for saturating scalar arithmetic
Summary: The following intrnisics are added: * @llvm.aarch64.sve.sqdec{b|h|w|d|p} * @llvm.aarch64.sve.sqinc{b|h|w|d|p} * @llvm.aarch64.sve.uqdec{b|h|w|d|p} * @llvm.aarch64.sve.uqinc{b|h|w|d|p} For every intrnisic there a scalar variants (with n32 or n64 suffix) and vector variants (no suffix). Reviewers: sdesmalen, rengolin, efriedma Reviewed By: sdesmalen, efriedma Subscribers: eli.friedman, tschuett, kristof.beyls, hiraditya, rkruppe, psnobl, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71252
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td120
-rw-r--r--llvm/lib/Target/AArch64/SVEInstrFormats.td86
2 files changed, 137 insertions, 69 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 01c6037537f..28cb5e7952d 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -852,76 +852,76 @@ let Predicates = [HasSVE] in {
defm INCD_XPiI : sve_int_pred_pattern_a<0b110, "incd">;
defm DECD_XPiI : sve_int_pred_pattern_a<0b111, "decd">;
- defm SQINCB_XPiWdI : sve_int_pred_pattern_b_s32<0b00000, "sqincb">;
- defm UQINCB_WPiI : sve_int_pred_pattern_b_u32<0b00001, "uqincb">;
- defm SQDECB_XPiWdI : sve_int_pred_pattern_b_s32<0b00010, "sqdecb">;
- defm UQDECB_WPiI : sve_int_pred_pattern_b_u32<0b00011, "uqdecb">;
- defm SQINCB_XPiI : sve_int_pred_pattern_b_x64<0b00100, "sqincb">;
- defm UQINCB_XPiI : sve_int_pred_pattern_b_x64<0b00101, "uqincb">;
- defm SQDECB_XPiI : sve_int_pred_pattern_b_x64<0b00110, "sqdecb">;
- defm UQDECB_XPiI : sve_int_pred_pattern_b_x64<0b00111, "uqdecb">;
-
- defm SQINCH_XPiWdI : sve_int_pred_pattern_b_s32<0b01000, "sqinch">;
- defm UQINCH_WPiI : sve_int_pred_pattern_b_u32<0b01001, "uqinch">;
- defm SQDECH_XPiWdI : sve_int_pred_pattern_b_s32<0b01010, "sqdech">;
- defm UQDECH_WPiI : sve_int_pred_pattern_b_u32<0b01011, "uqdech">;
- defm SQINCH_XPiI : sve_int_pred_pattern_b_x64<0b01100, "sqinch">;
- defm UQINCH_XPiI : sve_int_pred_pattern_b_x64<0b01101, "uqinch">;
- defm SQDECH_XPiI : sve_int_pred_pattern_b_x64<0b01110, "sqdech">;
- defm UQDECH_XPiI : sve_int_pred_pattern_b_x64<0b01111, "uqdech">;
-
- defm SQINCW_XPiWdI : sve_int_pred_pattern_b_s32<0b10000, "sqincw">;
- defm UQINCW_WPiI : sve_int_pred_pattern_b_u32<0b10001, "uqincw">;
- defm SQDECW_XPiWdI : sve_int_pred_pattern_b_s32<0b10010, "sqdecw">;
- defm UQDECW_WPiI : sve_int_pred_pattern_b_u32<0b10011, "uqdecw">;
- defm SQINCW_XPiI : sve_int_pred_pattern_b_x64<0b10100, "sqincw">;
- defm UQINCW_XPiI : sve_int_pred_pattern_b_x64<0b10101, "uqincw">;
- defm SQDECW_XPiI : sve_int_pred_pattern_b_x64<0b10110, "sqdecw">;
- defm UQDECW_XPiI : sve_int_pred_pattern_b_x64<0b10111, "uqdecw">;
-
- defm SQINCD_XPiWdI : sve_int_pred_pattern_b_s32<0b11000, "sqincd">;
- defm UQINCD_WPiI : sve_int_pred_pattern_b_u32<0b11001, "uqincd">;
- defm SQDECD_XPiWdI : sve_int_pred_pattern_b_s32<0b11010, "sqdecd">;
- defm UQDECD_WPiI : sve_int_pred_pattern_b_u32<0b11011, "uqdecd">;
- defm SQINCD_XPiI : sve_int_pred_pattern_b_x64<0b11100, "sqincd">;
- defm UQINCD_XPiI : sve_int_pred_pattern_b_x64<0b11101, "uqincd">;
- defm SQDECD_XPiI : sve_int_pred_pattern_b_x64<0b11110, "sqdecd">;
- defm UQDECD_XPiI : sve_int_pred_pattern_b_x64<0b11111, "uqdecd">;
-
- defm SQINCH_ZPiI : sve_int_countvlv<0b01000, "sqinch", ZPR16>;
- defm UQINCH_ZPiI : sve_int_countvlv<0b01001, "uqinch", ZPR16>;
- defm SQDECH_ZPiI : sve_int_countvlv<0b01010, "sqdech", ZPR16>;
- defm UQDECH_ZPiI : sve_int_countvlv<0b01011, "uqdech", ZPR16>;
+ defm SQINCB_XPiWdI : sve_int_pred_pattern_b_s32<0b00000, "sqincb", int_aarch64_sve_sqincb_n32>;
+ defm UQINCB_WPiI : sve_int_pred_pattern_b_u32<0b00001, "uqincb", int_aarch64_sve_uqincb_n32>;
+ defm SQDECB_XPiWdI : sve_int_pred_pattern_b_s32<0b00010, "sqdecb", int_aarch64_sve_sqdecb_n32>;
+ defm UQDECB_WPiI : sve_int_pred_pattern_b_u32<0b00011, "uqdecb", int_aarch64_sve_uqdecb_n32>;
+ defm SQINCB_XPiI : sve_int_pred_pattern_b_x64<0b00100, "sqincb", int_aarch64_sve_sqincb_n64>;
+ defm UQINCB_XPiI : sve_int_pred_pattern_b_x64<0b00101, "uqincb", int_aarch64_sve_uqincb_n64>;
+ defm SQDECB_XPiI : sve_int_pred_pattern_b_x64<0b00110, "sqdecb", int_aarch64_sve_sqdecb_n64>;
+ defm UQDECB_XPiI : sve_int_pred_pattern_b_x64<0b00111, "uqdecb", int_aarch64_sve_uqdecb_n64>;
+
+ defm SQINCH_XPiWdI : sve_int_pred_pattern_b_s32<0b01000, "sqinch", int_aarch64_sve_sqinch_n32>;
+ defm UQINCH_WPiI : sve_int_pred_pattern_b_u32<0b01001, "uqinch", int_aarch64_sve_uqinch_n32>;
+ defm SQDECH_XPiWdI : sve_int_pred_pattern_b_s32<0b01010, "sqdech", int_aarch64_sve_sqdech_n32>;
+ defm UQDECH_WPiI : sve_int_pred_pattern_b_u32<0b01011, "uqdech", int_aarch64_sve_uqdech_n32>;
+ defm SQINCH_XPiI : sve_int_pred_pattern_b_x64<0b01100, "sqinch", int_aarch64_sve_sqinch_n64>;
+ defm UQINCH_XPiI : sve_int_pred_pattern_b_x64<0b01101, "uqinch", int_aarch64_sve_uqinch_n64>;
+ defm SQDECH_XPiI : sve_int_pred_pattern_b_x64<0b01110, "sqdech", int_aarch64_sve_sqdech_n64>;
+ defm UQDECH_XPiI : sve_int_pred_pattern_b_x64<0b01111, "uqdech", int_aarch64_sve_uqdech_n64>;
+
+ defm SQINCW_XPiWdI : sve_int_pred_pattern_b_s32<0b10000, "sqincw", int_aarch64_sve_sqincw_n32>;
+ defm UQINCW_WPiI : sve_int_pred_pattern_b_u32<0b10001, "uqincw", int_aarch64_sve_uqincw_n32>;
+ defm SQDECW_XPiWdI : sve_int_pred_pattern_b_s32<0b10010, "sqdecw", int_aarch64_sve_sqdecw_n32>;
+ defm UQDECW_WPiI : sve_int_pred_pattern_b_u32<0b10011, "uqdecw", int_aarch64_sve_uqdecw_n32>;
+ defm SQINCW_XPiI : sve_int_pred_pattern_b_x64<0b10100, "sqincw", int_aarch64_sve_sqincw_n64>;
+ defm UQINCW_XPiI : sve_int_pred_pattern_b_x64<0b10101, "uqincw", int_aarch64_sve_uqincw_n64>;
+ defm SQDECW_XPiI : sve_int_pred_pattern_b_x64<0b10110, "sqdecw", int_aarch64_sve_sqdecw_n64>;
+ defm UQDECW_XPiI : sve_int_pred_pattern_b_x64<0b10111, "uqdecw", int_aarch64_sve_uqdecw_n64>;
+
+ defm SQINCD_XPiWdI : sve_int_pred_pattern_b_s32<0b11000, "sqincd", int_aarch64_sve_sqincd_n32>;
+ defm UQINCD_WPiI : sve_int_pred_pattern_b_u32<0b11001, "uqincd", int_aarch64_sve_uqincd_n32>;
+ defm SQDECD_XPiWdI : sve_int_pred_pattern_b_s32<0b11010, "sqdecd", int_aarch64_sve_sqdecd_n32>;
+ defm UQDECD_WPiI : sve_int_pred_pattern_b_u32<0b11011, "uqdecd", int_aarch64_sve_uqdecd_n32>;
+ defm SQINCD_XPiI : sve_int_pred_pattern_b_x64<0b11100, "sqincd", int_aarch64_sve_sqincd_n64>;
+ defm UQINCD_XPiI : sve_int_pred_pattern_b_x64<0b11101, "uqincd", int_aarch64_sve_uqincd_n64>;
+ defm SQDECD_XPiI : sve_int_pred_pattern_b_x64<0b11110, "sqdecd", int_aarch64_sve_sqdecd_n64>;
+ defm UQDECD_XPiI : sve_int_pred_pattern_b_x64<0b11111, "uqdecd", int_aarch64_sve_uqdecd_n64>;
+
+ defm SQINCH_ZPiI : sve_int_countvlv<0b01000, "sqinch", ZPR16, int_aarch64_sve_sqinch, nxv8i16>;
+ defm UQINCH_ZPiI : sve_int_countvlv<0b01001, "uqinch", ZPR16, int_aarch64_sve_uqinch, nxv8i16>;
+ defm SQDECH_ZPiI : sve_int_countvlv<0b01010, "sqdech", ZPR16, int_aarch64_sve_sqdech, nxv8i16>;
+ defm UQDECH_ZPiI : sve_int_countvlv<0b01011, "uqdech", ZPR16, int_aarch64_sve_uqdech, nxv8i16>;
defm INCH_ZPiI : sve_int_countvlv<0b01100, "inch", ZPR16>;
defm DECH_ZPiI : sve_int_countvlv<0b01101, "dech", ZPR16>;
- defm SQINCW_ZPiI : sve_int_countvlv<0b10000, "sqincw", ZPR32>;
- defm UQINCW_ZPiI : sve_int_countvlv<0b10001, "uqincw", ZPR32>;
- defm SQDECW_ZPiI : sve_int_countvlv<0b10010, "sqdecw", ZPR32>;
- defm UQDECW_ZPiI : sve_int_countvlv<0b10011, "uqdecw", ZPR32>;
+ defm SQINCW_ZPiI : sve_int_countvlv<0b10000, "sqincw", ZPR32, int_aarch64_sve_sqincw, nxv4i32>;
+ defm UQINCW_ZPiI : sve_int_countvlv<0b10001, "uqincw", ZPR32, int_aarch64_sve_uqincw, nxv4i32>;
+ defm SQDECW_ZPiI : sve_int_countvlv<0b10010, "sqdecw", ZPR32, int_aarch64_sve_sqdecw, nxv4i32>;
+ defm UQDECW_ZPiI : sve_int_countvlv<0b10011, "uqdecw", ZPR32, int_aarch64_sve_uqdecw, nxv4i32>;
defm INCW_ZPiI : sve_int_countvlv<0b10100, "incw", ZPR32>;
defm DECW_ZPiI : sve_int_countvlv<0b10101, "decw", ZPR32>;
- defm SQINCD_ZPiI : sve_int_countvlv<0b11000, "sqincd", ZPR64>;
- defm UQINCD_ZPiI : sve_int_countvlv<0b11001, "uqincd", ZPR64>;
- defm SQDECD_ZPiI : sve_int_countvlv<0b11010, "sqdecd", ZPR64>;
- defm UQDECD_ZPiI : sve_int_countvlv<0b11011, "uqdecd", ZPR64>;
+ defm SQINCD_ZPiI : sve_int_countvlv<0b11000, "sqincd", ZPR64, int_aarch64_sve_sqincd, nxv2i64>;
+ defm UQINCD_ZPiI : sve_int_countvlv<0b11001, "uqincd", ZPR64, int_aarch64_sve_uqincd, nxv2i64>;
+ defm SQDECD_ZPiI : sve_int_countvlv<0b11010, "sqdecd", ZPR64, int_aarch64_sve_sqdecd, nxv2i64>;
+ defm UQDECD_ZPiI : sve_int_countvlv<0b11011, "uqdecd", ZPR64, int_aarch64_sve_uqdecd, nxv2i64>;
defm INCD_ZPiI : sve_int_countvlv<0b11100, "incd", ZPR64>;
defm DECD_ZPiI : sve_int_countvlv<0b11101, "decd", ZPR64>;
- defm SQINCP_XPWd : sve_int_count_r_s32<0b00000, "sqincp">;
- defm SQINCP_XP : sve_int_count_r_x64<0b00010, "sqincp">;
- defm UQINCP_WP : sve_int_count_r_u32<0b00100, "uqincp">;
- defm UQINCP_XP : sve_int_count_r_x64<0b00110, "uqincp">;
- defm SQDECP_XPWd : sve_int_count_r_s32<0b01000, "sqdecp">;
- defm SQDECP_XP : sve_int_count_r_x64<0b01010, "sqdecp">;
- defm UQDECP_WP : sve_int_count_r_u32<0b01100, "uqdecp">;
- defm UQDECP_XP : sve_int_count_r_x64<0b01110, "uqdecp">;
+ defm SQINCP_XPWd : sve_int_count_r_s32<0b00000, "sqincp", int_aarch64_sve_sqincp_n32>;
+ defm SQINCP_XP : sve_int_count_r_x64<0b00010, "sqincp", int_aarch64_sve_sqincp_n64>;
+ defm UQINCP_WP : sve_int_count_r_u32<0b00100, "uqincp", int_aarch64_sve_uqincp_n32>;
+ defm UQINCP_XP : sve_int_count_r_x64<0b00110, "uqincp", int_aarch64_sve_uqincp_n64>;
+ defm SQDECP_XPWd : sve_int_count_r_s32<0b01000, "sqdecp", int_aarch64_sve_sqdecp_n32>;
+ defm SQDECP_XP : sve_int_count_r_x64<0b01010, "sqdecp", int_aarch64_sve_sqdecp_n64>;
+ defm UQDECP_WP : sve_int_count_r_u32<0b01100, "uqdecp", int_aarch64_sve_uqdecp_n32>;
+ defm UQDECP_XP : sve_int_count_r_x64<0b01110, "uqdecp", int_aarch64_sve_uqdecp_n64>;
defm INCP_XP : sve_int_count_r_x64<0b10000, "incp">;
defm DECP_XP : sve_int_count_r_x64<0b10100, "decp">;
- defm SQINCP_ZP : sve_int_count_v<0b00000, "sqincp">;
- defm UQINCP_ZP : sve_int_count_v<0b00100, "uqincp">;
- defm SQDECP_ZP : sve_int_count_v<0b01000, "sqdecp">;
- defm UQDECP_ZP : sve_int_count_v<0b01100, "uqdecp">;
+ defm SQINCP_ZP : sve_int_count_v<0b00000, "sqincp", int_aarch64_sve_sqincp>;
+ defm UQINCP_ZP : sve_int_count_v<0b00100, "uqincp", int_aarch64_sve_uqincp>;
+ defm SQDECP_ZP : sve_int_count_v<0b01000, "sqdecp", int_aarch64_sve_sqdecp>;
+ defm UQDECP_ZP : sve_int_count_v<0b01100, "uqdecp", int_aarch64_sve_uqdecp>;
defm INCP_ZP : sve_int_count_v<0b10000, "incp">;
defm DECP_ZP : sve_int_count_v<0b10100, "decp">;
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index c983d2b8a0c..0a3df4f2b71 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -236,7 +236,7 @@ def sve_fpimm_zero_one
: SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
"AArch64ExactFPImm::one">;
-def sve_incdec_imm : Operand<i32>, ImmLeaf<i32, [{
+def sve_incdec_imm : Operand<i32>, TImmLeaf<i32, [{
return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
}]> {
let ParserMatchClass = Imm1_16Operand;
@@ -470,25 +470,66 @@ class sve_int_count_r<bits<2> sz8_64, bits<5> opc, string asm,
let Constraints = "$Rdn = $_Rdn";
}
-multiclass sve_int_count_r_s32<bits<5> opc, string asm> {
+multiclass sve_int_count_r_s32<bits<5> opc, string asm,
+ SDPatternOperator op> {
def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64as32>;
def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64as32>;
def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64as32>;
def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64as32>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
+ (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
+ def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))))),
+ (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
+ (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
+ def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))))),
+ (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
+ (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
+ def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))))),
+ (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
+ (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
+ def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))))),
+ (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
}
-multiclass sve_int_count_r_u32<bits<5> opc, string asm> {
+multiclass sve_int_count_r_u32<bits<5> opc, string asm,
+ SDPatternOperator op> {
def _B : sve_int_count_r<0b00, opc, asm, GPR32z, PPR8, GPR32z>;
def _H : sve_int_count_r<0b01, opc, asm, GPR32z, PPR16, GPR32z>;
def _S : sve_int_count_r<0b10, opc, asm, GPR32z, PPR32, GPR32z>;
def _D : sve_int_count_r<0b11, opc, asm, GPR32z, PPR64, GPR32z>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
}
-multiclass sve_int_count_r_x64<bits<5> opc, string asm> {
+multiclass sve_int_count_r_x64<bits<5> opc, string asm,
+ SDPatternOperator op = null_frag> {
def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64z>;
def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64z>;
def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64z>;
def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64z>;
+
+ def : Pat<(i64 (op GPR64:$Rn, (nxv16i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i64 (op GPR64:$Rn, (nxv8i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i64 (op GPR64:$Rn, (nxv4i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
+ def : Pat<(i64 (op GPR64:$Rn, (nxv2i1 PPRAny:$Pg))),
+ (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
}
class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
@@ -513,11 +554,16 @@ class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
let ElementSize = ElementSizeNone;
}
-multiclass sve_int_count_v<bits<5> opc, string asm> {
+multiclass sve_int_count_v<bits<5> opc, string asm,
+ SDPatternOperator op = null_frag> {
def _H : sve_int_count_v<0b01, opc, asm, ZPR16, PPR16>;
def _S : sve_int_count_v<0b10, opc, asm, ZPR32, PPR32>;
def _D : sve_int_count_v<0b11, opc, asm, ZPR64, PPR64>;
+ def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, !cast<Instruction>(NAME # _H)>;
+ def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, !cast<Instruction>(NAME # _S)>;
+ def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, !cast<Instruction>(NAME # _D)>;
+
def : InstAlias<asm # "\t$Zdn, $Pm",
(!cast<Instruction>(NAME # "_H") ZPR16:$Zdn, PPRAny:$Pm), 0>;
def : InstAlias<asm # "\t$Zdn, $Pm",
@@ -616,13 +662,18 @@ class sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty>
let ElementSize = ElementSizeNone;
}
-multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty> {
+multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty,
+ SDPatternOperator op = null_frag,
+ ValueType vt = OtherVT> {
def NAME : sve_int_countvlv<opc, asm, zprty>;
def : InstAlias<asm # "\t$Zdn, $pattern",
(!cast<Instruction>(NAME) zprty:$Zdn, sve_pred_enum:$pattern, 1), 1>;
def : InstAlias<asm # "\t$Zdn",
(!cast<Instruction>(NAME) zprty:$Zdn, 0b11111, 1), 2>;
+
+ def : Pat<(vt (op (vt zprty:$Zn), (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
+ (!cast<Instruction>(NAME) $Zn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
}
class sve_int_pred_pattern_a<bits<3> opc, string asm>
@@ -681,31 +732,48 @@ class sve_int_pred_pattern_b<bits<5> opc, string asm, RegisterOperand dt,
let Constraints = "$Rdn = $_Rdn";
}
-multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm> {
+multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm,
+ SDPatternOperator op> {
def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64as32>;
def : InstAlias<asm # "\t$Rd, $Rn, $pattern",
(!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, sve_pred_enum:$pattern, 1), 1>;
def : InstAlias<asm # "\t$Rd, $Rn",
(!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, 0b11111, 1), 2>;
+
+ // NOTE: Register allocation doesn't like tied operands of differing register
+ // class, hence the extra INSERT_SUBREG complication.
+
+ def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
+ (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4), sub_32)>;
+ def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))))),
+ (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
}
-multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm> {
+multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm,
+ SDPatternOperator op> {
def NAME : sve_int_pred_pattern_b<opc, asm, GPR32z, GPR32z>;
def : InstAlias<asm # "\t$Rdn, $pattern",
(!cast<Instruction>(NAME) GPR32z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
def : InstAlias<asm # "\t$Rdn",
(!cast<Instruction>(NAME) GPR32z:$Rdn, 0b11111, 1), 2>;
+
+ def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
+ (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
}
-multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm> {
+multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm,
+ SDPatternOperator op> {
def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64z>;
def : InstAlias<asm # "\t$Rdn, $pattern",
(!cast<Instruction>(NAME) GPR64z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
def : InstAlias<asm # "\t$Rdn",
(!cast<Instruction>(NAME) GPR64z:$Rdn, 0b11111, 1), 2>;
+
+ def : Pat<(i64 (op GPR64:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
+ (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
}
OpenPOWER on IntegriCloud