Commit 4be8cf77 by Srinath Parvathaneni Committed by Kyrylo Tkachov

[ARM][GCC][1/2x]: MVE intrinsics with binary operands.

This patch supports following MVE ACLE intrinsics with binary operand.

vsubq_n_f16, vsubq_n_f32, vbrsrq_n_f16, vbrsrq_n_f32, vcvtq_n_f16_s16, vcvtq_n_f32_s32, vcvtq_n_f16_u16, vcvtq_n_f32_u32, vcreateq_f16, vcreateq_f32.

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

In this patch new constraint "Rd" is added, which checks the constant is with in the range of 1 to 16.
Also a new predicate "mve_imm_16" is added, to check the the matching constraint Rd.

2020-03-17  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Mihail Ionescu  <mihail.ionescu@arm.com>
            Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* config/arm/arm-builtins.c (BINOP_NONE_NONE_NONE_QUALIFIERS): Define
	qualifier for binary operands.
	(BINOP_NONE_NONE_IMM_QUALIFIERS): Likewise.
	(BINOP_NONE_UNONE_IMM_QUALIFIERS): Likewise.
	(BINOP_NONE_UNONE_UNONE_QUALIFIERS): Likewise.
	* config/arm/arm_mve.h (vsubq_n_f16): Define macro.
	(vsubq_n_f32): Likewise.
	(vbrsrq_n_f16): Likewise.
	(vbrsrq_n_f32): Likewise.
	(vcvtq_n_f16_s16): Likewise.
	(vcvtq_n_f32_s32): Likewise.
	(vcvtq_n_f16_u16): Likewise.
	(vcvtq_n_f32_u32): Likewise.
	(vcreateq_f16): Likewise.
	(vcreateq_f32): Likewise.
	(__arm_vsubq_n_f16): Define intrinsic.
	(__arm_vsubq_n_f32): Likewise.
	(__arm_vbrsrq_n_f16): Likewise.
	(__arm_vbrsrq_n_f32): Likewise.
	(__arm_vcvtq_n_f16_s16): Likewise.
	(__arm_vcvtq_n_f32_s32): Likewise.
	(__arm_vcvtq_n_f16_u16): Likewise.
	(__arm_vcvtq_n_f32_u32): Likewise.
	(__arm_vcreateq_f16): Likewise.
	(__arm_vcreateq_f32): Likewise.
	(vsubq): Define polymorphic variant.
	(vbrsrq): Likewise.
	(vcvtq_n): Likewise.
	* config/arm/arm_mve_builtins.def (BINOP_NONE_NONE_NONE_QUALIFIERS): Use
	it.
	(BINOP_NONE_NONE_IMM_QUALIFIERS): Likewise.
	(BINOP_NONE_UNONE_IMM_QUALIFIERS): Likewise.
	(BINOP_NONE_UNONE_UNONE_QUALIFIERS): Likewise.
	* config/arm/constraints.md (Rd): Define constraint to check constant is
	in the range of 1 to 16.
	* config/arm/mve.md (mve_vsubq_n_f<mode>): Define RTL pattern.
	mve_vbrsrq_n_f<mode>: Likewise.
	mve_vcvtq_n_to_f_<supf><mode>: Likewise.
	mve_vcreateq_f<mode>: Likewise.
	* config/arm/predicates.md (mve_imm_16): Define predicate to check
	the matching constraint Rd.

gcc/testsuite/ChangeLog:

2020-03-17  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Mihail Ionescu  <mihail.ionescu@arm.com>
            Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* gcc.target/arm/mve/intrinsics/vbrsrq_n_f16.c: New test.
	* gcc.target/arm/mve/intrinsics/vbrsrq_n_f32.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcreateq_f16.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcreateq_f32.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcvtq_n_f16_s16.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcvtq_n_f16_u16.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcvtq_n_f32_s32.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vcvtq_n_f32_u32.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vsubq_n_f16.c: Likewise.
	* gcc.target/arm/mve/intrinsics/vsubq_n_f32.c: Likewise.
parent a475f153
...@@ -2,6 +2,52 @@ ...@@ -2,6 +2,52 @@
Mihail Ionescu <mihail.ionescu@arm.com> Mihail Ionescu <mihail.ionescu@arm.com>
Srinath Parvathaneni <srinath.parvathaneni@arm.com> Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* config/arm/arm-builtins.c (BINOP_NONE_NONE_NONE_QUALIFIERS): Define
qualifier for binary operands.
(BINOP_NONE_NONE_IMM_QUALIFIERS): Likewise.
(BINOP_NONE_UNONE_IMM_QUALIFIERS): Likewise.
(BINOP_NONE_UNONE_UNONE_QUALIFIERS): Likewise.
* config/arm/arm_mve.h (vsubq_n_f16): Define macro.
(vsubq_n_f32): Likewise.
(vbrsrq_n_f16): Likewise.
(vbrsrq_n_f32): Likewise.
(vcvtq_n_f16_s16): Likewise.
(vcvtq_n_f32_s32): Likewise.
(vcvtq_n_f16_u16): Likewise.
(vcvtq_n_f32_u32): Likewise.
(vcreateq_f16): Likewise.
(vcreateq_f32): Likewise.
(__arm_vsubq_n_f16): Define intrinsic.
(__arm_vsubq_n_f32): Likewise.
(__arm_vbrsrq_n_f16): Likewise.
(__arm_vbrsrq_n_f32): Likewise.
(__arm_vcvtq_n_f16_s16): Likewise.
(__arm_vcvtq_n_f32_s32): Likewise.
(__arm_vcvtq_n_f16_u16): Likewise.
(__arm_vcvtq_n_f32_u32): Likewise.
(__arm_vcreateq_f16): Likewise.
(__arm_vcreateq_f32): Likewise.
(vsubq): Define polymorphic variant.
(vbrsrq): Likewise.
(vcvtq_n): Likewise.
* config/arm/arm_mve_builtins.def (BINOP_NONE_NONE_NONE_QUALIFIERS): Use
it.
(BINOP_NONE_NONE_IMM_QUALIFIERS): Likewise.
(BINOP_NONE_UNONE_IMM_QUALIFIERS): Likewise.
(BINOP_NONE_UNONE_UNONE_QUALIFIERS): Likewise.
* config/arm/constraints.md (Rd): Define constraint to check constant is
in the range of 1 to 16.
* config/arm/mve.md (mve_vsubq_n_f<mode>): Define RTL pattern.
mve_vbrsrq_n_f<mode>: Likewise.
mve_vcvtq_n_to_f_<supf><mode>: Likewise.
mve_vcreateq_f<mode>: Likewise.
* config/arm/predicates.md (mve_imm_16): Define predicate to check
the matching constraint Rd.
2020-03-17 Andre Vieira <andre.simoesdiasvieira@arm.com>
Mihail Ionescu <mihail.ionescu@arm.com>
Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* config/arm/arm-builtins.c (hi_UP): Define mode. * config/arm/arm-builtins.c (hi_UP): Define mode.
* config/arm/arm.h (IS_VPR_REGNUM): Move. * config/arm/arm.h (IS_VPR_REGNUM): Move.
* config/arm/arm.md (VPR_REGNUM): Define before APSRQ_REGNUM. * config/arm/arm.md (VPR_REGNUM): Define before APSRQ_REGNUM.
......
...@@ -373,6 +373,30 @@ arm_unop_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] ...@@ -373,6 +373,30 @@ arm_unop_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
#define UNOP_UNONE_IMM_QUALIFIERS \ #define UNOP_UNONE_IMM_QUALIFIERS \
(arm_unop_unone_imm_qualifiers) (arm_unop_unone_imm_qualifiers)
static enum arm_type_qualifiers
arm_binop_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_none, qualifier_none };
#define BINOP_NONE_NONE_NONE_QUALIFIERS \
(arm_binop_none_none_none_qualifiers)
static enum arm_type_qualifiers
arm_binop_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_none, qualifier_immediate };
#define BINOP_NONE_NONE_IMM_QUALIFIERS \
(arm_binop_none_none_imm_qualifiers)
static enum arm_type_qualifiers
arm_binop_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_unsigned, qualifier_immediate };
#define BINOP_NONE_UNONE_IMM_QUALIFIERS \
(arm_binop_none_unone_imm_qualifiers)
static enum arm_type_qualifiers
arm_binop_none_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_unsigned, qualifier_unsigned };
#define BINOP_NONE_UNONE_UNONE_QUALIFIERS \
(arm_binop_none_unone_unone_qualifiers)
/* End of Qualifier for MVE builtins. */ /* End of Qualifier for MVE builtins. */
/* void ([T element type] *, T, immediate). */ /* void ([T element type] *, T, immediate). */
......
...@@ -197,6 +197,16 @@ typedef struct { uint8x16_t val[4]; } uint8x16x4_t; ...@@ -197,6 +197,16 @@ typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
#define vctp64q(__a) __arm_vctp64q(__a) #define vctp64q(__a) __arm_vctp64q(__a)
#define vctp8q(__a) __arm_vctp8q(__a) #define vctp8q(__a) __arm_vctp8q(__a)
#define vpnot(__a) __arm_vpnot(__a) #define vpnot(__a) __arm_vpnot(__a)
#define vsubq_n_f16(__a, __b) __arm_vsubq_n_f16(__a, __b)
#define vsubq_n_f32(__a, __b) __arm_vsubq_n_f32(__a, __b)
#define vbrsrq_n_f16(__a, __b) __arm_vbrsrq_n_f16(__a, __b)
#define vbrsrq_n_f32(__a, __b) __arm_vbrsrq_n_f32(__a, __b)
#define vcvtq_n_f16_s16(__a, __imm6) __arm_vcvtq_n_f16_s16(__a, __imm6)
#define vcvtq_n_f32_s32(__a, __imm6) __arm_vcvtq_n_f32_s32(__a, __imm6)
#define vcvtq_n_f16_u16(__a, __imm6) __arm_vcvtq_n_f16_u16(__a, __imm6)
#define vcvtq_n_f32_u32(__a, __imm6) __arm_vcvtq_n_f32_u32(__a, __imm6)
#define vcreateq_f16(__a, __b) __arm_vcreateq_f16(__a, __b)
#define vcreateq_f32(__a, __b) __arm_vcreateq_f32(__a, __b)
#endif #endif
__extension__ extern __inline void __extension__ extern __inline void
...@@ -1085,6 +1095,76 @@ __arm_vcvtmq_s32_f32 (float32x4_t __a) ...@@ -1085,6 +1095,76 @@ __arm_vcvtmq_s32_f32 (float32x4_t __a)
return __builtin_mve_vcvtmq_sv4si (__a); return __builtin_mve_vcvtmq_sv4si (__a);
} }
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vsubq_n_f16 (float16x8_t __a, float16_t __b)
{
return __builtin_mve_vsubq_n_fv8hf (__a, __b);
}
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vsubq_n_f32 (float32x4_t __a, float32_t __b)
{
return __builtin_mve_vsubq_n_fv4sf (__a, __b);
}
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vbrsrq_n_f16 (float16x8_t __a, int32_t __b)
{
return __builtin_mve_vbrsrq_n_fv8hf (__a, __b);
}
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vbrsrq_n_f32 (float32x4_t __a, int32_t __b)
{
return __builtin_mve_vbrsrq_n_fv4sf (__a, __b);
}
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcvtq_n_f16_s16 (int16x8_t __a, const int __imm6)
{
return __builtin_mve_vcvtq_n_to_f_sv8hf (__a, __imm6);
}
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcvtq_n_f32_s32 (int32x4_t __a, const int __imm6)
{
return __builtin_mve_vcvtq_n_to_f_sv4sf (__a, __imm6);
}
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcvtq_n_f16_u16 (uint16x8_t __a, const int __imm6)
{
return __builtin_mve_vcvtq_n_to_f_uv8hf (__a, __imm6);
}
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcvtq_n_f32_u32 (uint32x4_t __a, const int __imm6)
{
return __builtin_mve_vcvtq_n_to_f_uv4sf (__a, __imm6);
}
__extension__ extern __inline float16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcreateq_f16 (uint64_t __a, uint64_t __b)
{
return __builtin_mve_vcreateq_fv8hf (__a, __b);
}
__extension__ extern __inline float32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_vcreateq_f32 (uint64_t __a, uint64_t __b)
{
return __builtin_mve_vcreateq_fv4sf (__a, __b);
}
#endif #endif
enum { enum {
...@@ -1452,6 +1532,27 @@ extern void *__ARM_undef; ...@@ -1452,6 +1532,27 @@ extern void *__ARM_undef;
int (*)[__ARM_mve_type_uint16x8_t]: __arm_vcvtq_f16_u16 (__ARM_mve_coerce(__p0, uint16x8_t)), \ int (*)[__ARM_mve_type_uint16x8_t]: __arm_vcvtq_f16_u16 (__ARM_mve_coerce(__p0, uint16x8_t)), \
int (*)[__ARM_mve_type_uint32x4_t]: __arm_vcvtq_f32_u32 (__ARM_mve_coerce(__p0, uint32x4_t)));}) int (*)[__ARM_mve_type_uint32x4_t]: __arm_vcvtq_f32_u32 (__ARM_mve_coerce(__p0, uint32x4_t)));})
#define vsubq(p0,p1) __arm_vsubq(p0,p1)
#define __arm_vsubq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
__typeof(p1) __p1 = (p1); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)][__ARM_mve_typeid(__p1)])0, \
int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16_t]: __arm_vsubq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), __ARM_mve_coerce(__p1, float16_t)), \
int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32_t]: __arm_vsubq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), __ARM_mve_coerce(__p1, float32_t)));})
#define vbrsrq(p0,p1) __arm_vbrsrq(p0,p1)
#define __arm_vbrsrq(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
int (*)[__ARM_mve_type_float16x8_t]: __arm_vbrsrq_n_f16 (__ARM_mve_coerce(__p0, float16x8_t), p1), \
int (*)[__ARM_mve_type_float32x4_t]: __arm_vbrsrq_n_f32 (__ARM_mve_coerce(__p0, float32x4_t), p1));})
#define vcvtq_n(p0,p1) __arm_vcvtq_n(p0,p1)
#define __arm_vcvtq_n(p0,p1) ({ __typeof(p0) __p0 = (p0); \
_Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \
int (*)[__ARM_mve_type_int16x8_t]: __arm_vcvtq_n_f16_s16 (__ARM_mve_coerce(__p0, int16x8_t), p1), \
int (*)[__ARM_mve_type_int32x4_t]: __arm_vcvtq_n_f32_s32 (__ARM_mve_coerce(__p0, int32x4_t), p1), \
int (*)[__ARM_mve_type_uint16x8_t]: __arm_vcvtq_n_f16_u16 (__ARM_mve_coerce(__p0, uint16x8_t), p1), \
int (*)[__ARM_mve_type_uint32x4_t]: __arm_vcvtq_n_f32_u32 (__ARM_mve_coerce(__p0, uint32x4_t), p1));})
#else /* MVE Interger. */ #else /* MVE Interger. */
#define vst4q(p0,p1) __arm_vst4q(p0,p1) #define vst4q(p0,p1) __arm_vst4q(p0,p1)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
GCC is free software; you can redistribute it and/or modify it GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your by the Free Software Foundation; either version 3, or (at your
option) any later version. option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT GCC is distributed in the hope that it will be useful, but WITHOUT
...@@ -76,3 +76,8 @@ VAR1 (UNOP_UNONE_UNONE, vctp32q, hi) ...@@ -76,3 +76,8 @@ VAR1 (UNOP_UNONE_UNONE, vctp32q, hi)
VAR1 (UNOP_UNONE_UNONE, vctp64q, hi) VAR1 (UNOP_UNONE_UNONE, vctp64q, hi)
VAR1 (UNOP_UNONE_UNONE, vctp8q, hi) VAR1 (UNOP_UNONE_UNONE, vctp8q, hi)
VAR1 (UNOP_UNONE_UNONE, vpnot, hi) VAR1 (UNOP_UNONE_UNONE, vpnot, hi)
VAR2 (BINOP_NONE_NONE_NONE, vsubq_n_f, v8hf, v4sf)
VAR2 (BINOP_NONE_NONE_NONE, vbrsrq_n_f, v8hf, v4sf)
VAR2 (BINOP_NONE_NONE_IMM, vcvtq_n_to_f_s, v8hf, v4sf)
VAR2 (BINOP_NONE_UNONE_IMM, vcvtq_n_to_f_u, v8hf, v4sf)
VAR2 (BINOP_NONE_UNONE_UNONE, vcreateq_f, v8hf, v4sf)
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, DN, Dm, Dl, DL, Do, Dv, Dy, Di, ;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, DN, Dm, Dl, DL, Do, Dv, Dy, Di,
;; Dt, Dp, Dz, Tu ;; Dt, Dp, Dz, Tu
;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe
;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz ;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz, Rd
;; in all states: Pf, Pg ;; in all states: Pf, Pg
;; The following memory constraints have been used: ;; The following memory constraints have been used:
...@@ -53,6 +53,11 @@ ...@@ -53,6 +53,11 @@
"MVE EVEN registers @code{r0}, @code{r2}, @code{r4}, @code{r6}, @code{r8}, "MVE EVEN registers @code{r0}, @code{r2}, @code{r4}, @code{r6}, @code{r8},
@code{r10}, @code{r12}, @code{r14}") @code{r10}, @code{r12}, @code{r14}")
(define_constraint "Rd"
"@internal In Thumb-2 state a constant in range 1 to 16"
(and (match_code "const_int")
(match_test "TARGET_HAVE_MVE && ival >= 1 && ival <= 16")))
(define_register_constraint "t" "TARGET_32BIT ? VFP_LO_REGS : NO_REGS" (define_register_constraint "t" "TARGET_32BIT ? VFP_LO_REGS : NO_REGS"
"The VFP registers @code{s0}-@code{s31}.") "The VFP registers @code{s0}-@code{s31}.")
......
...@@ -36,7 +36,9 @@ ...@@ -36,7 +36,9 @@
VREV32Q_U VREV32Q_S VMOVLTQ_U VMOVLTQ_S VMOVLBQ_S VREV32Q_U VREV32Q_S VMOVLTQ_U VMOVLTQ_S VMOVLBQ_S
VMOVLBQ_U VCVTQ_FROM_F_S VCVTQ_FROM_F_U VCVTPQ_S VMOVLBQ_U VCVTQ_FROM_F_S VCVTQ_FROM_F_U VCVTPQ_S
VCVTPQ_U VCVTNQ_S VCVTNQ_U VCVTMQ_S VCVTMQ_U VCVTPQ_U VCVTNQ_S VCVTNQ_U VCVTMQ_S VCVTMQ_U
VADDLVQ_U VCTP8Q VCTP16Q VCTP32Q VCTP64Q VPNOT]) VADDLVQ_U VCTP8Q VCTP16Q VCTP32Q VCTP64Q VPNOT
VCREATEQ_F VCVTQ_N_TO_F_S VCVTQ_N_TO_F_U VBRSRQ_N_F
VSUBQ_N_F])
(define_mode_attr MVE_CNVT [(V8HI "V8HF") (V4SI "V4SF") (define_mode_attr MVE_CNVT [(V8HI "V8HF") (V4SI "V4SF")
(V8HF "V8HI") (V4SF "V4SI")]) (V8HF "V8HI") (V4SF "V4SI")])
...@@ -52,7 +54,8 @@ ...@@ -52,7 +54,8 @@
(VCVTPQ_S "s") (VCVTPQ_U "u") (VCVTNQ_S "s") (VCVTPQ_S "s") (VCVTPQ_U "u") (VCVTNQ_S "s")
(VCVTNQ_U "u") (VCVTMQ_S "s") (VCVTMQ_U "u") (VCVTNQ_U "u") (VCVTMQ_S "s") (VCVTMQ_U "u")
(VCLZQ_U "u") (VCLZQ_S "s") (VREV32Q_U "u") (VCLZQ_U "u") (VCLZQ_S "s") (VREV32Q_U "u")
(VREV32Q_S "s") (VADDLVQ_U "u") (VADDLVQ_S "s")]) (VREV32Q_S "s") (VADDLVQ_U "u") (VADDLVQ_S "s")
(VCVTQ_N_TO_F_S "s") (VCVTQ_N_TO_F_U "u")])
(define_int_attr mode1 [(VCTP8Q "8") (VCTP16Q "16") (VCTP32Q "32") (define_int_attr mode1 [(VCTP8Q "8") (VCTP16Q "16") (VCTP32Q "32")
(VCTP64Q "64")]) (VCTP64Q "64")])
...@@ -75,6 +78,7 @@ ...@@ -75,6 +78,7 @@
(define_int_iterator VCVTMQ [VCVTMQ_S VCVTMQ_U]) (define_int_iterator VCVTMQ [VCVTMQ_S VCVTMQ_U])
(define_int_iterator VADDLVQ [VADDLVQ_U VADDLVQ_S]) (define_int_iterator VADDLVQ [VADDLVQ_U VADDLVQ_S])
(define_int_iterator VCTPQ [VCTP8Q VCTP16Q VCTP32Q VCTP64Q]) (define_int_iterator VCTPQ [VCTP8Q VCTP16Q VCTP32Q VCTP64Q])
(define_int_iterator VCVTQ_N_TO_F [VCVTQ_N_TO_F_S VCVTQ_N_TO_F_U])
(define_insn "*mve_mov<mode>" (define_insn "*mve_mov<mode>"
[(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w,w,r,w,Us") [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w,w,r,w,Us")
...@@ -687,3 +691,62 @@ ...@@ -687,3 +691,62 @@
"vpnot" "vpnot"
[(set_attr "type" "mve_move") [(set_attr "type" "mve_move")
]) ])
;;
;; [vsubq_n_f])
;;
(define_insn "mve_vsubq_n_f<mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
(unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w")
(match_operand:<V_elem> 2 "s_register_operand" "r")]
VSUBQ_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vsub.f<V_sz_elem> %q0, %q1, %2"
[(set_attr "type" "mve_move")
])
;;
;; [vbrsrq_n_f])
;;
(define_insn "mve_vbrsrq_n_f<mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
(unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "w")
(match_operand:SI 2 "s_register_operand" "r")]
VBRSRQ_N_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vbrsr.<V_sz_elem> %q0, %q1, %2"
[(set_attr "type" "mve_move")
])
;;
;; [vcvtq_n_to_f_s, vcvtq_n_to_f_u])
;;
(define_insn "mve_vcvtq_n_to_f_<supf><mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
(unspec:MVE_0 [(match_operand:<MVE_CNVT> 1 "s_register_operand" "w")
(match_operand:SI 2 "mve_imm_16" "Rd")]
VCVTQ_N_TO_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vcvt.f<V_sz_elem>.<supf><V_sz_elem>\t%q0, %q1, %2"
[(set_attr "type" "mve_move")
])
;; [vcreateq_f])
;;
(define_insn "mve_vcreateq_f<mode>"
[
(set (match_operand:MVE_0 0 "s_register_operand" "=w")
(unspec:MVE_0 [(match_operand:DI 1 "s_register_operand" "r")
(match_operand:DI 2 "s_register_operand" "r")]
VCREATEQ_F))
]
"TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
"vmov %q0[2], %q0[0], %Q2, %Q1\;vmov %q0[3], %q0[1], %R2, %R1"
[(set_attr "type" "mve_move")
(set_attr "length""8")])
...@@ -31,6 +31,10 @@ ...@@ -31,6 +31,10 @@
|| REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
}) })
;; True for immediates in the range of 1 to 16 for MVE.
(define_predicate "mve_imm_16"
(match_test "satisfies_constraint_Rd (op)"))
; Predicate for stack protector guard's address in ; Predicate for stack protector guard's address in
; stack_protect_combined_set_insn and stack_protect_combined_test_insn patterns ; stack_protect_combined_set_insn and stack_protect_combined_test_insn patterns
(define_predicate "guard_addr_operand" (define_predicate "guard_addr_operand"
......
...@@ -2,6 +2,21 @@ ...@@ -2,6 +2,21 @@
Mihail Ionescu <mihail.ionescu@arm.com> Mihail Ionescu <mihail.ionescu@arm.com>
Srinath Parvathaneni <srinath.parvathaneni@arm.com> Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* gcc.target/arm/mve/intrinsics/vbrsrq_n_f16.c: New test.
* gcc.target/arm/mve/intrinsics/vbrsrq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcvtq_n_f16_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcvtq_n_f16_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcvtq_n_f32_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcvtq_n_f32_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_f32.c: Likewise.
2020-03-17 Andre Vieira <andre.simoesdiasvieira@arm.com>
Mihail Ionescu <mihail.ionescu@arm.com>
Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* gcc.target/arm/mve/intrinsics/vctp16q.c: New test. * gcc.target/arm/mve/intrinsics/vctp16q.c: New test.
* gcc.target/arm/mve/intrinsics/vctp32q.c: Likewise. * gcc.target/arm/mve/intrinsics/vctp32q.c: Likewise.
* gcc.target/arm/mve/intrinsics/vctp64q.c: Likewise. * gcc.target/arm/mve/intrinsics/vctp64q.c: Likewise.
......
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float16x8_t
foo (float16x8_t a, int32_t b)
{
return vbrsrq_n_f16 (a, b);
}
/* { dg-final { scan-assembler "vbrsr.16" } } */
float16x8_t
foo1 (float16x8_t a, int32_t b)
{
return vbrsrq (a, b);
}
/* { dg-final { scan-assembler "vbrsr.16" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float32x4_t
foo (float32x4_t a, int32_t b)
{
return vbrsrq_n_f32 (a, b);
}
/* { dg-final { scan-assembler "vbrsr.32" } } */
float32x4_t
foo1 (float32x4_t a, int32_t b)
{
return vbrsrq (a, b);
}
/* { dg-final { scan-assembler "vbrsr.32" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float16x8_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_f16 (a, b);
}
/* { dg-final { scan-assembler "vmov" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float32x4_t
foo (uint64_t a, uint64_t b)
{
return vcreateq_f32 (a, b);
}
/* { dg-final { scan-assembler "vmov" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float16x8_t
foo (int16x8_t a)
{
return vcvtq_n_f16_s16 (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f16.s16" } } */
float16x8_t
foo1 (int16x8_t a)
{
return vcvtq_n (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f16.s16" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float16x8_t
foo (uint16x8_t a)
{
return vcvtq_n_f16_u16 (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f16.u16" } } */
float16x8_t
foo1 (uint16x8_t a)
{
return vcvtq_n (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f16.u16" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float32x4_t
foo (int32x4_t a)
{
return vcvtq_n_f32_s32 (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f32.s32" } } */
float32x4_t
foo1 (int32x4_t a)
{
return vcvtq_n (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f32.s32" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float32x4_t
foo (uint32x4_t a)
{
return vcvtq_n_f32_u32 (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f32.u32" } } */
float32x4_t
foo1 (uint32x4_t a)
{
return vcvtq_n (a, 1);
}
/* { dg-final { scan-assembler "vcvt.f32.u32" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float16x8_t
foo (float16x8_t a, float16_t b)
{
return vsubq_n_f16 (a, b);
}
/* { dg-final { scan-assembler "vsub.f16" } } */
float16x8_t
foo1 (float16x8_t a, float16_t b)
{
return vsubq (a, b);
}
/* { dg-final { scan-assembler "vsub.f16" } } */
/* { dg-do compile } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-add-options arm_v8_1m_mve_fp } */
/* { dg-additional-options "-O2" } */
#include "arm_mve.h"
float32x4_t
foo (float32x4_t a, float32_t b)
{
return vsubq_n_f32 (a, b);
}
/* { dg-final { scan-assembler "vsub.f32" } } */
float32x4_t
foo1 (float32x4_t a, float32_t b)
{
return vsubq (a, b);
}
/* { dg-final { scan-assembler "vsub.f32" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment