2013-05-01 James Greenhalgh <james.greenhalgh@arm.com>
+ * config/aarch64/aarch64-simd-builtins.def
+ (reduc_smax_): New.
+ (reduc_smin_): Likewise.
+ (reduc_umax_): Likewise.
+ (reduc_umin_): Likewise.
+ (reduc_smax_nan_): Likewise.
+ (reduc_smin_nan_): Likewise.
+ (fmax): Remove.
+ (fmin): Likewise.
+ (smax): Update for V2SF, V4SF and V2DF modes.
+ (smin): Likewise.
+ (smax_nan): New.
+ (smin_nan): Likewise.
+ * config/aarch64/aarch64-simd.md (<maxmin><mode>3): Rename to...
+ (<su><maxmin><mode>3): ...This, refactor.
+ (s<maxmin><mode>3): New.
+ (<maxmin_uns><mode>3): Likewise.
+ (reduc_<maxmin_uns>_<mode>): Refactor.
+ (reduc_<maxmin_uns>_v4sf): Likewise.
+ (reduc_<maxmin_uns>_v2si): Likewise.
+ (aarch64_<fmaxmin><mode>: Remove.
+ * config/aarch64/arm_neon.h (vmax<q>_f<32,64>): Rewrite to use
+ new builtin names.
+ (vmin<q>_f<32,64>): Likewise.
+ * config/iterators.md (unspec): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
+ (FMAXMIN): New.
+ (su): Add mappings for smax, smin, umax, umin.
+ (maxmin): New.
+ (FMAXMINV): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
+ (FMAXMIN): Rename as...
+ (FMAXMIN_UNS): ...This.
+ (maxminv): Remove.
+ (fmaxminv): Likewise.
+ (fmaxmin): Likewise.
+ (maxmin_uns): New.
+ (maxmin_uns_op): Likewise.
+
+2013-05-01 James Greenhalgh <james.greenhalgh@arm.com>
+
* config/aarch64/arm_neon.h
(vac<ge, gt><sd>_f<32, 64>): Rename to...
(vca<ge, gt><sd>_f<32, 64>): ...this, reimpliment in C.
BUILTIN_VSDQ_I_DI (BINOP, cmgtu, 0)
BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0)
- /* Implemented by aarch64_<fmaxmin><mode>. */
- BUILTIN_VDQF (BINOP, fmax, 0)
- BUILTIN_VDQF (BINOP, fmin, 0)
-
/* Implemented by aarch64_addv<mode>. */
BUILTIN_VDQF (UNOP, addv, 0)
- /* Implemented by <maxmin><mode>3. */
- BUILTIN_VDQ_BHSI (BINOP, smax, 3)
- BUILTIN_VDQ_BHSI (BINOP, smin, 3)
+ /* Implemented by reduc_<maxmin_uns>_<mode>. */
+ BUILTIN_VDQIF (UNOP, reduc_smax_, 10)
+ BUILTIN_VDQIF (UNOP, reduc_smin_, 10)
+ BUILTIN_VDQ_BHSI (UNOP, reduc_umax_, 10)
+ BUILTIN_VDQ_BHSI (UNOP, reduc_umin_, 10)
+ BUILTIN_VDQF (UNOP, reduc_smax_nan_, 10)
+ BUILTIN_VDQF (UNOP, reduc_smin_nan_, 10)
+
+ /* Implemented by <maxmin><mode>3.
+ smax variants map to fmaxnm,
+ smax_nan variants map to fmax. */
+ BUILTIN_VDQIF (BINOP, smax, 3)
+ BUILTIN_VDQIF (BINOP, smin, 3)
BUILTIN_VDQ_BHSI (BINOP, umax, 3)
BUILTIN_VDQ_BHSI (BINOP, umin, 3)
+ BUILTIN_VDQF (BINOP, smax_nan, 3)
+ BUILTIN_VDQF (BINOP, smin_nan, 3)
/* Implemented by <frint_pattern><mode>2. */
BUILTIN_VDQF (UNOP, btrunc, 2)
)
;; Max/Min operations.
-(define_insn "<maxmin><mode>3"
+(define_insn "<su><maxmin><mode>3"
[(set (match_operand:VQ_S 0 "register_operand" "=w")
(MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w")
(match_operand:VQ_S 2 "register_operand" "w")))]
"TARGET_SIMD"
- "<maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "<su><maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_minmax")
(set_attr "simd_mode" "<MODE>")]
)
;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
;; NaNs.
-(define_insn "smax<mode>3"
+(define_insn "<su><maxmin><mode>3"
[(set (match_operand:VDQF 0 "register_operand" "=w")
- (smax:VDQF (match_operand:VDQF 1 "register_operand" "w")
+ (FMAXMIN:VDQF (match_operand:VDQF 1 "register_operand" "w")
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
- "fmaxnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "f<maxmin>nm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_fminmax")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "smin<mode>3"
+(define_insn "<maxmin_uns><mode>3"
[(set (match_operand:VDQF 0 "register_operand" "=w")
- (smin:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
+ (match_operand:VDQF 2 "register_operand" "w")]
+ FMAXMIN_UNS))]
"TARGET_SIMD"
- "fminnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; FP 'across lanes' max and min ops.
-
-(define_insn "reduc_s<fmaxminv>_v4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmv\\t%s0, %1.4s";
- [(set_attr "simd_type" "simd_fminmaxv")
- (set_attr "simd_mode" "V4SF")]
-)
-
-(define_insn "reduc_s<fmaxminv>_<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmp\\t%0.<Vtype>, %1.<Vtype>, %1.<Vtype>";
+ "<maxmin_uns_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_fminmax")
(set_attr "simd_mode" "<MODE>")]
)
""
)
-(define_insn "reduc_<maxminv>_<mode>"
+;; 'across lanes' max and min ops.
+
+(define_insn "reduc_<maxmin_uns>_<mode>"
[(set (match_operand:VDQV 0 "register_operand" "=w")
(unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
MAXMINV))]
"TARGET_SIMD"
- "<maxminv>v\\t%<Vetype>0, %1.<Vtype>"
+ "<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
[(set_attr "simd_type" "simd_minmaxv")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "reduc_<maxminv>_v2si"
+(define_insn "reduc_<maxmin_uns>_v2di"
+ [(set (match_operand:V2DI 0 "register_operand" "=w")
+ (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
+ MAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>p\\t%d0, %1.2d"
+ [(set_attr "simd_type" "simd_minmaxv")
+ (set_attr "simd_mode" "V2DI")]
+)
+
+(define_insn "reduc_<maxmin_uns>_v2si"
[(set (match_operand:V2SI 0 "register_operand" "=w")
(unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
MAXMINV))]
"TARGET_SIMD"
- "<maxminv>p\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_minmax")
+ "<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
+ [(set_attr "simd_type" "simd_minmaxv")
(set_attr "simd_mode" "V2SI")]
)
+(define_insn "reduc_<maxmin_uns>_<mode>"
+ [(set (match_operand:V2F 0 "register_operand" "=w")
+ (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
+ FMAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>p\\t%<Vetype>0, %1.<Vtype>"
+ [(set_attr "simd_type" "simd_fminmaxv")
+ (set_attr "simd_mode" "<MODE>")]
+)
+
+(define_insn "reduc_<maxmin_uns>_v4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "=w")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
+ FMAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>v\\t%s0, %1.4s"
+ [(set_attr "simd_type" "simd_fminmaxv")
+ (set_attr "simd_mode" "V4SF")]
+)
+
;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
;; allocation.
;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
(set_attr "simd_mode" "DI")]
)
-(define_insn "aarch64_<fmaxmin><mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")]
- FMAXMIN))]
- "TARGET_SIMD"
- "<fmaxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
;; sqrt
(define_insn "sqrt<mode>2"
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
vmax_f32 (float32x2_t __a, float32x2_t __b)
{
- return __builtin_aarch64_fmaxv2sf (__a, __b);
+ return __builtin_aarch64_smax_nanv2sf (__a, __b);
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
vmaxq_f32 (float32x4_t __a, float32x4_t __b)
{
- return __builtin_aarch64_fmaxv4sf (__a, __b);
+ return __builtin_aarch64_smax_nanv4sf (__a, __b);
}
__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
vmaxq_f64 (float64x2_t __a, float64x2_t __b)
{
- return __builtin_aarch64_fmaxv2df (__a, __b);
+ return __builtin_aarch64_smax_nanv2df (__a, __b);
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
vmin_f32 (float32x2_t __a, float32x2_t __b)
{
- return __builtin_aarch64_fminv2sf (__a, __b);
+ return __builtin_aarch64_smin_nanv2sf (__a, __b);
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
vminq_f32 (float32x4_t __a, float32x4_t __b)
{
- return __builtin_aarch64_fminv4sf (__a, __b);
+ return __builtin_aarch64_smin_nanv4sf (__a, __b);
}
__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
vminq_f64 (float64x2_t __a, float64x2_t __b)
{
- return __builtin_aarch64_fminv2df (__a, __b);
+ return __builtin_aarch64_smin_nanv2df (__a, __b);
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
[
UNSPEC_ASHIFT_SIGNED ; Used in aarch-simd.md.
UNSPEC_ASHIFT_UNSIGNED ; Used in aarch64-simd.md.
+ UNSPEC_FMAX ; Used in aarch64-simd.md.
+ UNSPEC_FMAXNMV ; Used in aarch64-simd.md.
UNSPEC_FMAXV ; Used in aarch64-simd.md.
+ UNSPEC_FMIN ; Used in aarch64-simd.md.
+ UNSPEC_FMINNMV ; Used in aarch64-simd.md.
UNSPEC_FMINV ; Used in aarch64-simd.md.
UNSPEC_FADDV ; Used in aarch64-simd.md.
UNSPEC_ADDV ; Used in aarch64-simd.md.
UNSPEC_SSHLL ; Used in aarch64-simd.md.
UNSPEC_USHLL ; Used in aarch64-simd.md.
UNSPEC_ADDP ; Used in aarch64-simd.md.
- UNSPEC_FMAX ; Used in aarch64-simd.md.
- UNSPEC_FMIN ; Used in aarch64-simd.md.
UNSPEC_TBL ; Used in vector permute patterns.
UNSPEC_CONCAT ; Used in vector permute patterns.
UNSPEC_ZIP1 ; Used in vector permute patterns.
;; Code iterator for variants of vector max and min.
(define_code_iterator MAXMIN [smax smin umax umin])
+(define_code_iterator FMAXMIN [smax smin])
+
;; Code iterator for variants of vector max and min.
(define_code_iterator ADDSUB [plus minus])
(define_code_attr su [(sign_extend "s") (zero_extend "u")
(sign_extract "s") (zero_extract "u")
(fix "s") (unsigned_fix "u")
- (div "s") (udiv "u")])
+ (div "s") (udiv "u")
+ (smax "s") (umax "u")
+ (smin "s") (umin "u")])
;; Emit cbz/cbnz depending on comparison type.
(define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")])
(define_code_attr tbz [(eq "tbz") (ne "tbnz") (lt "tbnz") (ge "tbz")])
;; Max/min attributes.
-(define_code_attr maxmin [(smax "smax")
- (smin "smin")
- (umax "umax")
- (umin "umin")])
+(define_code_attr maxmin [(smax "max")
+ (smin "min")
+ (umax "max")
+ (umin "min")])
;; MLA/MLS attributes.
(define_code_attr as [(ss_plus "a") (ss_minus "s")])
(define_int_iterator MAXMINV [UNSPEC_UMAXV UNSPEC_UMINV
UNSPEC_SMAXV UNSPEC_SMINV])
-(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV])
+(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV
+ UNSPEC_FMAXNMV UNSPEC_FMINNMV])
(define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD
UNSPEC_SRHADD UNSPEC_URHADD
(define_int_iterator ADDSUBHN2 [UNSPEC_ADDHN2 UNSPEC_RADDHN2
UNSPEC_SUBHN2 UNSPEC_RSUBHN2])
-(define_int_iterator FMAXMIN [UNSPEC_FMAX UNSPEC_FMIN])
+(define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN])
(define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH])
;; -------------------------------------------------------------------
;; Int Iterators Attributes.
;; -------------------------------------------------------------------
-(define_int_attr maxminv [(UNSPEC_UMAXV "umax")
- (UNSPEC_UMINV "umin")
- (UNSPEC_SMAXV "smax")
- (UNSPEC_SMINV "smin")])
-
-(define_int_attr fmaxminv [(UNSPEC_FMAXV "max")
- (UNSPEC_FMINV "min")])
-
-(define_int_attr fmaxmin [(UNSPEC_FMAX "fmax")
- (UNSPEC_FMIN "fmin")])
+(define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax")
+ (UNSPEC_UMINV "umin")
+ (UNSPEC_SMAXV "smax")
+ (UNSPEC_SMINV "smin")
+ (UNSPEC_FMAX "smax_nan")
+ (UNSPEC_FMAXNMV "smax")
+ (UNSPEC_FMAXV "smax_nan")
+ (UNSPEC_FMIN "smin_nan")
+ (UNSPEC_FMINNMV "smin")
+ (UNSPEC_FMINV "smin_nan")])
+
+(define_int_attr maxmin_uns_op [(UNSPEC_UMAXV "umax")
+ (UNSPEC_UMINV "umin")
+ (UNSPEC_SMAXV "smax")
+ (UNSPEC_SMINV "smin")
+ (UNSPEC_FMAX "fmax")
+ (UNSPEC_FMAXNMV "fmaxnm")
+ (UNSPEC_FMAXV "fmax")
+ (UNSPEC_FMIN "fmin")
+ (UNSPEC_FMINNMV "fminnm")
+ (UNSPEC_FMINV "fmin")])
(define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
(UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")