diff mbox series

[v2,ARM,13x] : MVE ACLE scalar shift intrinsics.

Message ID AM0PR08MB5380451B1FC3C9D917C1465C9BF00@AM0PR08MB5380.eurprd08.prod.outlook.com
State New
Headers show
Series [v2,ARM,13x] : MVE ACLE scalar shift intrinsics. | expand

Commit Message

Srinath Parvathaneni March 23, 2020, 5:43 p.m. UTC
Hello Kyrill,

Following patch is the rebased version of v1.
(version v1) https://gcc.gnu.org/pipermail/gcc-patches/2019-November/534350.html

####

Hello,

This patch supports following MVE ACLE scalar shift intrinsics.

sqrshr, sqrshrl, sqrshrl_sat48, sqshl, sqshll, srshr, srshrl, uqrshl,
uqrshll, uqrshll_sat48, uqshl, uqshll, urshr, urshrl, lsll, asrl.

Please refer to M-profile Vector Extension (MVE) intrinsics [1]  for more details.
[1] https://developer.arm.com/architectures/instruction-sets/simd-isas/helium/mve-intrinsics

Regression tested on arm-none-eabi and found no regressions.

Ok for trunk?

Thanks,
Srinath.

gcc/ChangeLog:

2019-11-08  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* config/arm/arm-builtins.c (LSLL_QUALIFIERS): Define builtin qualifier.
	(UQSHL_QUALIFIERS): Likewise.
	(ASRL_QUALIFIERS): Likewise.
	(SQSHL_QUALIFIERS): Likewise.
	* config/arm/arm_mve.h (__ARM_BIG_ENDIAN): Check to not support MVE in
	Big-Endian Mode.
	(sqrshr): Define macro.
	(sqrshrl): Likewise.
	(sqrshrl_sat48): Likewise.
	(sqshl): Likewise.
	(sqshll): Likewise.
	(srshr): Likewise.
	(srshrl): Likewise.
	(uqrshl): Likewise.
	(uqrshll): Likewise.
	(uqrshll_sat48): Likewise.
	(uqshl): Likewise.
	(uqshll): Likewise.
	(urshr): Likewise.
	(urshrl): Likewise.
	(lsll): Likewise.
	(asrl): Likewise.
	(__arm_lsll): Define intrinsic.
	(__arm_asrl): Likewise.
	(__arm_uqrshll): Likewise.
	(__arm_uqrshll_sat48): Likewise.
	(__arm_sqrshrl): Likewise.
	(__arm_sqrshrl_sat48): Likewise.
	(__arm_uqshll): Likewise.
	(__arm_urshrl): Likewise.
	(__arm_srshrl): Likewise.
	(__arm_sqshll): Likewise.
	(__arm_uqrshl): Likewise.
	(__arm_sqrshr): Likewise.
	(__arm_uqshl): Likewise.
	(__arm_urshr): Likewise.
	(__arm_sqshl): Likewise.
	(__arm_srshr): Likewise.
	* config/arm/arm_mve_builtins.def (LSLL_QUALIFIERS): Use builtin
	qualifier.
        (UQSHL_QUALIFIERS): Likewise.
        (ASRL_QUALIFIERS): Likewise.
        (SQSHL_QUALIFIERS): Likewise.
	* config/arm/mve.md (mve_uqrshll_sat<supf>_di): Define RTL pattern.
	(mve_sqrshrl_sat<supf>_di): Likewise
	(mve_uqrshl_si): Likewise
	(mve_sqrshr_si): Likewise
	(mve_uqshll_di): Likewise
	(mve_urshrl_di): Likewise
	(mve_uqshl_si): Likewise
	(mve_urshr_si): Likewise
	(mve_sqshl_si): Likewise
	(mve_srshr_si): Likewise
	(mve_srshrl_di): Likewise
	(mve_sqshll_di): Likewise

gcc/testsuite/ChangeLog:

2019-11-08  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* gcc.target/arm/mve/intrinsics/asrl.c: New test.
	* gcc.target/arm/mve/intrinsics/lsll.c: Likewise.
	* gcc.target/arm/mve/intrinsics/sqrshr.c: Likewise.
	* gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c: Likewise.
	* gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c: Likewise.
	* gcc.target/arm/mve/intrinsics/sqshl.c: Likewise.
	* gcc.target/arm/mve/intrinsics/sqshll.c: Likewise.
	* gcc.target/arm/mve/intrinsics/srshr.c: Likewise.
	* gcc.target/arm/mve/intrinsics/srshrl.c: Likewise.
	* gcc.target/arm/mve/intrinsics/uqrshl.c: Likewise.
	* gcc.target/arm/mve/intrinsics/uqrshll_sat48.c: Likewise.
	* gcc.target/arm/mve/intrinsics/uqrshll_sat64.c: Likewise.
	* gcc.target/arm/mve/intrinsics/uqshl.c: Likewise.
	* gcc.target/arm/mve/intrinsics/uqshll.c: Likewise.
	* gcc.target/arm/mve/intrinsics/urshr.c: Likewise.
	* gcc.target/arm/mve/intrinsics/urshrl.c: Likewise.
	* lib/target-supports.exp:
        (check_effective_target_arm_v8_1m_mve_fp_ok_nocache): Modify to not
         support MVE floating point in Big Endian mode.
        (check_effective_target_arm_v8_1m_mve_ok_nocache): Modify to not
         support MVE integer in Big Endian mode.


###############     Attachment also inlined for ease of reply    ###############
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 96d8adcd37eb3caf51c71d66af0331f9d1924b92..56f0db21ea95dcd738877daba27f1cb60f0d5a32 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -762,6 +762,26 @@ arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
       qualifier_unsigned, qualifier_unsigned};
 #define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
 
+static enum arm_type_qualifiers
+arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_none};
+#define LSLL_QUALIFIERS (arm_lsll_qualifiers)
+
+static enum arm_type_qualifiers
+arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
+#define UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
+
+static enum arm_type_qualifiers
+arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_none, qualifier_none, qualifier_none};
+#define ASRL_QUALIFIERS (arm_asrl_qualifiers)
+
+static enum arm_type_qualifiers
+arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
+#define SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
+
 /* End of Qualifier for MVE builtins.  */
 
    /* void ([T element type] *, T, immediate).  */
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 43520ee78e19f074912a6d965731465f1226986d..f2d80ee636003ac58f70ddc25db15e129e228906 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -22,6 +22,10 @@
 #ifndef _GCC_ARM_MVE_H
 #define _GCC_ARM_MVE_H
 
+#if __ARM_BIG_ENDIAN
+#error "MVE intrinsics are not supported in Big-Endian mode."
+#endif
+
 #if !__ARM_FEATURE_MVE
 #error "MVE feature not supported"
 #endif
@@ -2526,6 +2530,22 @@ typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
 #define vgetq_lane_u16(__a,  __idx) __arm_vgetq_lane_u16(__a,  __idx)
 #define vgetq_lane_u32(__a,  __idx) __arm_vgetq_lane_u32(__a,  __idx)
 #define vgetq_lane_u64(__a,  __idx) __arm_vgetq_lane_u64(__a,  __idx)
+#define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1)
+#define sqrshrl(__p0, __p1) __arm_sqrshrl(__p0, __p1)
+#define sqrshrl_sat48(__p0, __p1) __arm_sqrshrl_sat48(__p0, __p1)
+#define sqshl(__p0, __p1) __arm_sqshl(__p0, __p1)
+#define sqshll(__p0, __p1) __arm_sqshll(__p0, __p1)
+#define srshr(__p0, __p1) __arm_srshr(__p0, __p1)
+#define srshrl(__p0, __p1) __arm_srshrl(__p0, __p1)
+#define uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1)
+#define uqrshll(__p0, __p1) __arm_uqrshll(__p0, __p1)
+#define uqrshll_sat48(__p0, __p1) __arm_uqrshll_sat48(__p0, __p1)
+#define uqshl(__p0, __p1) __arm_uqshl(__p0, __p1)
+#define uqshll(__p0, __p1) __arm_uqshll(__p0, __p1)
+#define urshr(__p0, __p1) __arm_urshr(__p0, __p1)
+#define urshrl(__p0, __p1) __arm_urshrl(__p0, __p1)
+#define lsll(__p0, __p1) __arm_lsll(__p0, __p1)
+#define asrl(__p0, __p1) __arm_asrl(__p0, __p1)
 #endif
 
 /* For big-endian, GCC's vector indices are reversed within each 64 bits
@@ -16539,6 +16559,118 @@ __arm_vgetq_lane_u64 (uint64x2_t __a, const int __idx)
   return __a[__ARM_LANEQ(__a,__idx)];
 }
 
+__extension__ extern __inline  uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_lsll (uint64_t value, int32_t shift)
+{
+  return (value << shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_asrl (int64_t value, int32_t shift)
+{
+  return (value >> shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshll (uint64_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshll_sat64_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshll_sat48 (uint64_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshll_sat48_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshrl (int64_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshrl_sat64_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshrl_sat48 (int64_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshrl_sat48_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqshll (uint64_t value, const int shift)
+{
+  return __builtin_mve_uqshll_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_urshrl (uint64_t value, const int shift)
+{
+  return __builtin_mve_urshrl_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_srshrl (int64_t value, const int shift)
+{
+  return __builtin_mve_srshrl_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqshll (int64_t value, const int shift)
+{
+  return __builtin_mve_sqshll_di (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshl (uint32_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshl_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshr (int32_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshr_si (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqshl (uint32_t value, const int shift)
+{
+  return  __builtin_mve_uqshl_si (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_urshr (uint32_t value, const int shift)
+{
+  return __builtin_mve_urshr_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqshl (int32_t value, const int shift)
+{
+  return __builtin_mve_sqshl_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_srshr (int32_t value, const int shift)
+{
+  return __builtin_mve_srshr_si (value, shift);
+}
+
 #if (__ARM_FEATURE_MVE & 2) /* MVE Floating point.  */
 
 __extension__ extern __inline void
diff --git a/gcc/config/arm/arm_mve_builtins.def b/gcc/config/arm/arm_mve_builtins.def
index a60650cb7b1fe4e52ab1c7bf3c1215ff083a106f..9379927ae509c1b4fb70e7cbbad40bf645284714 100644
--- a/gcc/config/arm/arm_mve_builtins.def
+++ b/gcc/config/arm/arm_mve_builtins.def
@@ -876,3 +876,17 @@ VAR1 (QUADOP_UNONE_UNONE_UNONE_UNONE_UNONE, vsbcq_m_u, v4si)
 VAR5 (STORE1, vst2q, v16qi, v8hi, v4si, v8hf, v4sf)
 VAR5 (LOAD1, vld4q, v16qi, v8hi, v4si, v8hf, v4sf)
 VAR5 (LOAD1, vld2q, v16qi, v8hi, v4si, v8hf, v4sf)
+VAR1 (ASRL, sqrshr_,si)
+VAR1 (ASRL, sqrshrl_sat64_,di)
+VAR1 (ASRL, sqrshrl_sat48_,di)
+VAR1 (LSLL, uqrshl_, si)
+VAR1 (LSLL, uqrshll_sat64_, di)
+VAR1 (LSLL, uqrshll_sat48_, di)
+VAR1 (SQSHL,srshr_,si)
+VAR1 (SQSHL,srshrl_,di)
+VAR1 (SQSHL,sqshl_,si)
+VAR1 (SQSHL,sqshll_,di)
+VAR1 (UQSHL, urshr_, si)
+VAR1 (UQSHL, urshrl_, di)
+VAR1 (UQSHL, uqshl_, si)
+VAR1 (UQSHL, uqshll_, di)
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 2b59d5a58171cddea1155610ddbb3c7f96105d24..ce98e35763107844a70377fbc3e9921bf055b0cb 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -214,7 +214,9 @@
 			 VLDRDQGBWB_S VLDRDQGBWB_U VADCQ_U VADCQ_M_U VADCQ_S
 			 VADCQ_M_S VSBCIQ_U VSBCIQ_S VSBCIQ_M_U VSBCIQ_M_S
 			 VSBCQ_U VSBCQ_S VSBCQ_M_U VSBCQ_M_S VADCIQ_U VADCIQ_M_U
-			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q])
+			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q SRSHRL SRSHR
+			 URSHR URSHRL SQRSHR UQRSHL UQRSHLL_64
+			 UQRSHLL_48 SQRSHRL_64 SQRSHRL_48])
 
 (define_mode_attr MVE_CNVT [(V8HI "V8HF") (V4SI "V4SF") (V8HF "V8HI")
 			    (V4SF "V4SI")])
@@ -391,7 +393,8 @@
 		       (VSBCIQ_M_U "u") (VSBCIQ_S "s") (VSBCIQ_M_S "s")
 		       (VADCQ_U "u")  (VADCQ_M_U "u") (VADCQ_S "s")
 		       (VADCIQ_U "u") (VADCIQ_M_U "u") (VADCIQ_S "s")
-		       (VADCIQ_M_S "s")])
+		       (VADCIQ_M_S "s") (SQRSHRL_64 "64") (SQRSHRL_48 "48")
+		       (UQRSHLL_64 "64") (UQRSHLL_48 "48")])
 
 (define_int_attr mode1 [(VCTP8Q "8") (VCTP16Q "16") (VCTP32Q "32")
 			(VCTP64Q "64") (VCTP8Q_M "8") (VCTP16Q_M "16")
@@ -654,7 +657,8 @@
 (define_int_iterator VSBCIQ_M [VSBCIQ_M_U VSBCIQ_M_S])
 (define_int_iterator VADCQ [VADCQ_U VADCQ_S])
 (define_int_iterator VADCQ_M [VADCQ_M_U VADCQ_M_S])
-
+(define_int_iterator UQRSHLLQ [UQRSHLL_64 UQRSHLL_48])
+(define_int_iterator SQRSHRLQ [SQRSHRL_64 SQRSHRL_48])
 
 (define_insn "*mve_mov<mode>"
   [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w,w,r,w,Us")
@@ -11005,3 +11009,143 @@
    return "vmov\t%f0, %J1, %K1";
 }
  [(set_attr "type" "mve_move")])
+
+;;
+;; [uqrshll_di]
+;;
+(define_insn "mve_uqrshll_sat<supf>_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 UQRSHLLQ))]
+  "TARGET_HAVE_MVE"
+  "uqrshll%?\\t%Q1, %R1, #<supf>, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqrshrl_di]
+;;
+(define_insn "mve_sqrshrl_sat<supf>_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 SQRSHRLQ))]
+  "TARGET_HAVE_MVE"
+  "sqrshrl%?\\t%Q1, %R1, #<supf>, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqrshl_si]
+;;
+(define_insn "mve_uqrshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 UQRSHL))]
+  "TARGET_HAVE_MVE"
+  "uqrshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqrshr_si]
+;;
+(define_insn "mve_sqrshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 SQRSHR))]
+  "TARGET_HAVE_MVE"
+  "sqrshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqshll_di]
+;;
+(define_insn "mve_uqshll_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(us_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "uqshll%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [urshrl_di]
+;;
+(define_insn "mve_urshrl_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 URSHRL))]
+  "TARGET_HAVE_MVE"
+  "urshrl%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqshl_si]
+;;
+(define_insn "mve_uqshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(us_ashift:SI (match_operand:SI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "uqshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [urshr_si]
+;;
+(define_insn "mve_urshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 URSHR))]
+  "TARGET_HAVE_MVE"
+  "urshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqshl_si]
+;;
+(define_insn "mve_sqshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "sqshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [srshr_si]
+;;
+(define_insn "mve_srshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 SRSHR))]
+  "TARGET_HAVE_MVE"
+  "srshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [srshrl_di]
+;;
+(define_insn "mve_srshrl_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 SRSHRL))]
+  "TARGET_HAVE_MVE"
+  "srshrl%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqshll_di]
+;;
+(define_insn "mve_sqshll_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(ss_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "sqshll%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..a2d5160e518b482f80eb26fae61f1d4b63e5e63f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+asrl_reg (int64_t longval3, int32_t x)
+{
+  return asrl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "asrl\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c1b62fb9f27a0c90a9bea43ea0bc0234e7b2721
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+lsll_reg (uint64_t longval3, int32_t x)
+{
+  return lsll (longval3, x);
+}
+
+/* { dg-final { scan-assembler "lsll\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f0a228e4b49595939d4cbff6cf18d6d7c53b52e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+sqrshr_reg (int32_t longval3, int32_t x)
+{
+  return sqrshr (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshr\\tr\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f1612cde77ba62a48a83a3f5ef6ba35e5034b1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqrshrl_reg (int64_t longval3, int32_t x)
+{
+  return sqrshrl_sat48 (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #48, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d0a4bd155ac65b0724cf67fe916105e4db39b5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqrshrl_reg (int64_t longval3, int32_t x)
+{
+  return sqrshrl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #64, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..8cb8c74b2686ef3c0e68fa949fa96944b8b1d799
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+sqshl_imm (int32_t longval3)
+{
+  return sqshl (longval3, 25);
+}
+
+/* { dg-final { scan-assembler "sqshl\\tr\[0-9\]+, #25" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
new file mode 100644
index 0000000000000000000000000000000000000000..016ef2a336ed9e5d2539f927435932ab14687f3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqshll_imm(int64_t value)
+{
+  return sqshll (value, 21);
+}
+
+/* { dg-final { scan-assembler "sqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..264f0bf09ce1684966ade2fdba62b70261e8f438
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+srshr_imm (int32_t longval3)
+{
+  return srshr (longval3, 25);
+}
+
+/* { dg-final { scan-assembler "srshr\\tr\[0-9\]+, #25" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab12d0da63596c7c4fb3bcb5bfc8f20fc5b0de31
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+srshrl_imm(int64_t value)
+{
+  return srshrl (value, 21);
+}
+
+/* { dg-final { scan-assembler "srshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..0064aa19fbc55a5b759f3aa8df2d9329eeee868d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint32_t
+uqrshl_reg (uint32_t longval3, int32_t x)
+{
+  return uqrshl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshl\\tr\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
new file mode 100644
index 0000000000000000000000000000000000000000..24cd232441306721e067fd441e803a5352477921
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqrshll_reg (uint64_t longval3, int32_t x)
+{
+  return uqrshll_sat48 (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #48, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
new file mode 100644
index 0000000000000000000000000000000000000000..22aaafdb919747721a408a8d6d2f18b770184f79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqrshll_reg (uint64_t longval3, int32_t x)
+{
+  return uqrshll (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #64, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e6ff649805acfca497bbcbe78f7538a2df0da30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint32_t
+uqshl_imm (uint32_t longval3)
+{
+  return uqshl (longval3, 21);
+}
+
+/* { dg-final { scan-assembler "uqshl\\tr\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
new file mode 100644
index 0000000000000000000000000000000000000000..52560721d6ff405c2bec64fdf833601c877d41be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqshll_imm(uint64_t value)
+{
+  return uqshll (value, 21);
+}
+
+/* { dg-final { scan-assembler "uqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..ec5d84bb0099de9f6b28bbb3bd6765c731d24ae8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+urshr_imm (uint32_t longval3)
+{
+  return urshr (longval3, 21);
+}
+
+/* { dg-final { scan-assembler "urshr\\tr\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..ea29412ab7a6438bab7ca84a98810f99b95dbecf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+urshrl_imm(uint64_t value)
+{
+  return urshrl (value, 21);
+}
+
+/* { dg-final { scan-assembler "urshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 58919a31a009f8202d746a654093d32de1bdf987..53524e11d52763a9db7459db50cf410ad6ff63ca 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4712,6 +4712,9 @@ proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } {
 	    #if !(__ARM_FEATURE_MVE & 2)
 	    #error "__ARM_FEATURE_MVE for floating point not defined"
 	    #endif
+	    #if __ARM_BIG_ENDIAN
+	    #error "MVE intrinsics are not supported in Big-Endian mode."
+	    #endif
 	} "$flags -mthumb"] } {
 	    set et_arm_v8_1m_mve_fp_flags "$flags -mthumb"
 	    return 1
@@ -4891,6 +4894,9 @@ proc check_effective_target_arm_v8_1m_mve_ok_nocache { } {
             #if !defined (__ARM_FEATURE_MVE)
             #error "__ARM_FEATURE_MVE not defined"
             #endif
+	    #if __ARM_BIG_ENDIAN
+	    #error "MVE intrinsics are not supported in Big-Endian mode."
+	    #endif
         } "$flags -mthumb"] } {
             set et_arm_v8_1m_mve_flags "$flags -mthumb"
             return 1

Comments

Kyrylo Tkachov March 23, 2020, 6:22 p.m. UTC | #1
Hi Srinath,

> -----Original Message-----
> From: Srinath Parvathaneni <Srinath.Parvathaneni@arm.com>
> Sent: 23 March 2020 17:44
> To: gcc-patches@gcc.gnu.org
> Cc: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>
> Subject: [PATCH v2][ARM][GCC][13x]: MVE ACLE scalar shift intrinsics.
> 
> Hello Kyrill,
> 
> Following patch is the rebased version of v1.
> (version v1) https://gcc.gnu.org/pipermail/gcc-patches/2019-
> November/534350.html
> 
> ####
> 
> Hello,
> 
> This patch supports following MVE ACLE scalar shift intrinsics.
> 
> sqrshr, sqrshrl, sqrshrl_sat48, sqshl, sqshll, srshr, srshrl, uqrshl, uqrshll,
> uqrshll_sat48, uqshl, uqshll, urshr, urshrl, lsll, asrl.
> 
> Please refer to M-profile Vector Extension (MVE) intrinsics [1]  for more
> details.
> [1] https://developer.arm.com/architectures/instruction-sets/simd-
> isas/helium/mve-intrinsics
> 
> Regression tested on arm-none-eabi and found no regressions.
> 
> Ok for trunk?

Thanks, I've pushed this patch to master.
Kyrill

> 
> Thanks,
> Srinath.
> 
> gcc/ChangeLog:
> 
> 2019-11-08  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>
> 
> 	* config/arm/arm-builtins.c (LSLL_QUALIFIERS): Define builtin
> qualifier.
> 	(UQSHL_QUALIFIERS): Likewise.
> 	(ASRL_QUALIFIERS): Likewise.
> 	(SQSHL_QUALIFIERS): Likewise.
> 	* config/arm/arm_mve.h (__ARM_BIG_ENDIAN): Check to not
> support MVE in
> 	Big-Endian Mode.
> 	(sqrshr): Define macro.
> 	(sqrshrl): Likewise.
> 	(sqrshrl_sat48): Likewise.
> 	(sqshl): Likewise.
> 	(sqshll): Likewise.
> 	(srshr): Likewise.
> 	(srshrl): Likewise.
> 	(uqrshl): Likewise.
> 	(uqrshll): Likewise.
> 	(uqrshll_sat48): Likewise.
> 	(uqshl): Likewise.
> 	(uqshll): Likewise.
> 	(urshr): Likewise.
> 	(urshrl): Likewise.
> 	(lsll): Likewise.
> 	(asrl): Likewise.
> 	(__arm_lsll): Define intrinsic.
> 	(__arm_asrl): Likewise.
> 	(__arm_uqrshll): Likewise.
> 	(__arm_uqrshll_sat48): Likewise.
> 	(__arm_sqrshrl): Likewise.
> 	(__arm_sqrshrl_sat48): Likewise.
> 	(__arm_uqshll): Likewise.
> 	(__arm_urshrl): Likewise.
> 	(__arm_srshrl): Likewise.
> 	(__arm_sqshll): Likewise.
> 	(__arm_uqrshl): Likewise.
> 	(__arm_sqrshr): Likewise.
> 	(__arm_uqshl): Likewise.
> 	(__arm_urshr): Likewise.
> 	(__arm_sqshl): Likewise.
> 	(__arm_srshr): Likewise.
> 	* config/arm/arm_mve_builtins.def (LSLL_QUALIFIERS): Use builtin
> 	qualifier.
>         (UQSHL_QUALIFIERS): Likewise.
>         (ASRL_QUALIFIERS): Likewise.
>         (SQSHL_QUALIFIERS): Likewise.
> 	* config/arm/mve.md (mve_uqrshll_sat<supf>_di): Define RTL
> pattern.
> 	(mve_sqrshrl_sat<supf>_di): Likewise
> 	(mve_uqrshl_si): Likewise
> 	(mve_sqrshr_si): Likewise
> 	(mve_uqshll_di): Likewise
> 	(mve_urshrl_di): Likewise
> 	(mve_uqshl_si): Likewise
> 	(mve_urshr_si): Likewise
> 	(mve_sqshl_si): Likewise
> 	(mve_srshr_si): Likewise
> 	(mve_srshrl_di): Likewise
> 	(mve_sqshll_di): Likewise
> 
> gcc/testsuite/ChangeLog:
> 
> 2019-11-08  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>
> 
> 	* gcc.target/arm/mve/intrinsics/asrl.c: New test.
> 	* gcc.target/arm/mve/intrinsics/lsll.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/sqrshr.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/sqshl.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/sqshll.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/srshr.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/srshrl.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/uqrshl.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/uqrshll_sat48.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/uqrshll_sat64.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/uqshl.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/uqshll.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/urshr.c: Likewise.
> 	* gcc.target/arm/mve/intrinsics/urshrl.c: Likewise.
> 	* lib/target-supports.exp:
>         (check_effective_target_arm_v8_1m_mve_fp_ok_nocache): Modify to
> not
>          support MVE floating point in Big Endian mode.
>         (check_effective_target_arm_v8_1m_mve_ok_nocache): Modify to not
>          support MVE integer in Big Endian mode.
> 
> 
> ###############     Attachment also inlined for ease of reply
> ###############
> 
> 
> diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
> index
> 96d8adcd37eb3caf51c71d66af0331f9d1924b92..56f0db21ea95dcd738877dab
> a27f1cb60f0d5a32 100644
> --- a/gcc/config/arm/arm-builtins.c
> +++ b/gcc/config/arm/arm-builtins.c
> @@ -762,6 +762,26 @@
> arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
>        qualifier_unsigned, qualifier_unsigned};  #define
> STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
> 
> +static enum arm_type_qualifiers
> +arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS]
> +  = { qualifier_unsigned, qualifier_unsigned, qualifier_none}; #define
> +LSLL_QUALIFIERS (arm_lsll_qualifiers)
> +
> +static enum arm_type_qualifiers
> +arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
> +  = { qualifier_unsigned, qualifier_unsigned, qualifier_const}; #define
> +UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
> +
> +static enum arm_type_qualifiers
> +arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
> +  = { qualifier_none, qualifier_none, qualifier_none}; #define
> +ASRL_QUALIFIERS (arm_asrl_qualifiers)
> +
> +static enum arm_type_qualifiers
> +arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
> +  = { qualifier_unsigned, qualifier_unsigned, qualifier_const}; #define
> +SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
> +
>  /* End of Qualifier for MVE builtins.  */
> 
>     /* void ([T element type] *, T, immediate).  */ diff --git
> a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index
> 43520ee78e19f074912a6d965731465f1226986d..f2d80ee636003ac58f70ddc2
> 5db15e129e228906 100644
> --- a/gcc/config/arm/arm_mve.h
> +++ b/gcc/config/arm/arm_mve.h
> @@ -22,6 +22,10 @@
>  #ifndef _GCC_ARM_MVE_H
>  #define _GCC_ARM_MVE_H
> 
> +#if __ARM_BIG_ENDIAN
> +#error "MVE intrinsics are not supported in Big-Endian mode."
> +#endif
> +
>  #if !__ARM_FEATURE_MVE
>  #error "MVE feature not supported"
>  #endif
> @@ -2526,6 +2530,22 @@ typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
> #define vgetq_lane_u16(__a,  __idx) __arm_vgetq_lane_u16(__a,  __idx)
> #define vgetq_lane_u32(__a,  __idx) __arm_vgetq_lane_u32(__a,  __idx)
> #define vgetq_lane_u64(__a,  __idx) __arm_vgetq_lane_u64(__a,  __idx)
> +#define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1) #define
> +sqrshrl(__p0, __p1) __arm_sqrshrl(__p0, __p1) #define
> +sqrshrl_sat48(__p0, __p1) __arm_sqrshrl_sat48(__p0, __p1) #define
> +sqshl(__p0, __p1) __arm_sqshl(__p0, __p1) #define sqshll(__p0, __p1)
> +__arm_sqshll(__p0, __p1) #define srshr(__p0, __p1) __arm_srshr(__p0,
> +__p1) #define srshrl(__p0, __p1) __arm_srshrl(__p0, __p1) #define
> +uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1) #define uqrshll(__p0, __p1)
> +__arm_uqrshll(__p0, __p1) #define uqrshll_sat48(__p0, __p1)
> +__arm_uqrshll_sat48(__p0, __p1) #define uqshl(__p0, __p1)
> +__arm_uqshl(__p0, __p1) #define uqshll(__p0, __p1) __arm_uqshll(__p0,
> +__p1) #define urshr(__p0, __p1) __arm_urshr(__p0, __p1) #define
> +urshrl(__p0, __p1) __arm_urshrl(__p0, __p1) #define lsll(__p0, __p1)
> +__arm_lsll(__p0, __p1) #define asrl(__p0, __p1) __arm_asrl(__p0, __p1)
>  #endif
> 
>  /* For big-endian, GCC's vector indices are reversed within each 64 bits @@
> -16539,6 +16559,118 @@ __arm_vgetq_lane_u64 (uint64x2_t __a, const int
> __idx)
>    return __a[__ARM_LANEQ(__a,__idx)];
>  }
> 
> +__extension__ extern __inline  uint64_t __attribute__
> +((__always_inline__, __gnu_inline__, __artificial__)) __arm_lsll
> +(uint64_t value, int32_t shift) {
> +  return (value << shift);
> +}
> +
> +__extension__ extern __inline int64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_asrl (int64_t value, int32_t shift) {
> +  return (value >> shift);
> +}
> +
> +__extension__ extern __inline uint64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_uqrshll (uint64_t value, int32_t shift) {
> +  return __builtin_mve_uqrshll_sat64_di (value, shift); }
> +
> +__extension__ extern __inline uint64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_uqrshll_sat48 (uint64_t value, int32_t shift) {
> +  return __builtin_mve_uqrshll_sat48_di (value, shift); }
> +
> +__extension__ extern __inline int64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_sqrshrl (int64_t value, int32_t shift) {
> +  return __builtin_mve_sqrshrl_sat64_di (value, shift); }
> +
> +__extension__ extern __inline int64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_sqrshrl_sat48 (int64_t value, int32_t shift) {
> +  return __builtin_mve_sqrshrl_sat48_di (value, shift); }
> +
> +__extension__ extern __inline uint64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_uqshll (uint64_t value, const int shift) {
> +  return __builtin_mve_uqshll_di (value, shift); }
> +
> +__extension__ extern __inline uint64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_urshrl (uint64_t value, const int shift) {
> +  return __builtin_mve_urshrl_di (value, shift); }
> +
> +__extension__ extern __inline int64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_srshrl (int64_t value, const int shift) {
> +  return __builtin_mve_srshrl_di (value, shift); }
> +
> +__extension__ extern __inline int64_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_sqshll (int64_t value, const int shift) {
> +  return __builtin_mve_sqshll_di (value, shift); }
> +
> +__extension__ extern __inline uint32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_uqrshl (uint32_t value, int32_t shift) {
> +  return __builtin_mve_uqrshl_si (value, shift); }
> +
> +__extension__ extern __inline int32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_sqrshr (int32_t value, int32_t shift) {
> +  return __builtin_mve_sqrshr_si (value, shift); }
> +
> +__extension__ extern __inline uint32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_uqshl (uint32_t value, const int shift) {
> +  return  __builtin_mve_uqshl_si (value, shift); }
> +
> +__extension__ extern __inline uint32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_urshr (uint32_t value, const int shift) {
> +  return __builtin_mve_urshr_si (value, shift); }
> +
> +__extension__ extern __inline int32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_sqshl (int32_t value, const int shift) {
> +  return __builtin_mve_sqshl_si (value, shift); }
> +
> +__extension__ extern __inline int32_t
> +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> +__arm_srshr (int32_t value, const int shift) {
> +  return __builtin_mve_srshr_si (value, shift); }
> +
>  #if (__ARM_FEATURE_MVE & 2) /* MVE Floating point.  */
> 
>  __extension__ extern __inline void
> diff --git a/gcc/config/arm/arm_mve_builtins.def
> b/gcc/config/arm/arm_mve_builtins.def
> index
> a60650cb7b1fe4e52ab1c7bf3c1215ff083a106f..9379927ae509c1b4fb70e7cbb
> ad40bf645284714 100644
> --- a/gcc/config/arm/arm_mve_builtins.def
> +++ b/gcc/config/arm/arm_mve_builtins.def
> @@ -876,3 +876,17 @@ VAR1
> (QUADOP_UNONE_UNONE_UNONE_UNONE_UNONE, vsbcq_m_u, v4si)
>  VAR5 (STORE1, vst2q, v16qi, v8hi, v4si, v8hf, v4sf)
>  VAR5 (LOAD1, vld4q, v16qi, v8hi, v4si, v8hf, v4sf)
>  VAR5 (LOAD1, vld2q, v16qi, v8hi, v4si, v8hf, v4sf)
> +VAR1 (ASRL, sqrshr_,si)
> +VAR1 (ASRL, sqrshrl_sat64_,di)
> +VAR1 (ASRL, sqrshrl_sat48_,di)
> +VAR1 (LSLL, uqrshl_, si)
> +VAR1 (LSLL, uqrshll_sat64_, di)
> +VAR1 (LSLL, uqrshll_sat48_, di)
> +VAR1 (SQSHL,srshr_,si)
> +VAR1 (SQSHL,srshrl_,di)
> +VAR1 (SQSHL,sqshl_,si)
> +VAR1 (SQSHL,sqshll_,di)
> +VAR1 (UQSHL, urshr_, si)
> +VAR1 (UQSHL, urshrl_, di)
> +VAR1 (UQSHL, uqshl_, si)
> +VAR1 (UQSHL, uqshll_, di)
> diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index
> 2b59d5a58171cddea1155610ddbb3c7f96105d24..ce98e35763107844a70377f
> bc3e9921bf055b0cb 100644
> --- a/gcc/config/arm/mve.md
> +++ b/gcc/config/arm/mve.md
> @@ -214,7 +214,9 @@
>  			 VLDRDQGBWB_S VLDRDQGBWB_U VADCQ_U
> VADCQ_M_U VADCQ_S
>  			 VADCQ_M_S VSBCIQ_U VSBCIQ_S VSBCIQ_M_U
> VSBCIQ_M_S
>  			 VSBCQ_U VSBCQ_S VSBCQ_M_U VSBCQ_M_S
> VADCIQ_U VADCIQ_M_U
> -			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q])
> +			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q
> SRSHRL SRSHR
> +			 URSHR URSHRL SQRSHR UQRSHL UQRSHLL_64
> +			 UQRSHLL_48 SQRSHRL_64 SQRSHRL_48])
> 
>  (define_mode_attr MVE_CNVT [(V8HI "V8HF") (V4SI "V4SF") (V8HF "V8HI")
>  			    (V4SF "V4SI")])
> @@ -391,7 +393,8 @@
>  		       (VSBCIQ_M_U "u") (VSBCIQ_S "s") (VSBCIQ_M_S "s")
>  		       (VADCQ_U "u")  (VADCQ_M_U "u") (VADCQ_S "s")
>  		       (VADCIQ_U "u") (VADCIQ_M_U "u") (VADCIQ_S "s")
> -		       (VADCIQ_M_S "s")])
> +		       (VADCIQ_M_S "s") (SQRSHRL_64 "64") (SQRSHRL_48 "48")
> +		       (UQRSHLL_64 "64") (UQRSHLL_48 "48")])
> 
>  (define_int_attr mode1 [(VCTP8Q "8") (VCTP16Q "16") (VCTP32Q "32")
>  			(VCTP64Q "64") (VCTP8Q_M "8") (VCTP16Q_M "16")
> @@ -654,7 +657,8 @@  (define_int_iterator VSBCIQ_M [VSBCIQ_M_U
> VSBCIQ_M_S])  (define_int_iterator VADCQ [VADCQ_U VADCQ_S])
> (define_int_iterator VADCQ_M [VADCQ_M_U VADCQ_M_S])
> -
> +(define_int_iterator UQRSHLLQ [UQRSHLL_64 UQRSHLL_48])
> +(define_int_iterator SQRSHRLQ [SQRSHRL_64 SQRSHRL_48])
> 
>  (define_insn "*mve_mov<mode>"
>    [(set (match_operand:MVE_types 0 "nonimmediate_operand"
> "=w,w,r,w,w,r,w,Us") @@ -11005,3 +11009,143 @@
>     return "vmov\t%f0, %J1, %K1";
>  }
>   [(set_attr "type" "mve_move")])
> +
> +;;
> +;; [uqrshll_di]
> +;;
> +(define_insn "mve_uqrshll_sat<supf>_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "s_register_operand" "r")]
> +	 UQRSHLLQ))]
> +  "TARGET_HAVE_MVE"
> +  "uqrshll%?\\t%Q1, %R1, #<supf>, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [sqrshrl_di]
> +;;
> +(define_insn "mve_sqrshrl_sat<supf>_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "s_register_operand" "r")]
> +	 SQRSHRLQ))]
> +  "TARGET_HAVE_MVE"
> +  "sqrshrl%?\\t%Q1, %R1, #<supf>, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [uqrshl_si]
> +;;
> +(define_insn "mve_uqrshl_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "s_register_operand" "r")]
> +	 UQRSHL))]
> +  "TARGET_HAVE_MVE"
> +  "uqrshl%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [sqrshr_si]
> +;;
> +(define_insn "mve_sqrshr_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "s_register_operand" "r")]
> +	 SQRSHR))]
> +  "TARGET_HAVE_MVE"
> +  "sqrshr%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [uqshll_di]
> +;;
> +(define_insn "mve_uqshll_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(us_ashift:DI (match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		      (match_operand:SI 2 "arm_reg_or_long_shift_imm"
> "rPg")))]
> +  "TARGET_HAVE_MVE"
> +  "uqshll%?\\t%Q1, %R1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [urshrl_di]
> +;;
> +(define_insn "mve_urshrl_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
> +	 URSHRL))]
> +  "TARGET_HAVE_MVE"
> +  "urshrl%?\\t%Q1, %R1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [uqshl_si]
> +;;
> +(define_insn "mve_uqshl_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(us_ashift:SI (match_operand:SI 1 "arm_general_register_operand"
> "r")
> +		      (match_operand:SI 2 "arm_reg_or_long_shift_imm"
> "rPg")))]
> +  "TARGET_HAVE_MVE"
> +  "uqshl%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [urshr_si]
> +;;
> +(define_insn "mve_urshr_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
> +	 URSHR))]
> +  "TARGET_HAVE_MVE"
> +  "urshr%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [sqshl_si]
> +;;
> +(define_insn "mve_sqshl_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		      (match_operand:SI 2 "arm_reg_or_long_shift_imm"
> "rPg")))]
> +  "TARGET_HAVE_MVE"
> +  "sqshl%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [srshr_si]
> +;;
> +(define_insn "mve_srshr_si"
> +  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
> +	(unspec:SI [(match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
> +	 SRSHR))]
> +  "TARGET_HAVE_MVE"
> +  "srshr%?\\t%1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [srshrl_di]
> +;;
> +(define_insn "mve_srshrl_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
> +	 SRSHRL))]
> +  "TARGET_HAVE_MVE"
> +  "srshrl%?\\t%Q1, %R1, %2"
> +  [(set_attr "predicable" "yes")])
> +
> +;;
> +;; [sqshll_di]
> +;;
> +(define_insn "mve_sqshll_di"
> +  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> +	(ss_ashift:DI (match_operand:DI 1 "arm_general_register_operand"
> "r")
> +		      (match_operand:SI 2 "arm_reg_or_long_shift_imm"
> "rPg")))]
> +  "TARGET_HAVE_MVE"
> +  "sqshll%?\\t%Q1, %R1, %2"
> +  [(set_attr "predicable" "yes")])
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..a2d5160e518b482f80eb26f
> ae61f1d4b63e5e63f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int64_t
> +asrl_reg (int64_t longval3, int32_t x)
> +{
> +  return asrl (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "asrl\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+"
> +} } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..9c1b62fb9f27a0c90a9bea4
> 3ea0bc0234e7b2721
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +lsll_reg (uint64_t longval3, int32_t x) {
> +  return lsll (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "lsll\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+"
> +} } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..1f0a228e4b49595939d4cbff
> 6cf18d6d7c53b52e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int32_t
> +sqrshr_reg (int32_t longval3, int32_t x) {
> +  return sqrshr (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "sqrshr\\tr\[0-9\]+, r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..2f1612cde77ba62a48a83a3
> f5ef6ba35e5034b1b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int64_t
> +sqrshrl_reg (int64_t longval3, int32_t x) {
> +  return sqrshrl_sat48 (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #48,
> +r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..5d0a4bd155ac65b0724cf67
> fe916105e4db39b5c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int64_t
> +sqrshrl_reg (int64_t longval3, int32_t x) {
> +  return sqrshrl (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #64,
> +r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..8cb8c74b2686ef3c0e68fa94
> 9fa96944b8b1d799
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int32_t
> +sqshl_imm (int32_t longval3)
> +{
> +  return sqshl (longval3, 25);
> +}
> +
> +/* { dg-final { scan-assembler "sqshl\\tr\[0-9\]+, #25" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..016ef2a336ed9e5d2539f92
> 7435932ab14687f3a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int64_t
> +sqshll_imm(int64_t value)
> +{
> +  return sqshll (value, 21);
> +}
> +
> +/* { dg-final { scan-assembler "sqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } }
> +*/
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..264f0bf09ce1684966ade2fd
> ba62b70261e8f438
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int32_t
> +srshr_imm (int32_t longval3)
> +{
> +  return srshr (longval3, 25);
> +}
> +
> +/* { dg-final { scan-assembler "srshr\\tr\[0-9\]+, #25" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ab12d0da63596c7c4fb3bcb
> 5bfc8f20fc5b0de31
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +int64_t
> +srshrl_imm(int64_t value)
> +{
> +  return srshrl (value, 21);
> +}
> +
> +/* { dg-final { scan-assembler "srshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } }
> +*/
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..0064aa19fbc55a5b759f3aa
> 8df2d9329eeee868d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint32_t
> +uqrshl_reg (uint32_t longval3, int32_t x) {
> +  return uqrshl (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "uqrshl\\tr\[0-9\]+, r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..24cd232441306721e067fd4
> 41e803a5352477921
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +uqrshll_reg (uint64_t longval3, int32_t x) {
> +  return uqrshll_sat48 (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #48,
> +r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..22aaafdb919747721a408a8
> d6d2f18b770184f79
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +uqrshll_reg (uint64_t longval3, int32_t x) {
> +  return uqrshll (longval3, x);
> +}
> +
> +/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #64,
> +r\[0-9\]+" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..9e6ff649805acfca497bbcbe
> 78f7538a2df0da30
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint32_t
> +uqshl_imm (uint32_t longval3)
> +{
> +  return uqshl (longval3, 21);
> +}
> +
> +/* { dg-final { scan-assembler "uqshl\\tr\[0-9\]+, #21" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..52560721d6ff405c2bec64fd
> f833601c877d41be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +uqshll_imm(uint64_t value)
> +{
> +  return uqshll (value, 21);
> +}
> +
> +/* { dg-final { scan-assembler "uqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } }
> +*/
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ec5d84bb0099de9f6b28bb
> b3bd6765c731d24ae8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +urshr_imm (uint32_t longval3)
> +{
> +  return urshr (longval3, 21);
> +}
> +
> +/* { dg-final { scan-assembler "urshr\\tr\[0-9\]+, #21" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
> b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ea29412ab7a6438bab7ca8
> 4a98810f99b95dbecf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
> @@ -0,0 +1,13 @@
> +/* { dg-require-effective-target arm_v8_1m_mve_ok } */
> +/* { dg-add-options arm_v8_1m_mve } */
> +/* { dg-additional-options "-O2" } */
> +
> +#include "arm_mve.h"
> +
> +uint64_t
> +urshrl_imm(uint64_t value)
> +{
> +  return urshrl (value, 21);
> +}
> +
> +/* { dg-final { scan-assembler "urshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } }
> +*/
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-
> supports.exp
> index
> 58919a31a009f8202d746a654093d32de1bdf987..53524e11d52763a9db7459
> db50cf410ad6ff63ca 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -4712,6 +4712,9 @@ proc
> check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } {
>  	    #if !(__ARM_FEATURE_MVE & 2)
>  	    #error "__ARM_FEATURE_MVE for floating point not defined"
>  	    #endif
> +	    #if __ARM_BIG_ENDIAN
> +	    #error "MVE intrinsics are not supported in Big-Endian mode."
> +	    #endif
>  	} "$flags -mthumb"] } {
>  	    set et_arm_v8_1m_mve_fp_flags "$flags -mthumb"
>  	    return 1
> @@ -4891,6 +4894,9 @@ proc
> check_effective_target_arm_v8_1m_mve_ok_nocache { } {
>              #if !defined (__ARM_FEATURE_MVE)
>              #error "__ARM_FEATURE_MVE not defined"
>              #endif
> +	    #if __ARM_BIG_ENDIAN
> +	    #error "MVE intrinsics are not supported in Big-Endian mode."
> +	    #endif
>          } "$flags -mthumb"] } {
>              set et_arm_v8_1m_mve_flags "$flags -mthumb"
>              return 1
diff mbox series

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 96d8adcd37eb3caf51c71d66af0331f9d1924b92..56f0db21ea95dcd738877daba27f1cb60f0d5a32 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -762,6 +762,26 @@  arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
       qualifier_unsigned, qualifier_unsigned};
 #define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
 
+static enum arm_type_qualifiers
+arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_none};
+#define LSLL_QUALIFIERS (arm_lsll_qualifiers)
+
+static enum arm_type_qualifiers
+arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
+#define UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
+
+static enum arm_type_qualifiers
+arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_none, qualifier_none, qualifier_none};
+#define ASRL_QUALIFIERS (arm_asrl_qualifiers)
+
+static enum arm_type_qualifiers
+arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
+#define SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
+
 /* End of Qualifier for MVE builtins.  */
 
    /* void ([T element type] *, T, immediate).  */
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 43520ee78e19f074912a6d965731465f1226986d..f2d80ee636003ac58f70ddc25db15e129e228906 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -22,6 +22,10 @@ 
 #ifndef _GCC_ARM_MVE_H
 #define _GCC_ARM_MVE_H
 
+#if __ARM_BIG_ENDIAN
+#error "MVE intrinsics are not supported in Big-Endian mode."
+#endif
+
 #if !__ARM_FEATURE_MVE
 #error "MVE feature not supported"
 #endif
@@ -2526,6 +2530,22 @@  typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
 #define vgetq_lane_u16(__a,  __idx) __arm_vgetq_lane_u16(__a,  __idx)
 #define vgetq_lane_u32(__a,  __idx) __arm_vgetq_lane_u32(__a,  __idx)
 #define vgetq_lane_u64(__a,  __idx) __arm_vgetq_lane_u64(__a,  __idx)
+#define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1)
+#define sqrshrl(__p0, __p1) __arm_sqrshrl(__p0, __p1)
+#define sqrshrl_sat48(__p0, __p1) __arm_sqrshrl_sat48(__p0, __p1)
+#define sqshl(__p0, __p1) __arm_sqshl(__p0, __p1)
+#define sqshll(__p0, __p1) __arm_sqshll(__p0, __p1)
+#define srshr(__p0, __p1) __arm_srshr(__p0, __p1)
+#define srshrl(__p0, __p1) __arm_srshrl(__p0, __p1)
+#define uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1)
+#define uqrshll(__p0, __p1) __arm_uqrshll(__p0, __p1)
+#define uqrshll_sat48(__p0, __p1) __arm_uqrshll_sat48(__p0, __p1)
+#define uqshl(__p0, __p1) __arm_uqshl(__p0, __p1)
+#define uqshll(__p0, __p1) __arm_uqshll(__p0, __p1)
+#define urshr(__p0, __p1) __arm_urshr(__p0, __p1)
+#define urshrl(__p0, __p1) __arm_urshrl(__p0, __p1)
+#define lsll(__p0, __p1) __arm_lsll(__p0, __p1)
+#define asrl(__p0, __p1) __arm_asrl(__p0, __p1)
 #endif
 
 /* For big-endian, GCC's vector indices are reversed within each 64 bits
@@ -16539,6 +16559,118 @@  __arm_vgetq_lane_u64 (uint64x2_t __a, const int __idx)
   return __a[__ARM_LANEQ(__a,__idx)];
 }
 
+__extension__ extern __inline  uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_lsll (uint64_t value, int32_t shift)
+{
+  return (value << shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_asrl (int64_t value, int32_t shift)
+{
+  return (value >> shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshll (uint64_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshll_sat64_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshll_sat48 (uint64_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshll_sat48_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshrl (int64_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshrl_sat64_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshrl_sat48 (int64_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshrl_sat48_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqshll (uint64_t value, const int shift)
+{
+  return __builtin_mve_uqshll_di (value, shift);
+}
+
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_urshrl (uint64_t value, const int shift)
+{
+  return __builtin_mve_urshrl_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_srshrl (int64_t value, const int shift)
+{
+  return __builtin_mve_srshrl_di (value, shift);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqshll (int64_t value, const int shift)
+{
+  return __builtin_mve_sqshll_di (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqrshl (uint32_t value, int32_t shift)
+{
+  return __builtin_mve_uqrshl_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqrshr (int32_t value, int32_t shift)
+{
+  return __builtin_mve_sqrshr_si (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_uqshl (uint32_t value, const int shift)
+{
+  return  __builtin_mve_uqshl_si (value, shift);
+}
+
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_urshr (uint32_t value, const int shift)
+{
+  return __builtin_mve_urshr_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_sqshl (int32_t value, const int shift)
+{
+  return __builtin_mve_sqshl_si (value, shift);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__arm_srshr (int32_t value, const int shift)
+{
+  return __builtin_mve_srshr_si (value, shift);
+}
+
 #if (__ARM_FEATURE_MVE & 2) /* MVE Floating point.  */
 
 __extension__ extern __inline void
diff --git a/gcc/config/arm/arm_mve_builtins.def b/gcc/config/arm/arm_mve_builtins.def
index a60650cb7b1fe4e52ab1c7bf3c1215ff083a106f..9379927ae509c1b4fb70e7cbbad40bf645284714 100644
--- a/gcc/config/arm/arm_mve_builtins.def
+++ b/gcc/config/arm/arm_mve_builtins.def
@@ -876,3 +876,17 @@  VAR1 (QUADOP_UNONE_UNONE_UNONE_UNONE_UNONE, vsbcq_m_u, v4si)
 VAR5 (STORE1, vst2q, v16qi, v8hi, v4si, v8hf, v4sf)
 VAR5 (LOAD1, vld4q, v16qi, v8hi, v4si, v8hf, v4sf)
 VAR5 (LOAD1, vld2q, v16qi, v8hi, v4si, v8hf, v4sf)
+VAR1 (ASRL, sqrshr_,si)
+VAR1 (ASRL, sqrshrl_sat64_,di)
+VAR1 (ASRL, sqrshrl_sat48_,di)
+VAR1 (LSLL, uqrshl_, si)
+VAR1 (LSLL, uqrshll_sat64_, di)
+VAR1 (LSLL, uqrshll_sat48_, di)
+VAR1 (SQSHL,srshr_,si)
+VAR1 (SQSHL,srshrl_,di)
+VAR1 (SQSHL,sqshl_,si)
+VAR1 (SQSHL,sqshll_,di)
+VAR1 (UQSHL, urshr_, si)
+VAR1 (UQSHL, urshrl_, di)
+VAR1 (UQSHL, uqshl_, si)
+VAR1 (UQSHL, uqshll_, di)
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 2b59d5a58171cddea1155610ddbb3c7f96105d24..ce98e35763107844a70377fbc3e9921bf055b0cb 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -214,7 +214,9 @@ 
 			 VLDRDQGBWB_S VLDRDQGBWB_U VADCQ_U VADCQ_M_U VADCQ_S
 			 VADCQ_M_S VSBCIQ_U VSBCIQ_S VSBCIQ_M_U VSBCIQ_M_S
 			 VSBCQ_U VSBCQ_S VSBCQ_M_U VSBCQ_M_S VADCIQ_U VADCIQ_M_U
-			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q])
+			 VADCIQ_S VADCIQ_M_S VLD2Q VLD4Q VST2Q SRSHRL SRSHR
+			 URSHR URSHRL SQRSHR UQRSHL UQRSHLL_64
+			 UQRSHLL_48 SQRSHRL_64 SQRSHRL_48])
 
 (define_mode_attr MVE_CNVT [(V8HI "V8HF") (V4SI "V4SF") (V8HF "V8HI")
 			    (V4SF "V4SI")])
@@ -391,7 +393,8 @@ 
 		       (VSBCIQ_M_U "u") (VSBCIQ_S "s") (VSBCIQ_M_S "s")
 		       (VADCQ_U "u")  (VADCQ_M_U "u") (VADCQ_S "s")
 		       (VADCIQ_U "u") (VADCIQ_M_U "u") (VADCIQ_S "s")
-		       (VADCIQ_M_S "s")])
+		       (VADCIQ_M_S "s") (SQRSHRL_64 "64") (SQRSHRL_48 "48")
+		       (UQRSHLL_64 "64") (UQRSHLL_48 "48")])
 
 (define_int_attr mode1 [(VCTP8Q "8") (VCTP16Q "16") (VCTP32Q "32")
 			(VCTP64Q "64") (VCTP8Q_M "8") (VCTP16Q_M "16")
@@ -654,7 +657,8 @@ 
 (define_int_iterator VSBCIQ_M [VSBCIQ_M_U VSBCIQ_M_S])
 (define_int_iterator VADCQ [VADCQ_U VADCQ_S])
 (define_int_iterator VADCQ_M [VADCQ_M_U VADCQ_M_S])
-
+(define_int_iterator UQRSHLLQ [UQRSHLL_64 UQRSHLL_48])
+(define_int_iterator SQRSHRLQ [SQRSHRL_64 SQRSHRL_48])
 
 (define_insn "*mve_mov<mode>"
   [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w,w,r,w,Us")
@@ -11005,3 +11009,143 @@ 
    return "vmov\t%f0, %J1, %K1";
 }
  [(set_attr "type" "mve_move")])
+
+;;
+;; [uqrshll_di]
+;;
+(define_insn "mve_uqrshll_sat<supf>_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 UQRSHLLQ))]
+  "TARGET_HAVE_MVE"
+  "uqrshll%?\\t%Q1, %R1, #<supf>, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqrshrl_di]
+;;
+(define_insn "mve_sqrshrl_sat<supf>_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 SQRSHRLQ))]
+  "TARGET_HAVE_MVE"
+  "sqrshrl%?\\t%Q1, %R1, #<supf>, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqrshl_si]
+;;
+(define_insn "mve_uqrshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 UQRSHL))]
+  "TARGET_HAVE_MVE"
+  "uqrshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqrshr_si]
+;;
+(define_insn "mve_sqrshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "s_register_operand" "r")]
+	 SQRSHR))]
+  "TARGET_HAVE_MVE"
+  "sqrshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqshll_di]
+;;
+(define_insn "mve_uqshll_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(us_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "uqshll%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [urshrl_di]
+;;
+(define_insn "mve_urshrl_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 URSHRL))]
+  "TARGET_HAVE_MVE"
+  "urshrl%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [uqshl_si]
+;;
+(define_insn "mve_uqshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(us_ashift:SI (match_operand:SI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "uqshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [urshr_si]
+;;
+(define_insn "mve_urshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 URSHR))]
+  "TARGET_HAVE_MVE"
+  "urshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqshl_si]
+;;
+(define_insn "mve_sqshl_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "sqshl%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [srshr_si]
+;;
+(define_insn "mve_srshr_si"
+  [(set (match_operand:SI 0 "arm_general_register_operand" "+r")
+	(unspec:SI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 SRSHR))]
+  "TARGET_HAVE_MVE"
+  "srshr%?\\t%1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [srshrl_di]
+;;
+(define_insn "mve_srshrl_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(unspec:DI [(match_operand:DI 1 "arm_general_register_operand" "r")
+		    (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")]
+	 SRSHRL))]
+  "TARGET_HAVE_MVE"
+  "srshrl%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
+
+;;
+;; [sqshll_di]
+;;
+(define_insn "mve_sqshll_di"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+	(ss_ashift:DI (match_operand:DI 1 "arm_general_register_operand" "r")
+		      (match_operand:SI 2 "arm_reg_or_long_shift_imm" "rPg")))]
+  "TARGET_HAVE_MVE"
+  "sqshll%?\\t%Q1, %R1, %2"
+  [(set_attr "predicable" "yes")])
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..a2d5160e518b482f80eb26fae61f1d4b63e5e63f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+asrl_reg (int64_t longval3, int32_t x)
+{
+  return asrl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "asrl\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c1b62fb9f27a0c90a9bea43ea0bc0234e7b2721
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+lsll_reg (uint64_t longval3, int32_t x)
+{
+  return lsll (longval3, x);
+}
+
+/* { dg-final { scan-assembler "lsll\\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f0a228e4b49595939d4cbff6cf18d6d7c53b52e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshr.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+sqrshr_reg (int32_t longval3, int32_t x)
+{
+  return sqrshr (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshr\\tr\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f1612cde77ba62a48a83a3f5ef6ba35e5034b1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat48.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqrshrl_reg (int64_t longval3, int32_t x)
+{
+  return sqrshrl_sat48 (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #48, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d0a4bd155ac65b0724cf67fe916105e4db39b5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqrshrl_sat64.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqrshrl_reg (int64_t longval3, int32_t x)
+{
+  return sqrshrl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "sqrshrl\\tr\[0-9\]+, r\[0-9\]+, #64, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..8cb8c74b2686ef3c0e68fa949fa96944b8b1d799
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+sqshl_imm (int32_t longval3)
+{
+  return sqshl (longval3, 25);
+}
+
+/* { dg-final { scan-assembler "sqshl\\tr\[0-9\]+, #25" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
new file mode 100644
index 0000000000000000000000000000000000000000..016ef2a336ed9e5d2539f927435932ab14687f3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+sqshll_imm(int64_t value)
+{
+  return sqshll (value, 21);
+}
+
+/* { dg-final { scan-assembler "sqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..264f0bf09ce1684966ade2fdba62b70261e8f438
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int32_t
+srshr_imm (int32_t longval3)
+{
+  return srshr (longval3, 25);
+}
+
+/* { dg-final { scan-assembler "srshr\\tr\[0-9\]+, #25" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab12d0da63596c7c4fb3bcb5bfc8f20fc5b0de31
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+int64_t
+srshrl_imm(int64_t value)
+{
+  return srshrl (value, 21);
+}
+
+/* { dg-final { scan-assembler "srshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..0064aa19fbc55a5b759f3aa8df2d9329eeee868d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint32_t
+uqrshl_reg (uint32_t longval3, int32_t x)
+{
+  return uqrshl (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshl\\tr\[0-9\]+, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
new file mode 100644
index 0000000000000000000000000000000000000000..24cd232441306721e067fd441e803a5352477921
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat48.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqrshll_reg (uint64_t longval3, int32_t x)
+{
+  return uqrshll_sat48 (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #48, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
new file mode 100644
index 0000000000000000000000000000000000000000..22aaafdb919747721a408a8d6d2f18b770184f79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqrshll_sat64.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqrshll_reg (uint64_t longval3, int32_t x)
+{
+  return uqrshll (longval3, x);
+}
+
+/* { dg-final { scan-assembler "uqrshll\\tr\[0-9\]+, r\[0-9\]+, #64, r\[0-9\]+" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e6ff649805acfca497bbcbe78f7538a2df0da30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint32_t
+uqshl_imm (uint32_t longval3)
+{
+  return uqshl (longval3, 21);
+}
+
+/* { dg-final { scan-assembler "uqshl\\tr\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
new file mode 100644
index 0000000000000000000000000000000000000000..52560721d6ff405c2bec64fdf833601c877d41be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+uqshll_imm(uint64_t value)
+{
+  return uqshll (value, 21);
+}
+
+/* { dg-final { scan-assembler "uqshll\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
new file mode 100644
index 0000000000000000000000000000000000000000..ec5d84bb0099de9f6b28bbb3bd6765c731d24ae8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+urshr_imm (uint32_t longval3)
+{
+  return urshr (longval3, 21);
+}
+
+/* { dg-final { scan-assembler "urshr\\tr\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..ea29412ab7a6438bab7ca84a98810f99b95dbecf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl.c
@@ -0,0 +1,13 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+uint64_t
+urshrl_imm(uint64_t value)
+{
+  return urshrl (value, 21);
+}
+
+/* { dg-final { scan-assembler "urshrl\\tr\[0-9\]+, r\[0-9\]+, #21" } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 58919a31a009f8202d746a654093d32de1bdf987..53524e11d52763a9db7459db50cf410ad6ff63ca 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4712,6 +4712,9 @@  proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } {
 	    #if !(__ARM_FEATURE_MVE & 2)
 	    #error "__ARM_FEATURE_MVE for floating point not defined"
 	    #endif
+	    #if __ARM_BIG_ENDIAN
+	    #error "MVE intrinsics are not supported in Big-Endian mode."
+	    #endif
 	} "$flags -mthumb"] } {
 	    set et_arm_v8_1m_mve_fp_flags "$flags -mthumb"
 	    return 1
@@ -4891,6 +4894,9 @@  proc check_effective_target_arm_v8_1m_mve_ok_nocache { } {
             #if !defined (__ARM_FEATURE_MVE)
             #error "__ARM_FEATURE_MVE not defined"
             #endif
+	    #if __ARM_BIG_ENDIAN
+	    #error "MVE intrinsics are not supported in Big-Endian mode."
+	    #endif
         } "$flags -mthumb"] } {
             set et_arm_v8_1m_mve_flags "$flags -mthumb"
             return 1