aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/aarch64/aarch64-sve.md25
-rw-r--r--gcc/config/aarch64/iterators.md6
-rw-r--r--gcc/internal-fn.def2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fscale.c46
4 files changed, 72 insertions, 7 deletions
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 5f0ecf4..affdb24 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -5088,6 +5088,21 @@
;; - FTSSEL
;; -------------------------------------------------------------------------
+(define_expand "ldexp<mode>3"
+ [(set (match_operand:GPF_HF 0 "register_operand")
+ (unspec:GPF_HF
+ [(match_dup 3)
+ (const_int SVE_STRICT_GP)
+ (match_operand:GPF_HF 1 "register_operand")
+ (match_operand:<V_INT_EQUIV> 2 "register_operand")]
+ UNSPEC_COND_FSCALE))]
+ "TARGET_SVE"
+ {
+ operands[3] = aarch64_ptrue_reg (<VPRED>mode,
+ GET_MODE_UNIT_SIZE (<MODE>mode));
+ }
+)
+
;; Unpredicated floating-point binary operations that take an integer as
;; their second operand.
(define_insn "@aarch64_sve_<optab><mode>"
@@ -5103,17 +5118,17 @@
;; Predicated floating-point binary operations that take an integer
;; as their second operand.
(define_insn "@aarch64_pred_<optab><mode>"
- [(set (match_operand:SVE_FULL_F 0 "register_operand")
- (unspec:SVE_FULL_F
+ [(set (match_operand:SVE_FULL_F_SCALAR 0 "register_operand")
+ (unspec:SVE_FULL_F_SCALAR
[(match_operand:<VPRED> 1 "register_operand")
(match_operand:SI 4 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_F 2 "register_operand")
+ (match_operand:SVE_FULL_F_SCALAR 2 "register_operand")
(match_operand:<V_INT_EQUIV> 3 "register_operand")]
SVE_COND_FP_BINARY_INT))]
"TARGET_SVE"
{@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ]
- [ w , Upl , 0 , w ; * ] <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- [ ?&w , Upl , w , w ; yes ] movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ [ w , Upl , 0 , w ; * ] <sve_fp_op>\t%Z0.<Vetype>, %1/m, %Z0.<Vetype>, %Z3.<Vetype>
+ [ ?&w , Upl , w , w ; yes ] movprfx\t%Z0, %Z2\;<sve_fp_op>\t%Z0.<Vetype>, %1/m, %Z0.<Vetype>, %Z3.<Vetype>
}
)
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 8e3b5731..ce8f032 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -452,6 +452,9 @@
;; All fully-packed SVE floating-point vector modes.
(define_mode_iterator SVE_FULL_F [VNx8HF VNx4SF VNx2DF])
+;; Fully-packed SVE floating-point vector modes and their scalar equivalents.
+(define_mode_iterator SVE_FULL_F_SCALAR [SVE_FULL_F GPF_HF])
+
;; Fully-packed SVE integer vector modes that have 8-bit or 16-bit elements.
(define_mode_iterator SVE_FULL_BHI [VNx16QI VNx8HI])
@@ -2354,7 +2357,8 @@
(VNx8DI "VNx2BI") (VNx8DF "VNx2BI")
(V8QI "VNx8BI") (V16QI "VNx16BI")
(V4HI "VNx4BI") (V8HI "VNx8BI") (V2SI "VNx2BI")
- (V4SI "VNx4BI") (V2DI "VNx2BI") (V1DI "VNx2BI")])
+ (V4SI "VNx4BI") (V2DI "VNx2BI") (V1DI "VNx2BI")
+ (HF "VNx8BI") (SF "VNx4BI") (DF "VNx2BI")])
;; ...and again in lower case.
(define_mode_attr vpred [(VNx16QI "vnx16bi") (VNx8QI "vnx8bi")
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index c3d0efc..09b7844 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -441,7 +441,7 @@ DEF_INTERNAL_OPTAB_FN (VEC_FMADDSUB, ECF_CONST, vec_fmaddsub, ternary)
DEF_INTERNAL_OPTAB_FN (VEC_FMSUBADD, ECF_CONST, vec_fmsubadd, ternary)
/* FP scales. */
-DEF_INTERNAL_FLT_FN (LDEXP, ECF_CONST, ldexp, binary)
+DEF_INTERNAL_FLT_FLOATN_FN (LDEXP, ECF_CONST, ldexp, binary)
/* Ternary math functions. */
DEF_INTERNAL_FLT_FLOATN_FN (FMA, ECF_CONST, fma, ternary)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fscale.c b/gcc/testsuite/gcc.target/aarch64/sve/fscale.c
new file mode 100644
index 0000000..23e295d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fscale.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Ofast" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** test_ldexpf16:
+** ...
+** ptrue (p[0-7]).b, vl2
+** ...
+** fscale z[0-9]+\.h, \1/m, z[0-9]+\.h, z[0-9]+\.h
+** ret
+*/
+_Float16
+test_ldexpf16 (_Float16 x, int i)
+{
+ return __builtin_ldexpf16 (x, i);
+}
+
+/*
+** test_ldexpf:
+** ...
+** ptrue (p[0-7])\.b, vl4
+** ...
+** fscale z[0-9]+\.s, \1/m, z[0-9]+\.s, z[0-9]+\.s
+** ret
+*/
+float
+test_ldexpf (float x, int i)
+{
+ return __builtin_ldexpf (x, i);
+}
+
+/*
+** test_ldexp:
+** ...
+** ptrue (p[0-7]).b, vl8
+** ...
+** fscale z[0-9]+\.d, \1/m, z[0-9]+\.d, z[0-9]+\.d
+** ret
+*/
+double
+test_ldexp (double x, int i)
+{
+ return __builtin_ldexp (x, i);
+}
+