Add patch 5/6 for full power7/VSX support

Co-Authored-By: Pat Haugen <pthaugen@us.ibm.com>
Co-Authored-By: Revital Eres <eres@il.ibm.com>

From-SVN: r150271
This commit is contained in:
Michael Meissner 2009-07-30 20:48:17 +00:00 committed by Michael Meissner
parent 1b3b24c2a6
commit 29e6733c20
48 changed files with 5730 additions and 236 deletions

View File

@ -1,3 +1,203 @@
2009-07-30 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Revital Eres <ERES@il.ibm.com>
* config/rs6000/vector.md (VEC_F): Add VSX support.
(VEC_A): Ditto.
(VEC_N): Ditto.
(mov<mode>): Ditto.
(vector_load_<mode>): Ditto.
(vector_store_<mode>): Ditto.
(vector GPR move split): Ditto.
(vec_reload_and_plus_<mptrsize>): Ditto.
(vec_reload_and_reg_<mptrsize>): Ditto.
(add<mode>3): Ditto.
(sub<mode>3): Ditto.
(mul<mode>3): Ditto.
(neg<mode>2): Ditto.
(abs<mode>2): Ditto.
(smin<mode>3): Ditto.
(smax<mode>3): Ditto.
(vector_eq<mode>): Ditto.
(vector_gt<mode>): Ditto.
(vector_ge<mode>): Ditto.
(vector_gtu<mode>): Ditto.
(vector_select_<mode>_uns): Ditto.
(vector_eq_<mode>_p): Ditto.
(vector_gt_<mode>_p): Ditto.
(vector_ge_<mode>_p): Ditto.
(vector_gtu_<mode>_p): Ditto.
(cr6_test_for_zero): Ditto.
(cr6_test_for_zero_reverse): Ditto.
(cr6_test_for_lt): Ditto.
(cr6_test_for_lt_reverse): Ditto.
(xor<mode>3): Ditto.
(ior<mode>3): Ditto.
(and<mode>3): Ditto.
(one_cmpl<mode>2): Ditto.
(nor<mode>2): Ditto.
(andc<mode>2): Ditto.
(float<VEC_int<mode>2): Ditto.
(unsigned_float<VEC_int><mode>2): Ditto.
(fix_trunc<mode><VEC_int>2): Ditto.
(fixuns_trunc<mode><VEC_int>2): Ditto.
(vec_init<mode>):
(vec_set<mode>): Ditto.
(vec_extract<mode>): Ditto.
(vec_interleave_highv4sf): Ditto.
(vec_interleave_lowv4sf): Ditto.
(vec_realign_load_<mode>): Ditto.
(vec_shl_<mode>): Ditto.
(vec_shr_<mode>): Ditto.
(div<mode>3): New patterns for VSX.
(vec_interleave_highv2df): Ditto.
(vec_interleave_lowv2df): Ditto.
(vec_pack_trunc_v2df): Ditto.
(vec_pack_sfix_trunc_v2df): Ditto.
(vec_pack_ufix_trunc_v2df): Ditto.
(vec_unpacks_hi_v4sf): Ditto.
(vec_unpacks_lo_v4sf): Ditto.
(vec_unpacks_float_hi_v4si): Ditto.
(vec_unpacku_float_lo_v4si): Ditto.
(vec_unpacku_float_hi_v4si): Ditto.
(vec_unpacks_float_lo_v4si): Ditto.
(movmisalign<mode>): Ditto.
(vector_ceil<mode>2): New patterns for vectorizing math library.
(vector_floor<mode>2): Ditto.
(vector_btrunc<mode>2): Ditto.
(vector_copysign<mode>3): Ditto.
* config/rs6000/predicates.md (easy_vector_constant_msb): New
predicate for setting the high bit in each word, used for
copysign.
* config/rs6000/ppc-asm.h (f19): Whitespace.
(f32-f63): Define if VSX.
(v0-v31): Define if Altivec.
(vs0-vs63): Define if VSX.
* config/rs6000/t-rs6000 (MD_INCLUDES): Add power7.md and vsx.md.
* config/rs6000/power7.md: New file, provide tuning parameters for
-mcpu=power7.
* config/rs6000/rs6000-c.c (rs6000_macro_to_expand): Add VSX
support.
(rs6000_cpu_cpp_builtins): Ditto.
(altivec_overloaded_builtins): Ditto.
(altivec_resolve_overloaded_builtin): Ditto.
* config/rs6000/rs6000.opt (-mno-vectorize-builtins): Add new
debug switch to disable vectorizing simple math builtin
functions.
* config/rs6000/rs6000.c (rs6000_builtin_vectorized_function):
Vectorize simple math builtin functions.
(TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Define target
hook to vectorize math builtins.
(rs6000_override_options): Enable -mvsx on -mcpu=power7.
(rs6000_builtin_conversion): Add VSX/power7 support.
(rs6000_builtin_vec_perm): Ditto.
(vsplits_constant): Add support for loading up a vector constant
with just the high bit set in each part.
(rs6000_expand_vector_init): Add VSX/power7 support.
(rs6000_expand_vector_set): Ditto.
(rs6000_expand_vector_extract): Ditto.
(rs6000_emit_move): Ditto.
(bdesc_3arg): Ditto.
(bdesc_2arg): Ditto.
(bdesc_1arg): Ditto.
(rs6000_expand_ternop_builtin): Ditto.
(altivec_expand_builtin): Ditto.
(rs6000_expand_unop_builtin): Ditto.
(rs6000_init_builtins): Ditto.
(altivec_init_builtins): Ditto.
(builtin_function_type): Ditto.
(rs6000_common_init_builtins): Ditto.
(rs6000_handle_altivec_attribute); Ditto.
(rs6000_mangle_type): Ditto.
(rs6000_vector_mode_supported_p): Ditto.
(rs6000_mode_dependent_address): Altivec addresses with AND -16
are mode dependent.
* config/rs6000/vsx.md: New file for VSX support.
* config/rs6000/rs6000.h (EASY_VECTOR_MSB): New macro for
identifing values with just the most significant bit set.
(enum rs6000_builtins): Add builtins for VSX. Add simple math
vectorized builtins.
* config/rs6000/altivec.md (UNSPEC_VRFIP): Delete.
(UNSPEC_VRFIM): Delete.
(splitter for loading up vector with most significant bit): New
splitter for vectorizing copysign.
(altivec_vrfiz): Rename from altivec_fturncv4sf2. Add support for
vectorizing simple math functions.
(altivec_vrfip): Add support for vectorizing simple math
functions.
(altivec_vrfim): Ditto.
(altivec_copysign_v4sf3): New insn for Altivec copysign support.
* config/rs6000/rs6000.md (UNSPEC_BPERM): New constant.
(power7.md, vsx.md): Include for power7 support.
(copysigndf3): Use VSX instructions if -mvsx.
(negdf2_fpr): Ditto.
(absdf2_fpr): Ditto.
(nabsdf2_fpr): Ditto.
(adddf3_fpr): Ditto.
(subdf3_fpr): Ditto.
(muldf3_fpr): Ditto.
(divdf3_fpr): Ditto.
(fix_truncdfdi2_fpr): Ditto.
(cmpdf_internal1): Ditto.
(fred, fred_fpr): Convert into expander/insn to add VSX support.
(btruncdf2, btruncdf2_fpr): Ditto.
(ceildf2, ceildf2_fpr): Ditto.
(floordf2, floordf2_fpr): Ditto.
(floatdidf2, floatdidf2_fpr): Ditto.
(fmadddf4_fpr): Name insn. Use VSX instructions if -mvsx.
(fmsubdf4_fpr): Ditto.
(fnmadddf4_fpr_1): Ditto.
(fnmadddf4_fpr_2): Ditto.
(fnmsubdf4_fpr_1): Ditto.
(fnmsubdf4_fpr_2): Ditto.
(fixuns_truncdfdi2): Add expander for VSX support.
(fix_truncdfdi2): Ditto.
(fix_truncdfsi2): Ditto.
(ftruncdf2): Ditto.
(btruncsf2): Whitespace.
(movdf_hardfloat32): Add support for VSX registers.
(movdf_softfloat32): Ditto.
(movdf_hardfloat64): Ditto.
(movdf_hardfloat64_mfpgpr): Ditto.
(movdf_softfloat64): Ditto.
(movti splitters): Add check for vector registers supporting
TImode in the future.
(bpermd): Add power7 bpermd instruction.
* config/rs6000/altivec.h (vec_div): Define if VSX.
(vec_mul): Ditto.
(vec_msub): Ditto.
(vec_nmadd): Ditto.
(vec_nearbyint): Ditto.
(vec_rint): Ditto.
(vec_sqrt): Ditto.
(all predicates): Use the generic builtin function, and not the
V4SF specific function so that the predicates will work with
VSX's V2DF.
(vec_all_*): Ditto.
(vec_any_*): Ditto.
* doc/extend.texi (PowerPC Altivec/VSX Built-in Functions):
Document new VSX functions and types.
* doc/invoke.texi (PowerPc options): Document -mpopcntd, -mvsx
switches.
* doc/md.texi (PowerPC constraints): Document "wd", "wf", "ws",
"wa", and "j" constraints. Modify "v" to talk about Altivec
instead of just vector.
2009-07-30 Andrew MacLeod <amacleod@redhat.com> 2009-07-30 Andrew MacLeod <amacleod@redhat.com>
PR debug/26475 PR debug/26475

View File

@ -306,6 +306,17 @@
#define vec_splats __builtin_vec_splats #define vec_splats __builtin_vec_splats
#define vec_promote __builtin_vec_promote #define vec_promote __builtin_vec_promote
#ifdef __VSX__
/* VSX additions */
#define vec_div __builtin_vec_div
#define vec_mul __builtin_vec_mul
#define vec_msub __builtin_vec_msub
#define vec_nmadd __builtin_vec_nmadd
#define vec_nearbyint __builtin_vec_nearbyint
#define vec_rint __builtin_vec_rint
#define vec_sqrt __builtin_vec_sqrt
#endif
/* Predicates. /* Predicates.
For C++, we use templates in order to allow non-parenthesized arguments. For C++, we use templates in order to allow non-parenthesized arguments.
For C, instead, we use macros since non-parenthesized arguments were For C, instead, we use macros since non-parenthesized arguments were
@ -356,14 +367,14 @@ __altivec_scalar_pred(vec_any_out,
__builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2)) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2))
__altivec_unary_pred(vec_all_nan, __altivec_unary_pred(vec_all_nan,
__builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a1)) __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1))
__altivec_unary_pred(vec_any_nan, __altivec_unary_pred(vec_any_nan,
__builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, a1, a1)) __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1))
__altivec_unary_pred(vec_all_numeric, __altivec_unary_pred(vec_all_numeric,
__builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a1)) __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1))
__altivec_unary_pred(vec_any_numeric, __altivec_unary_pred(vec_any_numeric,
__builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, a1, a1)) __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1))
__altivec_scalar_pred(vec_all_eq, __altivec_scalar_pred(vec_all_eq,
__builtin_vec_vcmpeq_p (__CR6_LT, a1, a2)) __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2))
@ -384,13 +395,13 @@ __altivec_scalar_pred(vec_any_lt,
__builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1)) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1))
__altivec_scalar_pred(vec_all_ngt, __altivec_scalar_pred(vec_all_ngt,
__builtin_altivec_vcmpgtfp_p (__CR6_EQ, a1, a2)) __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2))
__altivec_scalar_pred(vec_all_nlt, __altivec_scalar_pred(vec_all_nlt,
__builtin_altivec_vcmpgtfp_p (__CR6_EQ, a2, a1)) __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1))
__altivec_scalar_pred(vec_any_ngt, __altivec_scalar_pred(vec_any_ngt,
__builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a1, a2)) __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2))
__altivec_scalar_pred(vec_any_nlt, __altivec_scalar_pred(vec_any_nlt,
__builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a2, a1)) __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1))
/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types,
while for integer types it is converted to __builtin_vec_vcmpgt_p, while for integer types it is converted to __builtin_vec_vcmpgt_p,
@ -405,13 +416,13 @@ __altivec_scalar_pred(vec_any_ge,
__builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2)) __builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2))
__altivec_scalar_pred(vec_all_nge, __altivec_scalar_pred(vec_all_nge,
__builtin_altivec_vcmpgefp_p (__CR6_EQ, a1, a2)) __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2))
__altivec_scalar_pred(vec_all_nle, __altivec_scalar_pred(vec_all_nle,
__builtin_altivec_vcmpgefp_p (__CR6_EQ, a2, a1)) __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1))
__altivec_scalar_pred(vec_any_nge, __altivec_scalar_pred(vec_any_nge,
__builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a1, a2)) __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2))
__altivec_scalar_pred(vec_any_nle, __altivec_scalar_pred(vec_any_nle,
__builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a2, a1)) __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1))
#undef __altivec_scalar_pred #undef __altivec_scalar_pred
#undef __altivec_unary_pred #undef __altivec_unary_pred
@ -423,11 +434,11 @@ __altivec_scalar_pred(vec_any_nle,
#define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)) #define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2))
#define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)) #define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2))
#define vec_all_nan(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (a1), (a1)) #define vec_all_nan(a1) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a1))
#define vec_any_nan(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, (a1), (a1)) #define vec_any_nan(a1) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a1))
#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT, (a1), (a1)) #define vec_all_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a1))
#define vec_any_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, (a1), (a1)) #define vec_any_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a1))
#define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2)) #define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2))
#define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2)) #define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2))
@ -439,10 +450,10 @@ __altivec_scalar_pred(vec_any_nle,
#define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2)) #define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2))
#define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1)) #define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1))
#define vec_all_ngt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a1), (a2)) #define vec_all_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a1), (a2))
#define vec_all_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a2), (a1)) #define vec_all_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a2), (a1))
#define vec_any_ngt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a1), (a2)) #define vec_any_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a1), (a2))
#define vec_any_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a2), (a1)) #define vec_any_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a2), (a1))
/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, /* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types,
while for integer types it is converted to __builtin_vec_vcmpgt_p, while for integer types it is converted to __builtin_vec_vcmpgt_p,
@ -452,10 +463,10 @@ __altivec_scalar_pred(vec_any_nle,
#define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1)) #define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1))
#define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2)) #define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2))
#define vec_all_nge(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a1), (a2)) #define vec_all_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a1), (a2))
#define vec_all_nle(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a2), (a1)) #define vec_all_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a2), (a1))
#define vec_any_nge(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a1), (a2)) #define vec_any_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a1), (a2))
#define vec_any_nle(a1, a2) __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a2), (a1)) #define vec_any_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a2), (a1))
#endif #endif
/* These do not accept vectors, so they do not have a __builtin_vec_* /* These do not accept vectors, so they do not have a __builtin_vec_*

View File

@ -20,8 +20,8 @@
;; <http://www.gnu.org/licenses/>. ;; <http://www.gnu.org/licenses/>.
(define_constants (define_constants
[(UNSPEC_VCMPBFP 50)
;; 51-62 deleted ;; 51-62 deleted
[(UNSPEC_VCMPBFP 64)
(UNSPEC_VMSUMU 65) (UNSPEC_VMSUMU 65)
(UNSPEC_VMSUMM 66) (UNSPEC_VMSUMM 66)
(UNSPEC_VMSUMSHM 68) (UNSPEC_VMSUMSHM 68)
@ -66,9 +66,9 @@
(UNSPEC_VSUMSWS 135) (UNSPEC_VSUMSWS 135)
(UNSPEC_VPERM 144) (UNSPEC_VPERM 144)
(UNSPEC_VPERM_UNS 145) (UNSPEC_VPERM_UNS 145)
(UNSPEC_VRFIP 148) ;; 148 deleted
(UNSPEC_VRFIN 149) (UNSPEC_VRFIN 149)
(UNSPEC_VRFIM 150) ;; 150 deleted
(UNSPEC_VCFUX 151) (UNSPEC_VCFUX 151)
(UNSPEC_VCFSX 152) (UNSPEC_VCFSX 152)
(UNSPEC_VCTUXS 153) (UNSPEC_VCTUXS 153)
@ -220,6 +220,35 @@
} }
[(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
;; Load up a vector with the most significant bit set by loading up -1 and
;; doing a shift left
(define_split
[(set (match_operand:VM 0 "altivec_register_operand" "")
(match_operand:VM 1 "easy_vector_constant_msb" ""))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && reload_completed"
[(const_int 0)]
{
rtx dest = operands[0];
enum machine_mode mode = GET_MODE (operands[0]);
rtvec v;
int i, num_elements;
if (mode == V4SFmode)
{
mode = V4SImode;
dest = gen_lowpart (V4SImode, dest);
}
num_elements = GET_MODE_NUNITS (mode);
v = rtvec_alloc (num_elements);
for (i = 0; i < num_elements; i++)
RTVEC_ELT (v, i) = constm1_rtx;
emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v)));
emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest)));
DONE;
})
(define_split (define_split
[(set (match_operand:VM 0 "altivec_register_operand" "") [(set (match_operand:VM 0 "altivec_register_operand" "")
(match_operand:VM 1 "easy_vector_constant_add_self" ""))] (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
@ -1310,7 +1339,7 @@
"vspltis<VI_char> %0,%1" "vspltis<VI_char> %0,%1"
[(set_attr "type" "vecperm")]) [(set_attr "type" "vecperm")])
(define_insn "*altivec_ftruncv4sf2" (define_insn "*altivec_vrfiz"
[(set (match_operand:V4SF 0 "register_operand" "=v") [(set (match_operand:V4SF 0 "register_operand" "=v")
(fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
@ -1337,10 +1366,10 @@
"vperm %0,%1,%2,%3" "vperm %0,%1,%2,%3"
[(set_attr "type" "vecperm")]) [(set_attr "type" "vecperm")])
(define_insn "altivec_vrfip" (define_insn "altivec_vrfip" ; ceil
[(set (match_operand:V4SF 0 "register_operand" "=v") [(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
UNSPEC_VRFIP))] UNSPEC_FRIP))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC"
"vrfip %0,%1" "vrfip %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")])
@ -1353,10 +1382,10 @@
"vrfin %0,%1" "vrfin %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")])
(define_insn "altivec_vrfim" (define_insn "*altivec_vrfim" ; floor
[(set (match_operand:V4SF 0 "register_operand" "=v") [(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
UNSPEC_VRFIM))] UNSPEC_FRIM))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC"
"vrfim %0,%1" "vrfim %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")])
@ -1431,6 +1460,28 @@
"vrefp %0,%1" "vrefp %0,%1"
[(set_attr "type" "vecfloat")]) [(set_attr "type" "vecfloat")])
(define_expand "altivec_copysign_v4sf3"
[(use (match_operand:V4SF 0 "register_operand" ""))
(use (match_operand:V4SF 1 "register_operand" ""))
(use (match_operand:V4SF 2 "register_operand" ""))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"
{
rtx mask = gen_reg_rtx (V4SImode);
rtvec v = rtvec_alloc (4);
unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
RTVEC_ELT (v, 0) = GEN_INT (mask_val);
RTVEC_ELT (v, 1) = GEN_INT (mask_val);
RTVEC_ELT (v, 2) = GEN_INT (mask_val);
RTVEC_ELT (v, 3) = GEN_INT (mask_val);
emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
gen_lowpart (V4SFmode, mask)));
DONE;
}")
(define_insn "altivec_vsldoi_<mode>" (define_insn "altivec_vsldoi_<mode>"
[(set (match_operand:VM 0 "register_operand" "=v") [(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v") (unspec:VM [(match_operand:VM 1 "register_operand" "v")

318
gcc/config/rs6000/power7.md Normal file
View File

@ -0,0 +1,318 @@
;; Scheduling description for IBM POWER7 processor.
;; Copyright (C) 2009 Free Software Foundation, Inc.
;;
;; Contributed by Pat Haugen (pthaugen@us.ibm.com).
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_automaton "power7iu,power7lsu,power7vsu,power7misc")
(define_cpu_unit "iu1_power7,iu2_power7" "power7iu")
(define_cpu_unit "lsu1_power7,lsu2_power7" "power7lsu")
(define_cpu_unit "vsu1_power7,vsu2_power7" "power7vsu")
(define_cpu_unit "bpu_power7,cru_power7" "power7misc")
(define_cpu_unit "du1_power7,du2_power7,du3_power7,du4_power7,du5_power7"
"power7misc")
(define_reservation "DU_power7"
"du1_power7|du2_power7|du3_power7|du4_power7")
(define_reservation "DU2F_power7"
"du1_power7+du2_power7")
(define_reservation "DU4_power7"
"du1_power7+du2_power7+du3_power7+du4_power7")
(define_reservation "FXU_power7"
"iu1_power7|iu2_power7")
(define_reservation "VSU_power7"
"vsu1_power7|vsu2_power7")
(define_reservation "LSU_power7"
"lsu1_power7|lsu2_power7")
; Dispatch slots are allocated in order conforming to program order.
(absence_set "du1_power7" "du2_power7,du3_power7,du4_power7,du5_power7")
(absence_set "du2_power7" "du3_power7,du4_power7,du5_power7")
(absence_set "du3_power7" "du4_power7,du5_power7")
(absence_set "du4_power7" "du5_power7")
; LS Unit
(define_insn_reservation "power7-load" 2
(and (eq_attr "type" "load")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7")
(define_insn_reservation "power7-load-ext" 3
(and (eq_attr "type" "load_ext")
(eq_attr "cpu" "power7"))
"DU2F_power7,LSU_power7,FXU_power7")
(define_insn_reservation "power7-load-update" 2
(and (eq_attr "type" "load_u")
(eq_attr "cpu" "power7"))
"DU2F_power7,LSU_power7+FXU_power7")
(define_insn_reservation "power7-load-update-indexed" 3
(and (eq_attr "type" "load_ux")
(eq_attr "cpu" "power7"))
"DU4_power7,FXU_power7,LSU_power7+FXU_power7")
(define_insn_reservation "power7-load-ext-update" 4
(and (eq_attr "type" "load_ext_u")
(eq_attr "cpu" "power7"))
"DU2F_power7,LSU_power7+FXU_power7,FXU_power7")
(define_insn_reservation "power7-load-ext-update-indexed" 4
(and (eq_attr "type" "load_ext_ux")
(eq_attr "cpu" "power7"))
"DU4_power7,FXU_power7,LSU_power7+FXU_power7,FXU_power7")
(define_insn_reservation "power7-fpload" 3
(and (eq_attr "type" "fpload")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7")
(define_insn_reservation "power7-fpload-update" 3
(and (eq_attr "type" "fpload_u,fpload_ux")
(eq_attr "cpu" "power7"))
"DU2F_power7,LSU_power7+FXU_power7")
(define_insn_reservation "power7-store" 6 ; store-forwarding latency
(and (eq_attr "type" "store")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7+FXU_power7")
(define_insn_reservation "power7-store-update" 6
(and (eq_attr "type" "store_u")
(eq_attr "cpu" "power7"))
"DU2F_power7,LSU_power7+FXU_power7,FXU_power7")
(define_insn_reservation "power7-store-update-indexed" 6
(and (eq_attr "type" "store_ux")
(eq_attr "cpu" "power7"))
"DU4_power7,LSU_power7+FXU_power7,FXU_power7")
(define_insn_reservation "power7-fpstore" 6
(and (eq_attr "type" "fpstore")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7+VSU_power7")
(define_insn_reservation "power7-fpstore-update" 6
(and (eq_attr "type" "fpstore_u,fpstore_ux")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7+VSU_power7+FXU_power7")
(define_insn_reservation "power7-larx" 3
(and (eq_attr "type" "load_l")
(eq_attr "cpu" "power7"))
"DU4_power7,LSU_power7")
(define_insn_reservation "power7-stcx" 10
(and (eq_attr "type" "store_c")
(eq_attr "cpu" "power7"))
"DU4_power7,LSU_power7")
(define_insn_reservation "power7-vecload" 3
(and (eq_attr "type" "vecload")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7")
(define_insn_reservation "power7-vecstore" 6
(and (eq_attr "type" "vecstore")
(eq_attr "cpu" "power7"))
"DU_power7,LSU_power7+VSU_power7")
(define_insn_reservation "power7-sync" 11
(and (eq_attr "type" "sync")
(eq_attr "cpu" "power7"))
"DU4_power7,LSU_power7")
; FX Unit
(define_insn_reservation "power7-integer" 1
(and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\
var_shift_rotate,exts")
(eq_attr "cpu" "power7"))
"DU_power7,FXU_power7")
(define_insn_reservation "power7-cntlz" 2
(and (eq_attr "type" "cntlz")
(eq_attr "cpu" "power7"))
"DU_power7,FXU_power7")
(define_insn_reservation "power7-two" 2
(and (eq_attr "type" "two")
(eq_attr "cpu" "power7"))
"DU_power7+DU_power7,FXU_power7,FXU_power7")
(define_insn_reservation "power7-three" 3
(and (eq_attr "type" "three")
(eq_attr "cpu" "power7"))
"DU_power7+DU_power7+DU_power7,FXU_power7,FXU_power7,FXU_power7")
(define_insn_reservation "power7-cmp" 1
(and (eq_attr "type" "cmp,fast_compare")
(eq_attr "cpu" "power7"))
"DU_power7,FXU_power7")
(define_insn_reservation "power7-compare" 2
(and (eq_attr "type" "compare,delayed_compare,var_delayed_compare")
(eq_attr "cpu" "power7"))
"DU2F_power7,FXU_power7,FXU_power7")
(define_bypass 3 "power7-cmp,power7-compare" "power7-crlogical,power7-delayedcr")
(define_insn_reservation "power7-mul" 4
(and (eq_attr "type" "imul,imul2,imul3,lmul")
(eq_attr "cpu" "power7"))
"DU_power7,FXU_power7")
(define_insn_reservation "power7-mul-compare" 5
(and (eq_attr "type" "imul_compare,lmul_compare")
(eq_attr "cpu" "power7"))
"DU2F_power7,FXU_power7,nothing*3,FXU_power7")
(define_insn_reservation "power7-idiv" 36
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "power7"))
"DU2F_power7,iu1_power7*36|iu2_power7*36")
(define_insn_reservation "power7-ldiv" 68
(and (eq_attr "type" "ldiv")
(eq_attr "cpu" "power7"))
"DU2F_power7,iu1_power7*68|iu2_power7*68")
(define_insn_reservation "power7-isync" 1 ;
(and (eq_attr "type" "isync")
(eq_attr "cpu" "power7"))
"DU4_power7,FXU_power7")
; CR Unit
(define_insn_reservation "power7-mtjmpr" 4
(and (eq_attr "type" "mtjmpr")
(eq_attr "cpu" "power7"))
"du1_power7,FXU_power7")
(define_insn_reservation "power7-mfjmpr" 5
(and (eq_attr "type" "mfjmpr")
(eq_attr "cpu" "power7"))
"du1_power7,cru_power7+FXU_power7")
(define_insn_reservation "power7-crlogical" 3
(and (eq_attr "type" "cr_logical")
(eq_attr "cpu" "power7"))
"du1_power7,cru_power7")
(define_insn_reservation "power7-delayedcr" 3
(and (eq_attr "type" "delayed_cr")
(eq_attr "cpu" "power7"))
"du1_power7,cru_power7")
(define_insn_reservation "power7-mfcr" 6
(and (eq_attr "type" "mfcr")
(eq_attr "cpu" "power7"))
"du1_power7,cru_power7")
(define_insn_reservation "power7-mfcrf" 3
(and (eq_attr "type" "mfcrf")
(eq_attr "cpu" "power7"))
"du1_power7,cru_power7")
(define_insn_reservation "power7-mtcr" 3
(and (eq_attr "type" "mtcr")
(eq_attr "cpu" "power7"))
"DU4_power7,cru_power7+FXU_power7")
; BR Unit
; Branches take dispatch Slot 4. The presence_sets prevent other insn from
; grabbing previous dispatch slots once this is assigned.
(define_insn_reservation "power7-branch" 3
(and (eq_attr "type" "jmpreg,branch")
(eq_attr "cpu" "power7"))
"(du5_power7\
|du4_power7+du5_power7\
|du3_power7+du4_power7+du5_power7\
|du2_power7+du3_power7+du4_power7+du5_power7\
|du1_power7+du2_power7+du3_power7+du4_power7+du5_power7),bpu_power7")
; VS Unit (includes FP/VSX/VMX/DFP)
(define_insn_reservation "power7-fp" 6
(and (eq_attr "type" "fp,dmul")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_bypass 8 "power7-fp" "power7-branch")
(define_insn_reservation "power7-fpcompare" 4
(and (eq_attr "type" "fpcompare")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_insn_reservation "power7-sdiv" 26
(and (eq_attr "type" "sdiv")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_insn_reservation "power7-ddiv" 32
(and (eq_attr "type" "ddiv")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_insn_reservation "power7-sqrt" 31
(and (eq_attr "type" "ssqrt")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_insn_reservation "power7-dsqrt" 43
(and (eq_attr "type" "dsqrt")
(eq_attr "cpu" "power7"))
"DU_power7,VSU_power7")
(define_insn_reservation "power7-vecsimple" 2
(and (eq_attr "type" "vecsimple")
(eq_attr "cpu" "power7"))
"du1_power7,VSU_power7")
(define_insn_reservation "power7-veccmp" 7
(and (eq_attr "type" "veccmp")
(eq_attr "cpu" "power7"))
"du1_power7,VSU_power7")
(define_insn_reservation "power7-vecfloat" 7
(and (eq_attr "type" "vecfloat")
(eq_attr "cpu" "power7"))
"du1_power7,VSU_power7")
(define_bypass 6 "power7-vecfloat" "power7-vecfloat")
(define_insn_reservation "power7-veccomplex" 7
(and (eq_attr "type" "veccomplex")
(eq_attr "cpu" "power7"))
"du1_power7,VSU_power7")
(define_insn_reservation "power7-vecperm" 3
(and (eq_attr "type" "vecperm")
(eq_attr "cpu" "power7"))
"du2_power7,VSU_power7")

View File

@ -101,6 +101,143 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define f30 30 #define f30 30
#define f31 31 #define f31 31
#ifdef __VSX__
#define f32 32
#define f33 33
#define f34 34
#define f35 35
#define f36 36
#define f37 37
#define f38 38
#define f39 39
#define f40 40
#define f41 41
#define f42 42
#define f43 43
#define f44 44
#define f45 45
#define f46 46
#define f47 47
#define f48 48
#define f49 49
#define f50 30
#define f51 51
#define f52 52
#define f53 53
#define f54 54
#define f55 55
#define f56 56
#define f57 57
#define f58 58
#define f59 59
#define f60 60
#define f61 61
#define f62 62
#define f63 63
#endif
#ifdef __ALTIVEC__
#define v0 0
#define v1 1
#define v2 2
#define v3 3
#define v4 4
#define v5 5
#define v6 6
#define v7 7
#define v8 8
#define v9 9
#define v10 10
#define v11 11
#define v12 12
#define v13 13
#define v14 14
#define v15 15
#define v16 16
#define v17 17
#define v18 18
#define v19 19
#define v20 20
#define v21 21
#define v22 22
#define v23 23
#define v24 24
#define v25 25
#define v26 26
#define v27 27
#define v28 28
#define v29 29
#define v30 30
#define v31 31
#endif
#ifdef __VSX__
#define vs0 0
#define vs1 1
#define vs2 2
#define vs3 3
#define vs4 4
#define vs5 5
#define vs6 6
#define vs7 7
#define vs8 8
#define vs9 9
#define vs10 10
#define vs11 11
#define vs12 12
#define vs13 13
#define vs14 14
#define vs15 15
#define vs16 16
#define vs17 17
#define vs18 18
#define vs19 19
#define vs20 20
#define vs21 21
#define vs22 22
#define vs23 23
#define vs24 24
#define vs25 25
#define vs26 26
#define vs27 27
#define vs28 28
#define vs29 29
#define vs30 30
#define vs31 31
#define vs32 32
#define vs33 33
#define vs34 34
#define vs35 35
#define vs36 36
#define vs37 37
#define vs38 38
#define vs39 39
#define vs40 40
#define vs41 41
#define vs42 42
#define vs43 43
#define vs44 44
#define vs45 45
#define vs46 46
#define vs47 47
#define vs48 48
#define vs49 49
#define vs50 30
#define vs51 51
#define vs52 52
#define vs53 53
#define vs54 54
#define vs55 55
#define vs56 56
#define vs57 57
#define vs58 58
#define vs59 59
#define vs60 60
#define vs61 61
#define vs62 62
#define vs63 63
#endif
/* /*
* Macros to glue together two tokens. * Macros to glue together two tokens.
*/ */

View File

@ -377,6 +377,16 @@
return EASY_VECTOR_15_ADD_SELF (val); return EASY_VECTOR_15_ADD_SELF (val);
}) })
;; Same as easy_vector_constant but only for EASY_VECTOR_MSB.
(define_predicate "easy_vector_constant_msb"
(and (match_code "const_vector")
(and (match_test "TARGET_ALTIVEC")
(match_test "easy_altivec_constant (op, mode)")))
{
HOST_WIDE_INT val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1);
return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode));
})
;; Return 1 if operand is constant zero (scalars and vectors). ;; Return 1 if operand is constant zero (scalars and vectors).
(define_predicate "zero_constant" (define_predicate "zero_constant"
(and (match_code "const_int,const_double,const_vector") (and (match_code "const_int,const_double,const_vector")

View File

@ -214,7 +214,8 @@ rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
if (rid_code == RID_UNSIGNED || rid_code == RID_LONG if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
|| rid_code == RID_SHORT || rid_code == RID_SIGNED || rid_code == RID_SHORT || rid_code == RID_SIGNED
|| rid_code == RID_INT || rid_code == RID_CHAR || rid_code == RID_INT || rid_code == RID_CHAR
|| rid_code == RID_FLOAT) || rid_code == RID_FLOAT
|| (rid_code == RID_DOUBLE && TARGET_VSX))
{ {
expand_this = C_CPP_HASHNODE (__vector_keyword); expand_this = C_CPP_HASHNODE (__vector_keyword);
/* If the next keyword is bool or pixel, it /* If the next keyword is bool or pixel, it
@ -329,8 +330,43 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
if (TARGET_NO_LWSYNC) if (TARGET_NO_LWSYNC)
builtin_define ("__NO_LWSYNC__"); builtin_define ("__NO_LWSYNC__");
if (TARGET_VSX) if (TARGET_VSX)
{
builtin_define ("__VSX__"); builtin_define ("__VSX__");
/* For the VSX builtin functions identical to Altivec functions, just map
the altivec builtin into the vsx version (the altivec functions
generate VSX code if -mvsx). */
builtin_define ("__builtin_vsx_xxland=__builtin_vec_and");
builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc");
builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor");
builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or");
builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor");
builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel");
builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm");
/* Also map the a and m versions of the multiply/add instructions to the
builtin for people blindly going off the instruction manual. */
builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp");
builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp");
builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp");
builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp");
builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp");
builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp");
builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp");
builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp");
builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp");
builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp");
builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp");
builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp");
builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp");
builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp");
builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp");
builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp");
}
/* Tell users they can use __builtin_bswap{16,64}. */
builtin_define ("__HAVE_BSWAP__");
/* May be overridden by target configuration. */ /* May be overridden by target configuration. */
RS6000_CPU_CPP_ENDIAN_BUILTINS(); RS6000_CPU_CPP_ENDIAN_BUILTINS();
@ -393,7 +429,7 @@ struct altivec_builtin_types
}; };
const struct altivec_builtin_types altivec_overloaded_builtins[] = { const struct altivec_builtin_types altivec_overloaded_builtins[] = {
/* Unary AltiVec builtins. */ /* Unary AltiVec/VSX builtins. */
{ ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI, { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI,
RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI, { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI,
@ -402,6 +438,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF, { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABS, VSX_BUILTIN_XVABSDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V16QI, { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V16QI,
RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V8HI, { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V8HI,
@ -410,8 +448,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_CEIL, ALTIVEC_BUILTIN_VRFIP, { ALTIVEC_BUILTIN_VEC_CEIL, ALTIVEC_BUILTIN_VRFIP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_CEIL, VSX_BUILTIN_XVRDPIP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_EXPTE, ALTIVEC_BUILTIN_VEXPTEFP, { ALTIVEC_BUILTIN_VEC_EXPTE, ALTIVEC_BUILTIN_VEXPTEFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_FLOOR, VSX_BUILTIN_XVRDPIM,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_FLOOR, ALTIVEC_BUILTIN_VRFIM, { ALTIVEC_BUILTIN_VEC_FLOOR, ALTIVEC_BUILTIN_VRFIM,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_LOGE, ALTIVEC_BUILTIN_VLOGEFP, { ALTIVEC_BUILTIN_VEC_LOGE, ALTIVEC_BUILTIN_VLOGEFP,
@ -444,6 +486,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_TRUNC, ALTIVEC_BUILTIN_VRFIZ, { ALTIVEC_BUILTIN_VEC_TRUNC, ALTIVEC_BUILTIN_VRFIZ,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_TRUNC, VSX_BUILTIN_XVRDPIZ,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB,
RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB,
@ -489,7 +533,7 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB,
RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
/* Binary AltiVec builtins. */ /* Binary AltiVec/VSX builtins. */
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
@ -528,6 +572,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP, { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP, { ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM,
@ -673,9 +719,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
@ -727,9 +773,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
@ -812,6 +858,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP, { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPEQ, VSX_BUILTIN_XVCMPEQDP,
RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VCMPEQFP, ALTIVEC_BUILTIN_VCMPEQFP, { ALTIVEC_BUILTIN_VEC_VCMPEQFP, ALTIVEC_BUILTIN_VCMPEQFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
@ -832,6 +880,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_CMPGE, ALTIVEC_BUILTIN_VCMPGEFP, { ALTIVEC_BUILTIN_VEC_CMPGE, ALTIVEC_BUILTIN_VCMPGEFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_XVCMPGEDP,
RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUB, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUB,
RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSB, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSB,
@ -846,6 +896,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP, { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPGT, VSX_BUILTIN_XVCMPGTDP,
RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VCMPGTFP, ALTIVEC_BUILTIN_VCMPGTFP, { ALTIVEC_BUILTIN_VEC_VCMPGTFP, ALTIVEC_BUILTIN_VCMPGTFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW,
@ -874,6 +926,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VCMPGEFP, { ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VCMPGEFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_XVCMPGEDP,
RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUB, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUB,
RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSB, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSB,
@ -888,6 +942,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP, { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP,
RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CMPLT, VSX_BUILTIN_XVCMPGTDP,
RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_COPYSIGN, VSX_BUILTIN_CPSGNDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_COPYSIGN, ALTIVEC_BUILTIN_COPYSIGN_V4SF,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFUX, { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFUX,
RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 },
{ ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX, { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX,
@ -900,6 +960,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 },
{ ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS, { ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 },
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVSP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX,
RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX,
@ -1234,6 +1298,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP, { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP, { ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW,
@ -1410,6 +1476,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP, { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP, { ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW,
@ -1460,6 +1528,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
{ VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULSP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB, { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB, { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB,
@ -1492,6 +1564,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_VMULOUB, ALTIVEC_BUILTIN_VMULOUB, { ALTIVEC_BUILTIN_VEC_VMULOUB, ALTIVEC_BUILTIN_VMULOUB,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRDPI,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRSPI,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
@ -1523,9 +1599,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
@ -1622,6 +1698,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS, { ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
{ ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRDPIC,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRSPIC,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB,
RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
{ ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB,
@ -1658,6 +1738,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTSP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 },
{ ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW,
@ -1984,6 +2068,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP, { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP, { ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM,
@ -2145,9 +2231,9 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
@ -2191,7 +2277,7 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
/* Ternary AltiVec builtins. */ /* Ternary AltiVec/VSX builtins. */
{ ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI },
{ ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
@ -2354,6 +2440,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI },
{ ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMADDFP, { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VEC_MADD, VSX_BUILTIN_XVMADDDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ ALTIVEC_BUILTIN_VEC_MADDS, ALTIVEC_BUILTIN_VMHADDSHS, { ALTIVEC_BUILTIN_VEC_MADDS, ALTIVEC_BUILTIN_VMHADDSHS,
RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI },
{ ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM,
@ -2366,6 +2454,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI },
{ ALTIVEC_BUILTIN_VEC_MRADDS, ALTIVEC_BUILTIN_VMHRADDSHS, { ALTIVEC_BUILTIN_VEC_MRADDS, ALTIVEC_BUILTIN_VMHRADDSHS,
RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI },
{ VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBSP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUBM, { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUBM,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI },
{ ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMMBM, { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMMBM,
@ -2390,8 +2482,14 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI },
{ ALTIVEC_BUILTIN_VEC_VMSUMUHS, ALTIVEC_BUILTIN_VMSUMUHS, { ALTIVEC_BUILTIN_VEC_VMSUMUHS, ALTIVEC_BUILTIN_VMSUMUHS,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI },
{ VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDSP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP, { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VEC_NMSUB, VSX_BUILTIN_XVNMSUBDP,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF, { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI }, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI },
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI,
@ -2812,6 +2910,54 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
{ ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL,
RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF,
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SF,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI,
RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI,
RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
{ VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
RS6000_BTI_NOT_OPAQUE },
/* Predicates. */ /* Predicates. */
{ ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P,
@ -2852,6 +2998,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI },
{ ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTFP_P, { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTFP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VCMPGT_P, VSX_BUILTIN_XVCMPGTDP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, { ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P,
@ -2900,6 +3048,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI },
{ ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P, { ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VCMPEQ_P, VSX_BUILTIN_XVCMPEQDP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
/* cmpge is the same as cmpgt for all cases except floating point. /* cmpge is the same as cmpgt for all cases except floating point.
@ -2943,6 +3093,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI },
{ ALTIVEC_BUILTIN_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P, { ALTIVEC_BUILTIN_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
{ ALTIVEC_BUILTIN_VCMPGE_P, VSX_BUILTIN_XVCMPGEDP_P,
RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
{ (enum rs6000_builtins) 0, (enum rs6000_builtins) 0, 0, 0, 0, 0 } { (enum rs6000_builtins) 0, (enum rs6000_builtins) 0, 0, 0, 0, 0 }
}; };
@ -3064,8 +3216,10 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
const struct altivec_builtin_types *desc; const struct altivec_builtin_types *desc;
unsigned int n; unsigned int n;
if (fcode < ALTIVEC_BUILTIN_OVERLOADED_FIRST if ((fcode < ALTIVEC_BUILTIN_OVERLOADED_FIRST
|| fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST) || fcode > ALTIVEC_BUILTIN_OVERLOADED_LAST)
&& (fcode < VSX_BUILTIN_OVERLOADED_FIRST
|| fcode > VSX_BUILTIN_OVERLOADED_LAST))
return NULL_TREE; return NULL_TREE;
/* For now treat vec_splats and vec_promote as the same. */ /* For now treat vec_splats and vec_promote as the same. */
@ -3105,11 +3259,12 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
&& !INTEGRAL_TYPE_P (type)) && !INTEGRAL_TYPE_P (type))
goto bad; goto bad;
unsigned_p = TYPE_UNSIGNED (type); unsigned_p = TYPE_UNSIGNED (type);
if (type == long_long_unsigned_type_node
|| type == long_long_integer_type_node)
goto bad;
switch (TYPE_MODE (type)) switch (TYPE_MODE (type))
{ {
case DImode:
type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
size = 2;
break;
case SImode: case SImode:
type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
size = 4; size = 4;
@ -3123,6 +3278,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
size = 16; size = 16;
break; break;
case SFmode: type = V4SF_type_node; size = 4; break; case SFmode: type = V4SF_type_node; size = 4; break;
case DFmode: type = V2DF_type_node; size = 2; break;
default: default:
goto bad; goto bad;
} }
@ -3139,7 +3295,8 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
return build_constructor (type, vec); return build_constructor (type, vec);
} }
/* For now use pointer tricks to do the extaction. */ /* For now use pointer tricks to do the extaction, unless we are on VSX
extracting a double from a constant offset. */
if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT) if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT)
{ {
tree arg1; tree arg1;
@ -3148,6 +3305,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
tree arg1_inner_type; tree arg1_inner_type;
tree decl, stmt; tree decl, stmt;
tree innerptrtype; tree innerptrtype;
enum machine_mode mode;
/* No second argument. */ /* No second argument. */
if (nargs != 2) if (nargs != 2)
@ -3164,6 +3322,25 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
goto bad; goto bad;
if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
goto bad; goto bad;
/* If we can use the VSX xxpermdi instruction, use that for extract. */
mode = TYPE_MODE (arg1_type);
if ((mode == V2DFmode || mode == V2DImode) && VECTOR_MEM_VSX_P (mode)
&& TREE_CODE (arg2) == INTEGER_CST
&& TREE_INT_CST_HIGH (arg2) == 0
&& (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1))
{
tree call = NULL_TREE;
if (mode == V2DFmode)
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
else if (mode == V2DImode)
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
if (call)
return build_call_expr (call, 2, arg1, arg2);
}
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */ /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */
arg1_inner_type = TREE_TYPE (arg1_type); arg1_inner_type = TREE_TYPE (arg1_type);
arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,
@ -3193,7 +3370,8 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
return stmt; return stmt;
} }
/* For now use pointer tricks to do the insertation. */ /* For now use pointer tricks to do the insertation, unless we are on VSX
inserting a double to a constant offset.. */
if (fcode == ALTIVEC_BUILTIN_VEC_INSERT) if (fcode == ALTIVEC_BUILTIN_VEC_INSERT)
{ {
tree arg0; tree arg0;
@ -3203,6 +3381,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
tree arg1_inner_type; tree arg1_inner_type;
tree decl, stmt; tree decl, stmt;
tree innerptrtype; tree innerptrtype;
enum machine_mode mode;
/* No second or third arguments. */ /* No second or third arguments. */
if (nargs != 3) if (nargs != 3)
@ -3220,6 +3399,27 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
goto bad; goto bad;
if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
goto bad; goto bad;
/* If we can use the VSX xxpermdi instruction, use that for insert. */
mode = TYPE_MODE (arg1_type);
if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode)
&& TREE_CODE (arg2) == INTEGER_CST
&& TREE_INT_CST_HIGH (arg2) == 0
&& (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1))
{
tree call = NULL_TREE;
if (mode == V2DFmode)
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF];
else if (mode == V2DImode)
call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DI];
/* Note, __builtin_vec_insert_<xxx> has vector and scalar types
reversed. */
if (call)
return build_call_expr (call, 3, arg1, arg0, arg2);
}
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */ /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */
arg1_inner_type = TREE_TYPE (arg1_type); arg1_inner_type = TREE_TYPE (arg1_type);
arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,

View File

@ -837,6 +837,7 @@ static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
enum machine_mode, bool, bool, bool); enum machine_mode, bool, bool, bool);
static bool rs6000_reg_live_or_pic_offset_p (int); static bool rs6000_reg_live_or_pic_offset_p (int);
static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int); static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
static void rs6000_restore_saved_cr (rtx, int); static void rs6000_restore_saved_cr (rtx, int);
static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT); static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
@ -1395,6 +1396,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_HANDLE_OPTION #undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION rs6000_handle_option #define TARGET_HANDLE_OPTION rs6000_handle_option
#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
rs6000_builtin_vectorized_function
#undef TARGET_DEFAULT_TARGET_FLAGS #undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS \ #define TARGET_DEFAULT_TARGET_FLAGS \
(TARGET_DEFAULT) (TARGET_DEFAULT)
@ -1871,20 +1876,14 @@ rs6000_init_hard_regno_mode_ok (void)
} }
} }
/* V2DImode, prefer vsx over altivec, since the main use will be for /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
vectorized floating point conversions. */ Altivec doesn't have 64-bit support. */
if (TARGET_VSX) if (TARGET_VSX)
{ {
rs6000_vector_mem[V2DImode] = VECTOR_VSX; rs6000_vector_mem[V2DImode] = VECTOR_VSX;
rs6000_vector_unit[V2DImode] = VECTOR_NONE; rs6000_vector_unit[V2DImode] = VECTOR_NONE;
rs6000_vector_align[V2DImode] = align64; rs6000_vector_align[V2DImode] = align64;
} }
else if (TARGET_ALTIVEC)
{
rs6000_vector_mem[V2DImode] = VECTOR_ALTIVEC;
rs6000_vector_unit[V2DImode] = VECTOR_NONE;
rs6000_vector_align[V2DImode] = align64;
}
/* DFmode, see if we want to use the VSX unit. */ /* DFmode, see if we want to use the VSX unit. */
if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE) if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
@ -2169,7 +2168,7 @@ rs6000_override_options (const char *default_cpu)
{"power7", PROCESSOR_POWER7, {"power7", PROCESSOR_POWER7,
POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
| MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
/* | MASK_VSX */}, /* Don't add MASK_ISEL by default */ | MASK_VSX}, /* Don't add MASK_ISEL by default */
{"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK}, {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
{"powerpc64", PROCESSOR_POWERPC64, {"powerpc64", PROCESSOR_POWERPC64,
POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
@ -2765,6 +2764,14 @@ rs6000_builtin_conversion (unsigned int tcode, tree type)
case FIX_TRUNC_EXPR: case FIX_TRUNC_EXPR:
switch (TYPE_MODE (type)) switch (TYPE_MODE (type))
{ {
case V2DImode:
if (!VECTOR_UNIT_VSX_P (V2DFmode))
return NULL_TREE;
return TYPE_UNSIGNED (type)
? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
: rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
case V4SImode: case V4SImode:
if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
return NULL_TREE; return NULL_TREE;
@ -2780,6 +2787,14 @@ rs6000_builtin_conversion (unsigned int tcode, tree type)
case FLOAT_EXPR: case FLOAT_EXPR:
switch (TYPE_MODE (type)) switch (TYPE_MODE (type))
{ {
case V2DImode:
if (!VECTOR_UNIT_VSX_P (V2DFmode))
return NULL_TREE;
return TYPE_UNSIGNED (type)
? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
: rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
case V4SImode: case V4SImode:
if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
return NULL_TREE; return NULL_TREE;
@ -2908,6 +2923,22 @@ rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF]; d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
break; break;
case V2DFmode:
if (!TARGET_ALLOW_DF_PERMUTE)
return NULL_TREE;
d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
break;
case V2DImode:
if (!TARGET_ALLOW_DF_PERMUTE)
return NULL_TREE;
d = (uns_p
? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
: rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
break;
default: default:
return NULL_TREE; return NULL_TREE;
} }
@ -2981,6 +3012,136 @@ rs6000_parse_fpu_option (const char *option)
return FPU_NONE; return FPU_NONE;
} }
/* Returns a function decl for a vectorized version of the builtin function
with builtin function code FN and the result vector type TYPE, or NULL_TREE
if it is not available. */
static tree
rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
tree type_in)
{
enum machine_mode in_mode, out_mode;
int in_n, out_n;
if (TREE_CODE (type_out) != VECTOR_TYPE
|| TREE_CODE (type_in) != VECTOR_TYPE
|| !TARGET_VECTORIZE_BUILTINS)
return NULL_TREE;
out_mode = TYPE_MODE (TREE_TYPE (type_out));
out_n = TYPE_VECTOR_SUBPARTS (type_out);
in_mode = TYPE_MODE (TREE_TYPE (type_in));
in_n = TYPE_VECTOR_SUBPARTS (type_in);
switch (fn)
{
case BUILT_IN_COPYSIGN:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
break;
case BUILT_IN_COPYSIGNF:
if (out_mode != SFmode || out_n != 4
|| in_mode != SFmode || in_n != 4)
break;
if (VECTOR_UNIT_VSX_P (V4SFmode))
return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
break;
case BUILT_IN_SQRT:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
break;
case BUILT_IN_SQRTF:
if (VECTOR_UNIT_VSX_P (V4SFmode)
&& out_mode == SFmode && out_n == 4
&& in_mode == SFmode && in_n == 4)
return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
break;
case BUILT_IN_CEIL:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
break;
case BUILT_IN_CEILF:
if (out_mode != SFmode || out_n != 4
|| in_mode != SFmode || in_n != 4)
break;
if (VECTOR_UNIT_VSX_P (V4SFmode))
return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
break;
case BUILT_IN_FLOOR:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
break;
case BUILT_IN_FLOORF:
if (out_mode != SFmode || out_n != 4
|| in_mode != SFmode || in_n != 4)
break;
if (VECTOR_UNIT_VSX_P (V4SFmode))
return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
break;
case BUILT_IN_TRUNC:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
break;
case BUILT_IN_TRUNCF:
if (out_mode != SFmode || out_n != 4
|| in_mode != SFmode || in_n != 4)
break;
if (VECTOR_UNIT_VSX_P (V4SFmode))
return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
break;
case BUILT_IN_NEARBYINT:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& flag_unsafe_math_optimizations
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
break;
case BUILT_IN_NEARBYINTF:
if (VECTOR_UNIT_VSX_P (V4SFmode)
&& flag_unsafe_math_optimizations
&& out_mode == SFmode && out_n == 4
&& in_mode == SFmode && in_n == 4)
return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
break;
case BUILT_IN_RINT:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& !flag_trapping_math
&& out_mode == DFmode && out_n == 2
&& in_mode == DFmode && in_n == 2)
return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
break;
case BUILT_IN_RINTF:
if (VECTOR_UNIT_VSX_P (V4SFmode)
&& !flag_trapping_math
&& out_mode == SFmode && out_n == 4
&& in_mode == SFmode && in_n == 4)
return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
break;
default:
break;
}
return NULL_TREE;
}
/* Implement TARGET_HANDLE_OPTION. */ /* Implement TARGET_HANDLE_OPTION. */
static bool static bool
@ -3621,6 +3782,11 @@ vspltis_constant (rtx op, unsigned step, unsigned copies)
&& (splat_val >= 0 || (step == 1 && copies == 1))) && (splat_val >= 0 || (step == 1 && copies == 1)))
; ;
/* Also check if are loading up the most significant bit which can be done by
loading up -1 and shifting the value left by -1. */
else if (EASY_VECTOR_MSB (splat_val, inner))
;
else else
return false; return false;
@ -3971,8 +4137,6 @@ rs6000_expand_vector_init (rtx target, rtx vals)
emit_insn (gen_rtx_SET (VOIDmode, target, const_vec)); emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
return; return;
} }
else if (all_same && int_vector_p)
; /* Splat vector element. */
else else
{ {
/* Load from constant pool. */ /* Load from constant pool. */
@ -3981,8 +4145,66 @@ rs6000_expand_vector_init (rtx target, rtx vals)
} }
} }
/* Store value to stack temp. Load vector element. Splat. */ /* Double word values on VSX can use xxpermdi or lxvdsx. */
if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
{
if (all_same) if (all_same)
{
rtx element = XVECEXP (vals, 0, 0);
if (mode == V2DFmode)
emit_insn (gen_vsx_splat_v2df (target, element));
else
emit_insn (gen_vsx_splat_v2di (target, element));
}
else
{
rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
if (mode == V2DFmode)
emit_insn (gen_vsx_concat_v2df (target, op0, op1));
else
emit_insn (gen_vsx_concat_v2di (target, op0, op1));
}
return;
}
/* With single precision floating point on VSX, know that internally single
precision is actually represented as a double, and either make 2 V2DF
vectors, and convert these vectors to single precision, or do one
conversion, and splat the result to the other elements. */
if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
{
if (all_same)
{
rtx freg = gen_reg_rtx (V4SFmode);
rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
}
else
{
rtx dbl_even = gen_reg_rtx (V2DFmode);
rtx dbl_odd = gen_reg_rtx (V2DFmode);
rtx flt_even = gen_reg_rtx (V4SFmode);
rtx flt_odd = gen_reg_rtx (V4SFmode);
emit_insn (gen_vsx_concat_v2sf (dbl_even,
copy_to_reg (XVECEXP (vals, 0, 0)),
copy_to_reg (XVECEXP (vals, 0, 1))));
emit_insn (gen_vsx_concat_v2sf (dbl_odd,
copy_to_reg (XVECEXP (vals, 0, 2)),
copy_to_reg (XVECEXP (vals, 0, 3))));
emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
}
return;
}
/* Store value to stack temp. Load vector element. Splat. However, splat
of 64-bit items is not supported on Altivec. */
if (all_same && GET_MODE_SIZE (mode) <= 4)
{ {
mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
emit_move_insn (adjust_address_nv (mem, inner_mode, 0), emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
@ -4040,6 +4262,14 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt)
int width = GET_MODE_SIZE (inner_mode); int width = GET_MODE_SIZE (inner_mode);
int i; int i;
if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
{
rtx (*set_func) (rtx, rtx, rtx, rtx)
= ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
emit_insn (set_func (target, target, val, GEN_INT (elt)));
return;
}
/* Load single variable value. */ /* Load single variable value. */
mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val); emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
@ -4077,6 +4307,14 @@ rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
enum machine_mode inner_mode = GET_MODE_INNER (mode); enum machine_mode inner_mode = GET_MODE_INNER (mode);
rtx mem, x; rtx mem, x;
if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
{
rtx (*extract_func) (rtx, rtx, rtx)
= ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
emit_insn (extract_func (target, vec, GEN_INT (elt)));
return;
}
/* Allocate mode-sized buffer. */ /* Allocate mode-sized buffer. */
mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
@ -5447,6 +5685,10 @@ rs6000_mode_dependent_address (rtx addr)
case PRE_MODIFY: case PRE_MODIFY:
return TARGET_UPDATE; return TARGET_UPDATE;
/* AND is only allowed in Altivec loads. */
case AND:
return true;
default: default:
break; break;
} }
@ -6048,6 +6290,8 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
case V2SFmode: case V2SFmode:
case V2SImode: case V2SImode:
case V1DImode: case V1DImode:
case V2DFmode:
case V2DImode:
if (CONSTANT_P (operands[1]) if (CONSTANT_P (operands[1])
&& !easy_vector_constant (operands[1], mode)) && !easy_vector_constant (operands[1], mode))
operands[1] = force_const_mem (mode, operands[1]); operands[1] = force_const_mem (mode, operands[1]);
@ -8192,6 +8436,59 @@ static const struct builtin_description bdesc_3arg[] =
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
{ MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
{ MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
{ MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
{ MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
{ MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
{ MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
{ MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
{ MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
{ MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
{ MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
{ MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
{ MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
{ MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
{ MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
{ MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
{ MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
{ MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
{ MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
{ MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
{ MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
{ MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
{ MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
{ MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
{ MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
{ MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
{ MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
{ MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
{ MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
{ MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
{ MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
{ MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
{ MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
{ 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB }, { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
{ 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD }, { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
{ 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 }, { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
@ -8337,9 +8634,50 @@ static struct builtin_description bdesc_2arg[] =
{ MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS }, { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS }, { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
{ MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR }, { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
{ MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
{ MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
{ MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
{ MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
{ MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
{ MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
{ MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
{ MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
{ MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
{ MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
{ MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
{ MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
{ MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
{ MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
{ MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
{ MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
{ MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
{ MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
{ MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
{ MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
{ MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
{ MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
{ MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
{ MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
{ MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
{ MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
{ MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
{ MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
{ MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
{ MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
{ MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
{ MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
{ MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
{ MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
{ MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
@ -8377,6 +8715,7 @@ static struct builtin_description bdesc_2arg[] =
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
@ -8466,6 +8805,9 @@ static struct builtin_description bdesc_2arg[] =
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
{ 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 }, { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
{ 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 }, { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
{ 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 }, { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
@ -8661,6 +9003,19 @@ static const struct builtin_description_predicates bdesc_altivec_preds[] =
{ MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p", { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
ALTIVEC_BUILTIN_VCMPGTUB_P }, ALTIVEC_BUILTIN_VCMPGTUB_P },
{ MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
VSX_BUILTIN_XVCMPEQSP_P },
{ MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
VSX_BUILTIN_XVCMPGESP_P },
{ MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
VSX_BUILTIN_XVCMPGTSP_P },
{ MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
VSX_BUILTIN_XVCMPEQDP_P },
{ MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
VSX_BUILTIN_XVCMPGEDP_P },
{ MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
VSX_BUILTIN_XVCMPGTDP_P },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p", { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
ALTIVEC_BUILTIN_VCMPEQ_P }, ALTIVEC_BUILTIN_VCMPEQ_P },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p", { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
@ -8724,7 +9079,11 @@ static const struct builtin_description bdesc_abs[] =
{ MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI }, { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI }, { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI }, { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI } { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
{ MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
{ MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
{ MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
{ MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
}; };
/* Simple unary operations: VECb = foo (unsigned literal) or VECb = /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
@ -8735,10 +9094,10 @@ static struct builtin_description bdesc_1arg[] =
{ MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM }, { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN }, { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP }, { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
{ MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ }, { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP }, { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB }, { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH }, { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
@ -8750,6 +9109,65 @@ static struct builtin_description bdesc_1arg[] =
{ MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX }, { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
{ MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH }, { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
{ MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
{ MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
{ MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
{ MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
{ MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
{ MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
{ MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
{ MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
{ MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
{ MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
{ MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
{ MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
{ MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
{ MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
{ MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
{ MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
{ MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
{ MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
{ MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
{ MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
{ MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
{ MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
{ MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
{ MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
{ MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
{ MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
{ MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
{ MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
{ MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
{ MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
{ MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
{ MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
{ MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
{ MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
{ MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
{ MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
{ MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
{ MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
{ MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
{ MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
{ MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
{ MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
{ MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
{ MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
{ MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
{ MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
{ MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
{ MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
{ MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
{ MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
{ MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
@ -8770,6 +9188,10 @@ static struct builtin_description bdesc_1arg[] =
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
{ MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
{ MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
{ MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI }, { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
@ -9293,6 +9715,36 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
} }
break; break;
case CODE_FOR_vsx_xxpermdi_v2df:
case CODE_FOR_vsx_xxpermdi_v2di:
case CODE_FOR_vsx_xxsldwi_v16qi:
case CODE_FOR_vsx_xxsldwi_v8hi:
case CODE_FOR_vsx_xxsldwi_v4si:
case CODE_FOR_vsx_xxsldwi_v4sf:
case CODE_FOR_vsx_xxsldwi_v2di:
case CODE_FOR_vsx_xxsldwi_v2df:
/* Only allow 2-bit unsigned literals. */
STRIP_NOPS (arg2);
if (TREE_CODE (arg2) != INTEGER_CST
|| TREE_INT_CST_LOW (arg2) & ~0x3)
{
error ("argument 3 must be a 2-bit unsigned literal");
return const0_rtx;
}
break;
case CODE_FOR_vsx_set_v2df:
case CODE_FOR_vsx_set_v2di:
/* Only allow 1-bit unsigned literals. */
STRIP_NOPS (arg2);
if (TREE_CODE (arg2) != INTEGER_CST
|| TREE_INT_CST_LOW (arg2) & ~0x1)
{
error ("argument 3 must be a 1-bit unsigned literal");
return const0_rtx;
}
break;
default: default:
break; break;
} }
@ -9602,8 +10054,10 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
enum machine_mode tmode, mode0; enum machine_mode tmode, mode0;
unsigned int fcode = DECL_FUNCTION_CODE (fndecl); unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST) && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
|| (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
&& fcode <= VSX_BUILTIN_OVERLOADED_LAST))
{ {
*expandedp = true; *expandedp = true;
error ("unresolved overload for Altivec builtin %qF", fndecl); error ("unresolved overload for Altivec builtin %qF", fndecl);
@ -9711,18 +10165,24 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
case ALTIVEC_BUILTIN_VEC_INIT_V8HI: case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
case ALTIVEC_BUILTIN_VEC_INIT_V16QI: case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
case ALTIVEC_BUILTIN_VEC_INIT_V4SF: case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
case VSX_BUILTIN_VEC_INIT_V2DF:
case VSX_BUILTIN_VEC_INIT_V2DI:
return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
case ALTIVEC_BUILTIN_VEC_SET_V4SI: case ALTIVEC_BUILTIN_VEC_SET_V4SI:
case ALTIVEC_BUILTIN_VEC_SET_V8HI: case ALTIVEC_BUILTIN_VEC_SET_V8HI:
case ALTIVEC_BUILTIN_VEC_SET_V16QI: case ALTIVEC_BUILTIN_VEC_SET_V16QI:
case ALTIVEC_BUILTIN_VEC_SET_V4SF: case ALTIVEC_BUILTIN_VEC_SET_V4SF:
case VSX_BUILTIN_VEC_SET_V2DF:
case VSX_BUILTIN_VEC_SET_V2DI:
return altivec_expand_vec_set_builtin (exp); return altivec_expand_vec_set_builtin (exp);
case ALTIVEC_BUILTIN_VEC_EXT_V4SI: case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
case ALTIVEC_BUILTIN_VEC_EXT_V8HI: case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
case ALTIVEC_BUILTIN_VEC_EXT_V16QI: case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
case ALTIVEC_BUILTIN_VEC_EXT_V4SF: case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
case VSX_BUILTIN_VEC_EXT_V2DF:
case VSX_BUILTIN_VEC_EXT_V2DI:
return altivec_expand_vec_ext_builtin (exp, target); return altivec_expand_vec_ext_builtin (exp, target);
default: default:
@ -10245,6 +10705,11 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (fcode == RS6000_BUILTIN_BSWAP_HI) if (fcode == RS6000_BUILTIN_BSWAP_HI)
return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target); return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
if (fcode == POWER7_BUILTIN_BPERMD)
return rs6000_expand_binop_builtin (((TARGET_64BIT)
? CODE_FOR_bpermd_di
: CODE_FOR_bpermd_si), exp, target);
if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
|| fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
{ {
@ -10500,6 +10965,33 @@ rs6000_init_builtins (void)
TYPE_NAME (pixel_V8HI_type_node) = tdecl; TYPE_NAME (pixel_V8HI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl); (*lang_hooks.decls.pushdecl) (tdecl);
if (TARGET_VSX)
{
tdecl = build_decl (BUILTINS_LOCATION,
TYPE_DECL, get_identifier ("__vector double"),
unsigned_V2DI_type_node);
TYPE_NAME (V2DF_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
tdecl = build_decl (BUILTINS_LOCATION,
TYPE_DECL, get_identifier ("__vector long"),
V2DI_type_node);
TYPE_NAME (V2DI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
tdecl = build_decl (BUILTINS_LOCATION,
TYPE_DECL, get_identifier ("__vector unsigned long"),
unsigned_V2DI_type_node);
TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
tdecl = build_decl (BUILTINS_LOCATION,
TYPE_DECL, get_identifier ("__vector __bool long"),
bool_V2DI_type_node);
TYPE_NAME (bool_V2DI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
}
if (TARGET_PAIRED_FLOAT) if (TARGET_PAIRED_FLOAT)
paired_init_builtins (); paired_init_builtins ();
if (TARGET_SPE) if (TARGET_SPE)
@ -10531,6 +11023,15 @@ rs6000_init_builtins (void)
RS6000_BUILTIN_RECIP); RS6000_BUILTIN_RECIP);
} }
if (TARGET_POPCNTD)
{
enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
POWER7_BUILTIN_BPERMD,
"__builtin_bpermd");
def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
POWER7_BUILTIN_BPERMD);
}
if (TARGET_POWERPC) if (TARGET_POWERPC)
{ {
/* Don't use builtin_function_type here, as it maps HI/QI to SI. */ /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
@ -10969,6 +11470,10 @@ altivec_init_builtins (void)
= build_function_type_list (integer_type_node, = build_function_type_list (integer_type_node,
integer_type_node, V4SF_type_node, integer_type_node, V4SF_type_node,
V4SF_type_node, NULL_TREE); V4SF_type_node, NULL_TREE);
tree int_ftype_int_v2df_v2df
= build_function_type_list (integer_type_node,
integer_type_node, V2DF_type_node,
V2DF_type_node, NULL_TREE);
tree v4si_ftype_v4si tree v4si_ftype_v4si
= build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE); = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
tree v8hi_ftype_v8hi tree v8hi_ftype_v8hi
@ -10977,6 +11482,8 @@ altivec_init_builtins (void)
= build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
tree v4sf_ftype_v4sf tree v4sf_ftype_v4sf
= build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
tree v2df_ftype_v2df
= build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
tree void_ftype_pcvoid_int_int tree void_ftype_pcvoid_int_int
= build_function_type_list (void_type_node, = build_function_type_list (void_type_node,
pcvoid_type_node, integer_type_node, pcvoid_type_node, integer_type_node,
@ -11079,8 +11586,10 @@ altivec_init_builtins (void)
{ {
enum machine_mode mode1; enum machine_mode mode1;
tree type; tree type;
bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST; && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
|| (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
&& dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
if (is_overloaded) if (is_overloaded)
mode1 = VOIDmode; mode1 = VOIDmode;
@ -11104,6 +11613,9 @@ altivec_init_builtins (void)
case V4SFmode: case V4SFmode:
type = int_ftype_int_v4sf_v4sf; type = int_ftype_int_v4sf_v4sf;
break; break;
case V2DFmode:
type = int_ftype_int_v2df_v2df;
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
@ -11134,6 +11646,9 @@ altivec_init_builtins (void)
case V4SFmode: case V4SFmode:
type = v4sf_ftype_v4sf; type = v4sf_ftype_v4sf;
break; break;
case V2DFmode:
type = v2df_ftype_v2df;
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
@ -11193,6 +11708,19 @@ altivec_init_builtins (void)
def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype, def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
ALTIVEC_BUILTIN_VEC_INIT_V4SF); ALTIVEC_BUILTIN_VEC_INIT_V4SF);
if (TARGET_VSX)
{
ftype = build_function_type_list (V2DF_type_node, double_type_node,
double_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
VSX_BUILTIN_VEC_INIT_V2DF);
ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
intDI_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
VSX_BUILTIN_VEC_INIT_V2DI);
}
/* Access to the vec_set patterns. */ /* Access to the vec_set patterns. */
ftype = build_function_type_list (V4SI_type_node, V4SI_type_node, ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
intSI_type_node, intSI_type_node,
@ -11218,6 +11746,21 @@ altivec_init_builtins (void)
def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype, def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
ALTIVEC_BUILTIN_VEC_SET_V4SF); ALTIVEC_BUILTIN_VEC_SET_V4SF);
if (TARGET_VSX)
{
ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
double_type_node,
integer_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
VSX_BUILTIN_VEC_SET_V2DF);
ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
intDI_type_node,
integer_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
VSX_BUILTIN_VEC_SET_V2DI);
}
/* Access to the vec_extract patterns. */ /* Access to the vec_extract patterns. */
ftype = build_function_type_list (intSI_type_node, V4SI_type_node, ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
integer_type_node, NULL_TREE); integer_type_node, NULL_TREE);
@ -11238,6 +11781,19 @@ altivec_init_builtins (void)
integer_type_node, NULL_TREE); integer_type_node, NULL_TREE);
def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype, def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
ALTIVEC_BUILTIN_VEC_EXT_V4SF); ALTIVEC_BUILTIN_VEC_EXT_V4SF);
if (TARGET_VSX)
{
ftype = build_function_type_list (double_type_node, V2DF_type_node,
integer_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
VSX_BUILTIN_VEC_EXT_V2DF);
ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
integer_type_node, NULL_TREE);
def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
VSX_BUILTIN_VEC_EXT_V2DI);
}
} }
/* Hash function for builtin functions with up to 3 arguments and a return /* Hash function for builtin functions with up to 3 arguments and a return
@ -11333,6 +11889,14 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
case ALTIVEC_BUILTIN_VSEL_8HI_UNS: case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
case ALTIVEC_BUILTIN_VSEL_4SI_UNS: case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
case ALTIVEC_BUILTIN_VSEL_2DI_UNS: case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
case VSX_BUILTIN_VPERM_16QI_UNS:
case VSX_BUILTIN_VPERM_8HI_UNS:
case VSX_BUILTIN_VPERM_4SI_UNS:
case VSX_BUILTIN_VPERM_2DI_UNS:
case VSX_BUILTIN_XXSEL_16QI_UNS:
case VSX_BUILTIN_XXSEL_8HI_UNS:
case VSX_BUILTIN_XXSEL_4SI_UNS:
case VSX_BUILTIN_XXSEL_2DI_UNS:
h.uns_p[0] = 1; h.uns_p[0] = 1;
h.uns_p[1] = 1; h.uns_p[1] = 1;
h.uns_p[2] = 1; h.uns_p[2] = 1;
@ -11346,6 +11910,12 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
case ALTIVEC_BUILTIN_VPERM_4SF: case ALTIVEC_BUILTIN_VPERM_4SF:
case ALTIVEC_BUILTIN_VPERM_2DI: case ALTIVEC_BUILTIN_VPERM_2DI:
case ALTIVEC_BUILTIN_VPERM_2DF: case ALTIVEC_BUILTIN_VPERM_2DF:
case VSX_BUILTIN_VPERM_16QI:
case VSX_BUILTIN_VPERM_8HI:
case VSX_BUILTIN_VPERM_4SI:
case VSX_BUILTIN_VPERM_4SF:
case VSX_BUILTIN_VPERM_2DI:
case VSX_BUILTIN_VPERM_2DF:
h.uns_p[3] = 1; h.uns_p[3] = 1;
break; break;
@ -11442,8 +12012,10 @@ rs6000_common_init_builtins (void)
|| (mask == 0 && !TARGET_PAIRED_FLOAT)) || (mask == 0 && !TARGET_PAIRED_FLOAT))
continue; continue;
if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
|| (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
&& d->code <= VSX_BUILTIN_OVERLOADED_LAST))
{ {
if (! (type = opaque_ftype_opaque_opaque_opaque)) if (! (type = opaque_ftype_opaque_opaque_opaque))
type = opaque_ftype_opaque_opaque_opaque type = opaque_ftype_opaque_opaque_opaque
@ -11481,8 +12053,10 @@ rs6000_common_init_builtins (void)
|| (mask == 0 && !TARGET_PAIRED_FLOAT)) || (mask == 0 && !TARGET_PAIRED_FLOAT))
continue; continue;
if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
|| (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
&& d->code <= VSX_BUILTIN_OVERLOADED_LAST))
{ {
if (! (type = opaque_ftype_opaque_opaque)) if (! (type = opaque_ftype_opaque_opaque))
type = opaque_ftype_opaque_opaque type = opaque_ftype_opaque_opaque
@ -11537,14 +12111,15 @@ rs6000_common_init_builtins (void)
enum machine_mode mode0, mode1; enum machine_mode mode0, mode1;
tree type; tree type;
int mask = d->mask; int mask = d->mask;
bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
if ((mask != 0 && (mask & target_flags) == 0) if ((mask != 0 && (mask & target_flags) == 0)
|| (mask == 0 && !TARGET_PAIRED_FLOAT)) || (mask == 0 && !TARGET_PAIRED_FLOAT))
continue; continue;
if (is_overloaded) if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
&& d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
|| (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
&& d->code <= VSX_BUILTIN_OVERLOADED_LAST))
{ {
if (! (type = opaque_ftype_opaque)) if (! (type = opaque_ftype_opaque))
type = opaque_ftype_opaque type = opaque_ftype_opaque
@ -22228,18 +22803,24 @@ rs6000_handle_altivec_attribute (tree *node,
mode = TYPE_MODE (type); mode = TYPE_MODE (type);
/* Check for invalid AltiVec type qualifiers. */ /* Check for invalid AltiVec type qualifiers. */
if (!TARGET_VSX)
{
if (type == long_unsigned_type_node || type == long_integer_type_node) if (type == long_unsigned_type_node || type == long_integer_type_node)
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
error ("use of %<long%> in AltiVec types is invalid for 64-bit code"); error ("use of %<long%> in AltiVec types is invalid for "
"64-bit code without -mvsx");
else if (rs6000_warn_altivec_long) else if (rs6000_warn_altivec_long)
warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>"); warning (0, "use of %<long%> in AltiVec types is deprecated; "
"use %<int%>");
} }
else if (type == long_long_unsigned_type_node else if (type == long_long_unsigned_type_node
|| type == long_long_integer_type_node) || type == long_long_integer_type_node)
error ("use of %<long long%> in AltiVec types is invalid"); error ("use of %<long long%> in AltiVec types is invalid without "
"-mvsx");
else if (type == double_type_node) else if (type == double_type_node)
error ("use of %<double%> in AltiVec types is invalid"); error ("use of %<double%> in AltiVec types is invalid without -mvsx");
}
else if (type == long_double_type_node) else if (type == long_double_type_node)
error ("use of %<long double%> in AltiVec types is invalid"); error ("use of %<long double%> in AltiVec types is invalid");
else if (type == boolean_type_node) else if (type == boolean_type_node)
@ -22255,6 +22836,9 @@ rs6000_handle_altivec_attribute (tree *node,
unsigned_p = TYPE_UNSIGNED (type); unsigned_p = TYPE_UNSIGNED (type);
switch (mode) switch (mode)
{ {
case DImode:
result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
break;
case SImode: case SImode:
result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
break; break;
@ -22265,10 +22849,12 @@ rs6000_handle_altivec_attribute (tree *node,
result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
break; break;
case SFmode: result = V4SF_type_node; break; case SFmode: result = V4SF_type_node; break;
case DFmode: result = V2DF_type_node; break;
/* If the user says 'vector int bool', we may be handed the 'bool' /* If the user says 'vector int bool', we may be handed the 'bool'
attribute _before_ the 'vector' attribute, and so select the attribute _before_ the 'vector' attribute, and so select the
proper type in the 'b' case below. */ proper type in the 'b' case below. */
case V4SImode: case V8HImode: case V16QImode: case V4SFmode: case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
case V2DImode: case V2DFmode:
result = type; result = type;
default: break; default: break;
} }
@ -22276,6 +22862,7 @@ rs6000_handle_altivec_attribute (tree *node,
case 'b': case 'b':
switch (mode) switch (mode)
{ {
case DImode: case V2DImode: result = bool_V2DI_type_node; break;
case SImode: case V4SImode: result = bool_V4SI_type_node; break; case SImode: case V4SImode: result = bool_V4SI_type_node; break;
case HImode: case V8HImode: result = bool_V8HI_type_node; break; case HImode: case V8HImode: result = bool_V8HI_type_node; break;
case QImode: case V16QImode: result = bool_V16QI_type_node; case QImode: case V16QImode: result = bool_V16QI_type_node;
@ -22320,6 +22907,7 @@ rs6000_mangle_type (const_tree type)
if (type == bool_short_type_node) return "U6__bools"; if (type == bool_short_type_node) return "U6__bools";
if (type == pixel_type_node) return "u7__pixel"; if (type == pixel_type_node) return "u7__pixel";
if (type == bool_int_type_node) return "U6__booli"; if (type == bool_int_type_node) return "U6__booli";
if (type == bool_long_type_node) return "U6__booll";
/* Mangle IBM extended float long double as `g' (__float128) on /* Mangle IBM extended float long double as `g' (__float128) on
powerpc*-linux where long-double-64 previously was the default. */ powerpc*-linux where long-double-64 previously was the default. */
@ -24557,7 +25145,7 @@ rs6000_vector_mode_supported_p (enum machine_mode mode)
if (TARGET_SPE && SPE_VECTOR_MODE (mode)) if (TARGET_SPE && SPE_VECTOR_MODE (mode))
return true; return true;
else if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)) else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
return true; return true;
else else

View File

@ -1883,6 +1883,10 @@ typedef struct rs6000_args
&& EASY_VECTOR_15((n) >> 1) \ && EASY_VECTOR_15((n) >> 1) \
&& ((n) & 1) == 0) && ((n) & 1) == 0)
#define EASY_VECTOR_MSB(n,mode) \
(((unsigned HOST_WIDE_INT)n) == \
((((unsigned HOST_WIDE_INT)GET_MODE_MASK (mode)) + 1) >> 1))
/* Try a machine-dependent way of reloading an illegitimate address /* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This operand. If we find one, push the reload and jump to WIN. This
@ -2678,6 +2682,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_EXT_V8HI, ALTIVEC_BUILTIN_VEC_EXT_V8HI,
ALTIVEC_BUILTIN_VEC_EXT_V16QI, ALTIVEC_BUILTIN_VEC_EXT_V16QI,
ALTIVEC_BUILTIN_VEC_EXT_V4SF, ALTIVEC_BUILTIN_VEC_EXT_V4SF,
ALTIVEC_BUILTIN_COPYSIGN_V4SF,
/* Altivec overloaded builtins. */ /* Altivec overloaded builtins. */
ALTIVEC_BUILTIN_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQ_P,
@ -2703,6 +2708,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VEC_CMPGT,
ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VEC_CMPLE,
ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VEC_CMPLT,
ALTIVEC_BUILTIN_VEC_COPYSIGN,
ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VEC_CTF,
ALTIVEC_BUILTIN_VEC_CTS, ALTIVEC_BUILTIN_VEC_CTS,
ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VEC_CTU,
@ -2745,6 +2751,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_VEC_MTVSCR,
ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VEC_MULE,
ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VEC_MULO,
ALTIVEC_BUILTIN_VEC_NEARBYINT,
ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VEC_NMSUB,
ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VEC_NOR,
ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VEC_OR,
@ -2755,6 +2762,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VEC_PERM,
ALTIVEC_BUILTIN_VEC_RE, ALTIVEC_BUILTIN_VEC_RE,
ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VEC_RL,
ALTIVEC_BUILTIN_VEC_RINT,
ALTIVEC_BUILTIN_VEC_ROUND, ALTIVEC_BUILTIN_VEC_ROUND,
ALTIVEC_BUILTIN_VEC_RSQRTE, ALTIVEC_BUILTIN_VEC_RSQRTE,
ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VEC_SEL,
@ -2772,6 +2780,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_SPLTB, ALTIVEC_BUILTIN_VEC_SPLTB,
ALTIVEC_BUILTIN_VEC_SPLTH, ALTIVEC_BUILTIN_VEC_SPLTH,
ALTIVEC_BUILTIN_VEC_SPLTW, ALTIVEC_BUILTIN_VEC_SPLTW,
ALTIVEC_BUILTIN_VEC_SQRT,
ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VEC_SR,
ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VEC_SRA,
ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VEC_SRL,
@ -3228,6 +3237,8 @@ enum rs6000_builtins
VSX_BUILTIN_XSRSQRTEDP, VSX_BUILTIN_XSRSQRTEDP,
VSX_BUILTIN_XSSQRTDP, VSX_BUILTIN_XSSQRTDP,
VSX_BUILTIN_XSSUBDP, VSX_BUILTIN_XSSUBDP,
VSX_BUILTIN_CPSGNDP,
VSX_BUILTIN_CPSGNSP,
VSX_BUILTIN_XSTDIVDP_FE, VSX_BUILTIN_XSTDIVDP_FE,
VSX_BUILTIN_XSTDIVDP_FG, VSX_BUILTIN_XSTDIVDP_FG,
VSX_BUILTIN_XSTSQRTDP_FE, VSX_BUILTIN_XSTSQRTDP_FE,

View File

@ -101,6 +101,7 @@
(UNSPEC_RSQRT 48) (UNSPEC_RSQRT 48)
(UNSPEC_TOCREL 49) (UNSPEC_TOCREL 49)
(UNSPEC_MACHOPIC_OFFSET 50) (UNSPEC_MACHOPIC_OFFSET 50)
(UNSPEC_BPERM 51)
]) ])
;; ;;
@ -167,6 +168,7 @@
(include "power4.md") (include "power4.md")
(include "power5.md") (include "power5.md")
(include "power6.md") (include "power6.md")
(include "power7.md")
(include "cell.md") (include "cell.md")
(include "xfpu.md") (include "xfpu.md")
@ -5900,9 +5902,18 @@
(match_dup 5)) (match_dup 5))
(match_dup 3) (match_dup 3)
(match_dup 4)))] (match_dup 4)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)" && ((TARGET_PPC_GFXOPT
&& !HONOR_NANS (DFmode)
&& !HONOR_SIGNED_ZEROS (DFmode))
|| VECTOR_UNIT_VSX_P (DFmode))"
{ {
if (VECTOR_UNIT_VSX_P (DFmode))
{
emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1],
operands[2], CONST0_RTX (DFmode)));
DONE;
}
operands[3] = gen_reg_rtx (DFmode); operands[3] = gen_reg_rtx (DFmode);
operands[4] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (DFmode);
operands[5] = CONST0_RTX (DFmode); operands[5] = CONST0_RTX (DFmode);
@ -6037,7 +6048,8 @@
(define_insn "*negdf2_fpr" (define_insn "*negdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fneg %0,%1" "fneg %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -6050,14 +6062,16 @@
(define_insn "*absdf2_fpr" (define_insn "*absdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fabs %0,%1" "fabs %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "*nabsdf2_fpr" (define_insn "*nabsdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))] (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fnabs %0,%1" "fnabs %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -6072,7 +6086,8 @@
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))] (match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"{fa|fadd} %0,%1,%2" "{fa|fadd} %0,%1,%2"
[(set_attr "type" "fp") [(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")]) (set_attr "fp_type" "fp_addsub_d")])
@ -6088,7 +6103,8 @@
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "d") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))] (match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"{fs|fsub} %0,%1,%2" "{fs|fsub} %0,%1,%2"
[(set_attr "type" "fp") [(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")]) (set_attr "fp_type" "fp_addsub_d")])
@ -6104,7 +6120,8 @@
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))] (match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"{fm|fmul} %0,%1,%2" "{fm|fmul} %0,%1,%2"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_mul_d")]) (set_attr "fp_type" "fp_mul_d")])
@ -6122,7 +6139,8 @@
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "d") (div:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))] (match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
&& !VECTOR_UNIT_VSX_P (DFmode)"
"{fd|fdiv} %0,%1,%2" "{fd|fdiv} %0,%1,%2"
[(set_attr "type" "ddiv")]) [(set_attr "type" "ddiv")])
@ -6138,73 +6156,81 @@
DONE; DONE;
}) })
(define_insn "fred" (define_expand "fred"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))] (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))]
"TARGET_POPCNTB && flag_finite_math_only" "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only"
"")
(define_insn "*fred_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
"TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)"
"fre %0,%1" "fre %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "" (define_insn "*fmadddf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d"))
(match_operand:DF 3 "gpc_reg_operand" "d")))] (match_operand:DF 3 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"{fma|fmadd} %0,%1,%2,%3" "{fma|fmadd} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
(define_insn "" (define_insn "*fmsubdf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d"))
(match_operand:DF 3 "gpc_reg_operand" "d")))] (match_operand:DF 3 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_NONE_P (DFmode)"
"{fms|fmsub} %0,%1,%2,%3" "{fms|fmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
(define_insn "" (define_insn "*fnmadddf4_fpr_1"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d"))
(match_operand:DF 3 "gpc_reg_operand" "d"))))] (match_operand:DF 3 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& HONOR_SIGNED_ZEROS (DFmode)" && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
"{fnma|fnmadd} %0,%1,%2,%3" "{fnma|fnmadd} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
(define_insn "" (define_insn "*fnmadddf4_fpr_2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")) (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d"))
(match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d"))
(match_operand:DF 3 "gpc_reg_operand" "d")))] (match_operand:DF 3 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& ! HONOR_SIGNED_ZEROS (DFmode)" && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
"{fnma|fnmadd} %0,%1,%2,%3" "{fnma|fnmadd} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
(define_insn "" (define_insn "*fnmsubdf4_fpr_1"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")) (match_operand:DF 2 "gpc_reg_operand" "d"))
(match_operand:DF 3 "gpc_reg_operand" "d"))))] (match_operand:DF 3 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& HONOR_SIGNED_ZEROS (DFmode)" && HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
"{fnms|fnmsub} %0,%1,%2,%3" "{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
(define_insn "" (define_insn "*fnmsubdf4_fpr_2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (match_operand:DF 3 "gpc_reg_operand" "d") (minus:DF (match_operand:DF 3 "gpc_reg_operand" "d")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d"))))] (match_operand:DF 2 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
&& ! HONOR_SIGNED_ZEROS (DFmode)" && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
"{fnms|fnmsub} %0,%1,%2,%3" "{fnms|fnmsub} %0,%1,%2,%3"
[(set_attr "type" "dmul") [(set_attr "type" "dmul")
(set_attr "fp_type" "fp_maddsub_d")]) (set_attr "fp_type" "fp_maddsub_d")])
@ -6213,7 +6239,8 @@
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_DOUBLE_FLOAT" && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fsqrt %0,%1" "fsqrt %0,%1"
[(set_attr "type" "dsqrt")]) [(set_attr "type" "dsqrt")])
@ -6308,6 +6335,12 @@
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
"") "")
(define_expand "fixuns_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_VSX"
"")
; For each of these conversions, there is a define_expand, a define_insn ; For each of these conversions, there is a define_expand, a define_insn
; with a '#' template, and a define_split (with C code). The idea is ; with a '#' template, and a define_split (with C code). The idea is
; to allow constant folding with the template of the define_insn, ; to allow constant folding with the template of the define_insn,
@ -6549,10 +6582,17 @@
"{fcirz|fctiwz} %0,%1" "{fcirz|fctiwz} %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "btruncdf2" (define_expand "btruncdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))] (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"")
(define_insn "*btruncdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"friz %0,%1" "friz %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -6563,10 +6603,17 @@
"friz %0,%1" "friz %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "ceildf2" (define_expand "ceildf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"")
(define_insn "*ceildf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))] (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"frip %0,%1" "frip %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -6577,10 +6624,17 @@
"frip %0,%1" "frip %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "floordf2" (define_expand "floordf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"")
(define_insn "*floordf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))] (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"frim %0,%1" "frim %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -6591,6 +6645,7 @@
"frim %0,%1" "frim %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
;; No VSX equivalent to frin
(define_insn "rounddf2" (define_insn "rounddf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))] (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))]
@ -6605,6 +6660,12 @@
"frin %0,%1" "frin %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_expand "ftruncdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"VECTOR_UNIT_VSX_P (DFmode)"
"")
; An UNSPEC is used so we don't have to support SImode in FP registers. ; An UNSPEC is used so we don't have to support SImode in FP registers.
(define_insn "stfiwx" (define_insn "stfiwx"
[(set (match_operand:SI 0 "memory_operand" "=Z") [(set (match_operand:SI 0 "memory_operand" "=Z")
@ -6620,17 +6681,40 @@
"TARGET_HARD_FLOAT && !TARGET_FPRS" "TARGET_HARD_FLOAT && !TARGET_FPRS"
"") "")
(define_insn "floatdidf2" (define_expand "floatdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
"(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
"")
(define_insn "*floatdidf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d") [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))]
"(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "(TARGET_POWERPC64 || TARGET_XILINX_FPU)
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fcfid %0,%1" "fcfid %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "fix_truncdfdi2" (define_expand "floatunsdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
"TARGET_VSX"
"")
(define_expand "fix_truncdfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))]
"(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
"")
(define_insn "*fix_truncdfdi2_fpr"
[(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r")
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))]
"(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)"
"fctidz %0,%1" "fctidz %0,%1"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
@ -8956,8 +9040,8 @@
;; The "??" is a kludge until we can figure out a more reasonable way ;; The "??" is a kludge until we can figure out a more reasonable way
;; of handling these non-offsettable values. ;; of handling these non-offsettable values.
(define_insn "*movdf_hardfloat32" (define_insn "*movdf_hardfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r") [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,!r,!r,!r")
(match_operand:DF 1 "input_operand" "r,m,r,d,m,d,G,H,F"))] (match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,d,m,d,j,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], DFmode) && (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))" || gpc_reg_operand (operands[1], DFmode))"
@ -9036,19 +9120,30 @@
return \"\"; return \"\";
} }
case 3: case 3:
return \"fmr %0,%1\";
case 4: case 4:
return \"lfd%U1%X1 %0,%1\"; return \"xxlor %x0,%x1,%x1\";
case 5: case 5:
return \"stfd%U0%X0 %1,%0\";
case 6: case 6:
return \"lxsd%U1x %x0,%y1\";
case 7: case 7:
case 8: case 8:
return \"stxsd%U0x %x1,%y0\";
case 9:
return \"fmr %0,%1\";
case 10:
return \"lfd%U1%X1 %0,%1\";
case 11:
return \"stfd%U0%X0 %1,%0\";
case 12:
return \"xxlxor %x0,%x0,%x0\";
case 13:
case 14:
case 15:
return \"#\"; return \"#\";
} }
}" }"
[(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*") [(set_attr "type" "two,load,store,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,*,*,*")
(set_attr "length" "8,16,16,4,4,4,8,12,16")]) (set_attr "length" "8,16,16,4,4,4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat32" (define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
@ -9096,8 +9191,8 @@
; ld/std require word-aligned displacements -> 'Y' constraint. ; ld/std require word-aligned displacements -> 'Y' constraint.
; List Y->r and r->Y before r->r for reload. ; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64_mfpgpr" (define_insn "*movdf_hardfloat64_mfpgpr"
[(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d") [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r,r,d")
(match_operand:DF 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))] (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,r"))]
"TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_DOUBLE_FLOAT && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], DFmode) && (gpc_reg_operand (operands[0], DFmode)
@ -9106,9 +9201,16 @@
std%U0%X0 %1,%0 std%U0%X0 %1,%0
ld%U1%X1 %0,%1 ld%U1%X1 %0,%1
mr %0,%1 mr %0,%1
xxlor %x0,%x1,%x1
xxlor %x0,%x1,%x1
lxsd%U1x %x0,%y1
lxsd%U1x %x0,%y1
stxsd%U0x %x1,%y0
stxsd%U0x %x1,%y0
fmr %0,%1 fmr %0,%1
lfd%U1%X1 %0,%1 lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0 stfd%U0%X0 %1,%0
xxlxor %x0,%x0,%x0
mt%0 %1 mt%0 %1
mf%1 %0 mf%1 %0
{cror 0,0,0|nop} {cror 0,0,0|nop}
@ -9117,14 +9219,14 @@
# #
mftgpr %0,%1 mftgpr %0,%1
mffgpr %0,%1" mffgpr %0,%1"
[(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
(set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
; ld/std require word-aligned displacements -> 'Y' constraint. ; ld/std require word-aligned displacements -> 'Y' constraint.
; List Y->r and r->Y before r->r for reload. ; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64" (define_insn "*movdf_hardfloat64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r") [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r")
(match_operand:DF 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))] (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F"))]
"TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_DOUBLE_FLOAT && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], DFmode) && (gpc_reg_operand (operands[0], DFmode)
@ -9133,17 +9235,24 @@
std%U0%X0 %1,%0 std%U0%X0 %1,%0
ld%U1%X1 %0,%1 ld%U1%X1 %0,%1
mr %0,%1 mr %0,%1
xxlor %x0,%x1,%x1
xxlor %x0,%x1,%x1
lxsd%U1x %x0,%y1
lxsd%U1x %x0,%y1
stxsd%U0x %x1,%y0
stxsd%U0x %x1,%y0
fmr %0,%1 fmr %0,%1
lfd%U1%X1 %0,%1 lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0 stfd%U0%X0 %1,%0
xxlxor %x0,%x0,%x0
mt%0 %1 mt%0 %1
mf%1 %0 mf%1 %0
{cror 0,0,0|nop} {cror 0,0,0|nop}
# #
# #
#" #"
[(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*") [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*")
(set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")]) (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat64" (define_insn "*movdf_softfloat64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
@ -9720,15 +9829,16 @@
(define_insn "*movti_ppc64" (define_insn "*movti_ppc64"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r") [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
(match_operand:TI 1 "input_operand" "r,r,m"))] (match_operand:TI 1 "input_operand" "r,r,m"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) "(TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|| gpc_reg_operand (operands[1], TImode))" || gpc_reg_operand (operands[1], TImode)))
&& VECTOR_MEM_NONE_P (TImode)"
"#" "#"
[(set_attr "type" "*,store,load")]) [(set_attr "type" "*,store,load")])
(define_split (define_split
[(set (match_operand:TI 0 "gpc_reg_operand" "") [(set (match_operand:TI 0 "gpc_reg_operand" "")
(match_operand:TI 1 "const_double_operand" ""))] (match_operand:TI 1 "const_double_operand" ""))]
"TARGET_POWERPC64" "TARGET_POWERPC64 && VECTOR_MEM_NONE_P (TImode)"
[(set (match_dup 2) (match_dup 4)) [(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))] (set (match_dup 3) (match_dup 5))]
" "
@ -9754,7 +9864,7 @@
(define_split (define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "") [(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "input_operand" ""))] (match_operand:TI 1 "input_operand" ""))]
"reload_completed "reload_completed && VECTOR_MEM_NONE_P (TImode)
&& gpr_or_gpr_p (operands[0], operands[1])" && gpr_or_gpr_p (operands[0], operands[1])"
[(pc)] [(pc)]
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
@ -12647,7 +12757,8 @@
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y") [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d") (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))] (match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fcmpu %0,%1,%2" "fcmpu %0,%1,%2"
[(set_attr "type" "fpcompare")]) [(set_attr "type" "fpcompare")])
@ -15320,9 +15431,19 @@
}" }"
[(set_attr "type" "load")]) [(set_attr "type" "load")])
(define_insn "bpermd_<mode>"
[(set (match_operand:P 0 "gpc_reg_operand" "=r")
(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
(match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
"TARGET_POPCNTD"
"bpermd %0,%1,%2"
[(set_attr "type" "integer")])
(include "sync.md") (include "sync.md")
(include "vector.md") (include "vector.md")
(include "vsx.md")
(include "altivec.md") (include "altivec.md")
(include "spe.md") (include "spe.md")
(include "dfp.md") (include "dfp.md")

View File

@ -151,6 +151,10 @@ malign-branch-targets
Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1) Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1)
; Explicitly set/unset whether rs6000_align_branch_targets is set ; Explicitly set/unset whether rs6000_align_branch_targets is set
mvectorize-builtins
Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1)
; Explicitly control whether we vectorize the builtins or not.
mupdate mupdate
Target Report Var(TARGET_UPDATE) Init(1) Target Report Var(TARGET_UPDATE) Init(1)
Generate load/store with update instructions Generate load/store with update instructions

View File

@ -53,6 +53,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \
$(srcdir)/config/rs6000/power4.md \ $(srcdir)/config/rs6000/power4.md \
$(srcdir)/config/rs6000/power5.md \ $(srcdir)/config/rs6000/power5.md \
$(srcdir)/config/rs6000/power6.md \ $(srcdir)/config/rs6000/power6.md \
$(srcdir)/config/rs6000/power7.md \
$(srcdir)/config/rs6000/cell.md \ $(srcdir)/config/rs6000/cell.md \
$(srcdir)/config/rs6000/xfpu.md \ $(srcdir)/config/rs6000/xfpu.md \
$(srcdir)/config/rs6000/predicates.md \ $(srcdir)/config/rs6000/predicates.md \
@ -60,6 +61,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \
$(srcdir)/config/rs6000/darwin.md \ $(srcdir)/config/rs6000/darwin.md \
$(srcdir)/config/rs6000/sync.md \ $(srcdir)/config/rs6000/sync.md \
$(srcdir)/config/rs6000/vector.md \ $(srcdir)/config/rs6000/vector.md \
$(srcdir)/config/rs6000/vsx.md \
$(srcdir)/config/rs6000/altivec.md \ $(srcdir)/config/rs6000/altivec.md \
$(srcdir)/config/rs6000/spe.md \ $(srcdir)/config/rs6000/spe.md \
$(srcdir)/config/rs6000/dfp.md \ $(srcdir)/config/rs6000/dfp.md \

View File

@ -1,6 +1,7 @@
;; Expander definitions for vector support. No instructions are in this file, ;; Expander definitions for vector support between altivec & vsx. No
;; this file provides the generic vector expander, and the actual vector ;; instructions are in this file, this file provides the generic vector
;; instructions will be in altivec.md. ;; expander, and the actual vector instructions will be in altivec.md and
;; vsx.md
;; Copyright (C) 2009 ;; Copyright (C) 2009
;; Free Software Foundation, Inc. ;; Free Software Foundation, Inc.
@ -27,10 +28,10 @@
(define_mode_iterator VEC_I [V16QI V8HI V4SI]) (define_mode_iterator VEC_I [V16QI V8HI V4SI])
;; Vector float modes ;; Vector float modes
(define_mode_iterator VEC_F [V4SF]) (define_mode_iterator VEC_F [V4SF V2DF])
;; Vector arithmetic modes ;; Vector arithmetic modes
(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF]) (define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF])
;; Vector modes that need alginment via permutes ;; Vector modes that need alginment via permutes
(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
@ -41,6 +42,9 @@
;; Vector modes for moves. Don't do TImode here. ;; Vector modes for moves. Don't do TImode here.
(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF]) (define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF])
;; Vector modes for types that don't need a realignment under VSX
(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF])
;; Vector comparison modes ;; Vector comparison modes
(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF]) (define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF])
@ -75,7 +79,7 @@
(define_expand "mov<mode>" (define_expand "mov<mode>"
[(set (match_operand:VEC_M 0 "nonimmediate_operand" "") [(set (match_operand:VEC_M 0 "nonimmediate_operand" "")
(match_operand:VEC_M 1 "any_operand" ""))] (match_operand:VEC_M 1 "any_operand" ""))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{ {
if (can_create_pseudo_p ()) if (can_create_pseudo_p ())
{ {
@ -89,24 +93,25 @@
} }
}) })
;; Generic vector floating point load/store instructions. ;; Generic vector floating point load/store instructions. These will match
;; insns defined in vsx.md or altivec.md depending on the switches.
(define_expand "vector_load_<mode>" (define_expand "vector_load_<mode>"
[(set (match_operand:VEC_M 0 "vfloat_operand" "") [(set (match_operand:VEC_M 0 "vfloat_operand" "")
(match_operand:VEC_M 1 "memory_operand" ""))] (match_operand:VEC_M 1 "memory_operand" ""))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_store_<mode>" (define_expand "vector_store_<mode>"
[(set (match_operand:VEC_M 0 "memory_operand" "") [(set (match_operand:VEC_M 0 "memory_operand" "")
(match_operand:VEC_M 1 "vfloat_operand" ""))] (match_operand:VEC_M 1 "vfloat_operand" ""))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
;; Splits if a GPR register was chosen for the move ;; Splits if a GPR register was chosen for the move
(define_split (define_split
[(set (match_operand:VEC_L 0 "nonimmediate_operand" "") [(set (match_operand:VEC_L 0 "nonimmediate_operand" "")
(match_operand:VEC_L 1 "input_operand" ""))] (match_operand:VEC_L 1 "input_operand" ""))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode) "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
&& reload_completed && reload_completed
&& gpr_or_gpr_p (operands[0], operands[1])" && gpr_or_gpr_p (operands[0], operands[1])"
[(pc)] [(pc)]
@ -149,7 +154,7 @@
(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
(match_operand:P 2 "reg_or_cint_operand" "rI")) (match_operand:P 2 "reg_or_cint_operand" "rI"))
(const_int -16)))] (const_int -16)))]
"TARGET_ALTIVEC && (reload_in_progress || reload_completed)" "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
"#" "#"
"&& reload_completed" "&& reload_completed"
[(set (match_dup 0) [(set (match_dup 0)
@ -167,7 +172,7 @@
[(set (match_operand:P 0 "gpc_reg_operand" "=b") [(set (match_operand:P 0 "gpc_reg_operand" "=b")
(and:P (match_operand:P 1 "gpc_reg_operand" "r") (and:P (match_operand:P 1 "gpc_reg_operand" "r")
(const_int -16)))] (const_int -16)))]
"TARGET_ALTIVEC && (reload_in_progress || reload_completed)" "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
"#" "#"
"&& reload_completed" "&& reload_completed"
[(parallel [(set (match_dup 0) [(parallel [(set (match_dup 0)
@ -180,68 +185,131 @@
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
(match_operand:VEC_F 2 "vfloat_operand" "")))] (match_operand:VEC_F 2 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "sub<mode>3" (define_expand "sub<mode>3"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
(match_operand:VEC_F 2 "vfloat_operand" "")))] (match_operand:VEC_F 2 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "mul<mode>3" (define_expand "mul<mode>3"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
(match_operand:VEC_F 2 "vfloat_operand" "")))] (match_operand:VEC_F 2 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && TARGET_FUSED_MADD" "(VECTOR_UNIT_VSX_P (<MODE>mode)
|| (VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && TARGET_FUSED_MADD))"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2]));
DONE; DONE;
}
}") }")
(define_expand "div<mode>3"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(div:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
(match_operand:VEC_F 2 "vfloat_operand" "")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"")
(define_expand "neg<mode>2" (define_expand "neg<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1]));
DONE; DONE;
}
}") }")
(define_expand "abs<mode>2" (define_expand "abs<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1]));
DONE; DONE;
}
}") }")
(define_expand "smin<mode>3" (define_expand "smin<mode>3"
[(set (match_operand:VEC_F 0 "register_operand" "") [(set (match_operand:VEC_F 0 "register_operand" "")
(smin:VEC_F (match_operand:VEC_F 1 "register_operand" "") (smin:VEC_F (match_operand:VEC_F 1 "register_operand" "")
(match_operand:VEC_F 2 "register_operand" "")))] (match_operand:VEC_F 2 "register_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "smax<mode>3" (define_expand "smax<mode>3"
[(set (match_operand:VEC_F 0 "register_operand" "") [(set (match_operand:VEC_F 0 "register_operand" "")
(smax:VEC_F (match_operand:VEC_F 1 "register_operand" "") (smax:VEC_F (match_operand:VEC_F 1 "register_operand" "")
(match_operand:VEC_F 2 "register_operand" "")))] (match_operand:VEC_F 2 "register_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "sqrt<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"")
(define_expand "ftrunc<mode>2" (define_expand "ftrunc<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_ceil<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")]
UNSPEC_FRIP))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
(define_expand "vector_floor<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")]
UNSPEC_FRIM))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
(define_expand "vector_btrunc<mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
(define_expand "vector_copysign<mode>3"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(if_then_else:VEC_F
(ge:VEC_F (match_operand:VEC_F 2 "vfloat_operand" "")
(match_dup 3))
(abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" ""))
(neg:VEC_F (abs:VEC_F (match_dup 1)))))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{
emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1],
operands[2]));
DONE;
}
operands[3] = CONST0_RTX (<MODE>mode);
}")
;; Vector comparisons ;; Vector comparisons
(define_expand "vcond<mode>" (define_expand "vcond<mode>"
@ -252,7 +320,7 @@
(match_operand:VEC_F 5 "vfloat_operand" "")]) (match_operand:VEC_F 5 "vfloat_operand" "")])
(match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 1 "vfloat_operand" "")
(match_operand:VEC_F 2 "vfloat_operand" "")))] (match_operand:VEC_F 2 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{ {
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
@ -302,21 +370,21 @@
[(set (match_operand:VEC_C 0 "vlogical_operand" "") [(set (match_operand:VEC_C 0 "vlogical_operand" "")
(eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
(match_operand:VEC_C 2 "vlogical_operand" "")))] (match_operand:VEC_C 2 "vlogical_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_gt<mode>" (define_expand "vector_gt<mode>"
[(set (match_operand:VEC_C 0 "vlogical_operand" "") [(set (match_operand:VEC_C 0 "vlogical_operand" "")
(gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
(match_operand:VEC_C 2 "vlogical_operand" "")))] (match_operand:VEC_C 2 "vlogical_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_ge<mode>" (define_expand "vector_ge<mode>"
[(set (match_operand:VEC_C 0 "vlogical_operand" "") [(set (match_operand:VEC_C 0 "vlogical_operand" "")
(ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") (ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
(match_operand:VEC_C 2 "vlogical_operand" "")))] (match_operand:VEC_C 2 "vlogical_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_gtu<mode>" (define_expand "vector_gtu<mode>"
@ -342,7 +410,7 @@
(const_int 0)) (const_int 0))
(match_operand:VEC_L 2 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" "")
(match_operand:VEC_L 1 "vlogical_operand" "")))] (match_operand:VEC_L 1 "vlogical_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_select_<mode>_uns" (define_expand "vector_select_<mode>_uns"
@ -352,7 +420,7 @@
(const_int 0)) (const_int 0))
(match_operand:VEC_L 2 "vlogical_operand" "") (match_operand:VEC_L 2 "vlogical_operand" "")
(match_operand:VEC_L 1 "vlogical_operand" "")))] (match_operand:VEC_L 1 "vlogical_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
;; Expansions that compare vectors producing a vector result and a predicate, ;; Expansions that compare vectors producing a vector result and a predicate,
@ -366,7 +434,7 @@
(set (match_operand:VEC_A 0 "vlogical_operand" "") (set (match_operand:VEC_A 0 "vlogical_operand" "")
(eq:VEC_A (match_dup 1) (eq:VEC_A (match_dup 1)
(match_dup 2)))])] (match_dup 2)))])]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_gt_<mode>_p" (define_expand "vector_gt_<mode>_p"
@ -378,7 +446,7 @@
(set (match_operand:VEC_A 0 "vlogical_operand" "") (set (match_operand:VEC_A 0 "vlogical_operand" "")
(gt:VEC_A (match_dup 1) (gt:VEC_A (match_dup 1)
(match_dup 2)))])] (match_dup 2)))])]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_ge_<mode>_p" (define_expand "vector_ge_<mode>_p"
@ -390,7 +458,7 @@
(set (match_operand:VEC_F 0 "vfloat_operand" "") (set (match_operand:VEC_F 0 "vfloat_operand" "")
(ge:VEC_F (match_dup 1) (ge:VEC_F (match_dup 1)
(match_dup 2)))])] (match_dup 2)))])]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "vector_gtu_<mode>_p" (define_expand "vector_gtu_<mode>_p"
@ -402,16 +470,16 @@
(set (match_operand:VEC_I 0 "vlogical_operand" "") (set (match_operand:VEC_I 0 "vlogical_operand" "")
(gtu:VEC_I (match_dup 1) (gtu:VEC_I (match_dup 1)
(match_dup 2)))])] (match_dup 2)))])]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
;; AltiVec predicates. ;; AltiVec/VSX predicates.
(define_expand "cr6_test_for_zero" (define_expand "cr6_test_for_zero"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(eq:SI (reg:CC 74) (eq:SI (reg:CC 74)
(const_int 0)))] (const_int 0)))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC || TARGET_VSX"
"") "")
(define_expand "cr6_test_for_zero_reverse" (define_expand "cr6_test_for_zero_reverse"
@ -419,14 +487,14 @@
(eq:SI (reg:CC 74) (eq:SI (reg:CC 74)
(const_int 0))) (const_int 0)))
(set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC || TARGET_VSX"
"") "")
(define_expand "cr6_test_for_lt" (define_expand "cr6_test_for_lt"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(lt:SI (reg:CC 74) (lt:SI (reg:CC 74)
(const_int 0)))] (const_int 0)))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC || TARGET_VSX"
"") "")
(define_expand "cr6_test_for_lt_reverse" (define_expand "cr6_test_for_lt_reverse"
@ -434,7 +502,7 @@
(lt:SI (reg:CC 74) (lt:SI (reg:CC 74)
(const_int 0))) (const_int 0)))
(set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
"TARGET_ALTIVEC" "TARGET_ALTIVEC || TARGET_VSX"
"") "")
@ -443,82 +511,94 @@
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
(match_operand:VEC_L 2 "vlogical_operand" "")))] (match_operand:VEC_L 2 "vlogical_operand" "")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "ior<mode>3" (define_expand "ior<mode>3"
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
(match_operand:VEC_L 2 "vlogical_operand" "")))] (match_operand:VEC_L 2 "vlogical_operand" "")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "and<mode>3" (define_expand "and<mode>3"
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
(match_operand:VEC_L 2 "vlogical_operand" "")))] (match_operand:VEC_L 2 "vlogical_operand" "")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "one_cmpl<mode>2" (define_expand "one_cmpl<mode>2"
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))] (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "nor<mode>3" (define_expand "nor<mode>3"
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") (not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
(match_operand:VEC_L 2 "vlogical_operand" ""))))] (match_operand:VEC_L 2 "vlogical_operand" ""))))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
(define_expand "andc<mode>3" (define_expand "andc<mode>3"
[(set (match_operand:VEC_L 0 "vlogical_operand" "") [(set (match_operand:VEC_L 0 "vlogical_operand" "")
(and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" "")) (and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" ""))
(match_operand:VEC_L 1 "vlogical_operand" "")))] (match_operand:VEC_L 1 "vlogical_operand" "")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
"") "")
;; Same size conversions ;; Same size conversions
(define_expand "float<VEC_int><mode>2" (define_expand "float<VEC_int><mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx));
DONE; DONE;
}
}") }")
(define_expand "unsigned_float<VEC_int><mode>2" (define_expand "unsigned_float<VEC_int><mode>2"
[(set (match_operand:VEC_F 0 "vfloat_operand" "") [(set (match_operand:VEC_F 0 "vfloat_operand" "")
(unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx));
DONE; DONE;
}
}") }")
(define_expand "fix_trunc<mode><VEC_int>2" (define_expand "fix_trunc<mode><VEC_int>2"
[(set (match_operand:<VEC_INT> 0 "vint_operand" "") [(set (match_operand:<VEC_INT> 0 "vint_operand" "")
(fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx));
DONE; DONE;
}
}") }")
(define_expand "fixuns_trunc<mode><VEC_int>2" (define_expand "fixuns_trunc<mode><VEC_int>2"
[(set (match_operand:<VEC_INT> 0 "vint_operand" "") [(set (match_operand:<VEC_INT> 0 "vint_operand" "")
(unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
" "
{
if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
{ {
emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx));
DONE; DONE;
}
}") }")
@ -526,7 +606,7 @@
(define_expand "vec_init<mode>" (define_expand "vec_init<mode>"
[(match_operand:VEC_E 0 "vlogical_operand" "") [(match_operand:VEC_E 0 "vlogical_operand" "")
(match_operand:VEC_E 1 "" "")] (match_operand:VEC_E 1 "" "")]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{ {
rs6000_expand_vector_init (operands[0], operands[1]); rs6000_expand_vector_init (operands[0], operands[1]);
DONE; DONE;
@ -536,7 +616,7 @@
[(match_operand:VEC_E 0 "vlogical_operand" "") [(match_operand:VEC_E 0 "vlogical_operand" "")
(match_operand:<VEC_base> 1 "register_operand" "") (match_operand:<VEC_base> 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")] (match_operand 2 "const_int_operand" "")]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{ {
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2])); rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
DONE; DONE;
@ -546,7 +626,7 @@
[(match_operand:<VEC_base> 0 "register_operand" "") [(match_operand:<VEC_base> 0 "register_operand" "")
(match_operand:VEC_E 1 "vlogical_operand" "") (match_operand:VEC_E 1 "vlogical_operand" "")
(match_operand 2 "const_int_operand" "")] (match_operand 2 "const_int_operand" "")]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{ {
rs6000_expand_vector_extract (operands[0], operands[1], rs6000_expand_vector_extract (operands[0], operands[1],
INTVAL (operands[2])); INTVAL (operands[2]));
@ -568,7 +648,7 @@
(const_int 3) (const_int 3)
(const_int 1)])) (const_int 1)]))
(const_int 5)))] (const_int 5)))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
"") "")
(define_expand "vec_interleave_lowv4sf" (define_expand "vec_interleave_lowv4sf"
@ -585,9 +665,149 @@
(const_int 1) (const_int 1)
(const_int 3)])) (const_int 3)]))
(const_int 5)))] (const_int 5)))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
"") "")
(define_expand "vec_interleave_highv2df"
[(set (match_operand:V2DF 0 "vfloat_operand" "")
(vec_concat:V2DF
(vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "")
(parallel [(const_int 0)]))
(vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "")
(parallel [(const_int 0)]))))]
"VECTOR_UNIT_VSX_P (V2DFmode)"
"")
(define_expand "vec_interleave_lowv2df"
[(set (match_operand:V2DF 0 "vfloat_operand" "")
(vec_concat:V2DF
(vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "")
(parallel [(const_int 1)]))
(vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "")
(parallel [(const_int 1)]))))]
"VECTOR_UNIT_VSX_P (V2DFmode)"
"")
;; Convert double word types to single word types
(define_expand "vec_pack_trunc_v2df"
[(match_operand:V4SF 0 "vfloat_operand" "")
(match_operand:V2DF 1 "vfloat_operand" "")
(match_operand:V2DF 2 "vfloat_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
{
rtx r1 = gen_reg_rtx (V4SFmode);
rtx r2 = gen_reg_rtx (V4SFmode);
emit_insn (gen_vsx_xvcvdpsp (r1, operands[1]));
emit_insn (gen_vsx_xvcvdpsp (r2, operands[2]));
emit_insn (gen_vec_extract_evenv4sf (operands[0], r1, r2));
DONE;
})
(define_expand "vec_pack_sfix_trunc_v2df"
[(match_operand:V4SI 0 "vint_operand" "")
(match_operand:V2DF 1 "vfloat_operand" "")
(match_operand:V2DF 2 "vfloat_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
{
rtx r1 = gen_reg_rtx (V4SImode);
rtx r2 = gen_reg_rtx (V4SImode);
emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1]));
emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2]));
emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2));
DONE;
})
(define_expand "vec_pack_ufix_trunc_v2df"
[(match_operand:V4SI 0 "vint_operand" "")
(match_operand:V2DF 1 "vfloat_operand" "")
(match_operand:V2DF 2 "vfloat_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
{
rtx r1 = gen_reg_rtx (V4SImode);
rtx r2 = gen_reg_rtx (V4SImode);
emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1]));
emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2]));
emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2));
DONE;
})
;; Convert single word types to double word
(define_expand "vec_unpacks_hi_v4sf"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SF 1 "vfloat_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
{
rtx reg = gen_reg_rtx (V4SFmode);
emit_insn (gen_vec_interleave_highv4sf (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
DONE;
})
(define_expand "vec_unpacks_lo_v4sf"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SF 1 "vfloat_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
{
rtx reg = gen_reg_rtx (V4SFmode);
emit_insn (gen_vec_interleave_lowv4sf (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
DONE;
})
(define_expand "vec_unpacks_float_hi_v4si"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SI 1 "vint_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
{
rtx reg = gen_reg_rtx (V4SImode);
emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
DONE;
})
(define_expand "vec_unpacks_float_lo_v4si"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SI 1 "vint_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
{
rtx reg = gen_reg_rtx (V4SImode);
emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
DONE;
})
(define_expand "vec_unpacku_float_hi_v4si"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SI 1 "vint_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
{
rtx reg = gen_reg_rtx (V4SImode);
emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
DONE;
})
(define_expand "vec_unpacku_float_lo_v4si"
[(match_operand:V2DF 0 "vfloat_operand" "")
(match_operand:V4SI 1 "vint_operand" "")]
"VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
{
rtx reg = gen_reg_rtx (V4SImode);
emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1]));
emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
DONE;
})
;; Align vector loads with a permute. ;; Align vector loads with a permute.
(define_expand "vec_realign_load_<mode>" (define_expand "vec_realign_load_<mode>"
@ -595,13 +815,21 @@
(match_operand:VEC_K 1 "vlogical_operand" "") (match_operand:VEC_K 1 "vlogical_operand" "")
(match_operand:VEC_K 2 "vlogical_operand" "") (match_operand:VEC_K 2 "vlogical_operand" "")
(match_operand:V16QI 3 "vlogical_operand" "")] (match_operand:V16QI 3 "vlogical_operand" "")]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{ {
emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2], emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2],
operands[3])); operands[3]));
DONE; DONE;
}) })
;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned
;; since the load already handles it.
(define_expand "movmisalign<mode>"
[(set (match_operand:VEC_N 0 "vfloat_operand" "")
(match_operand:VEC_N 1 "vfloat_operand" ""))]
"VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN"
"")
;; Vector shift left in bits. Currently supported ony for shift ;; Vector shift left in bits. Currently supported ony for shift
;; amounts that can be expressed as byte shifts (divisible by 8). ;; amounts that can be expressed as byte shifts (divisible by 8).
@ -627,9 +855,18 @@
if (bitshift_val & 0x7) if (bitshift_val & 0x7)
FAIL; FAIL;
byteshift_val = bitshift_val >> 3; byteshift_val = bitshift_val >> 3;
if (TARGET_VSX && (byteshift_val & 0x3) == 0)
{
shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2);
insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1],
shift);
}
else
{
shift = gen_rtx_CONST_INT (QImode, byteshift_val); shift = gen_rtx_CONST_INT (QImode, byteshift_val);
insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
shift); shift);
}
emit_insn (insn); emit_insn (insn);
DONE; DONE;
@ -659,9 +896,18 @@
if (bitshift_val & 0x7) if (bitshift_val & 0x7)
FAIL; FAIL;
byteshift_val = 16 - (bitshift_val >> 3); byteshift_val = 16 - (bitshift_val >> 3);
if (TARGET_VSX && (byteshift_val & 0x3) == 0)
{
shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2);
insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1],
shift);
}
else
{
shift = gen_rtx_CONST_INT (QImode, byteshift_val); shift = gen_rtx_CONST_INT (QImode, byteshift_val);
insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
shift); shift);
}
emit_insn (insn); emit_insn (insn);
DONE; DONE;

1339
gcc/config/rs6000/vsx.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7298,7 +7298,7 @@ instructions, but allow the compiler to schedule those calls.
* MIPS Loongson Built-in Functions:: * MIPS Loongson Built-in Functions::
* Other MIPS Built-in Functions:: * Other MIPS Built-in Functions::
* picoChip Built-in Functions:: * picoChip Built-in Functions::
* PowerPC AltiVec Built-in Functions:: * PowerPC AltiVec/VSX Built-in Functions::
* SPARC VIS Built-in Functions:: * SPARC VIS Built-in Functions::
* SPU Built-in Functions:: * SPU Built-in Functions::
@end menu @end menu
@ -9776,7 +9776,7 @@ GCC defines the preprocessor macro @code{___GCC_HAVE_BUILTIN_MIPS_CACHE}
when this function is available. when this function is available.
@end table @end table
@node PowerPC AltiVec Built-in Functions @node PowerPC AltiVec/VSX Built-in Functions
@subsection PowerPC AltiVec Built-in Functions @subsection PowerPC AltiVec Built-in Functions
GCC provides an interface for the PowerPC family of processors to access GCC provides an interface for the PowerPC family of processors to access
@ -9802,6 +9802,19 @@ vector bool int
vector float vector float
@end smallexample @end smallexample
If @option{-mvsx} is used the following additional vector types are
implemented.
@smallexample
vector unsigned long
vector signed long
vector double
@end smallexample
The long types are only implemented for 64-bit code generation, and
the long type is only used in the floating point/integer conversion
instructions.
GCC's implementation of the high-level language interface available from GCC's implementation of the high-level language interface available from
C and C++ code differs from Motorola's documentation in several ways. C and C++ code differs from Motorola's documentation in several ways.
@ -10067,6 +10080,8 @@ vector signed char vec_vavgsb (vector signed char, vector signed char);
vector unsigned char vec_vavgub (vector unsigned char, vector unsigned char vec_vavgub (vector unsigned char,
vector unsigned char); vector unsigned char);
vector float vec_copysign (vector float);
vector float vec_ceil (vector float); vector float vec_ceil (vector float);
vector signed int vec_cmpb (vector float, vector float); vector signed int vec_cmpb (vector float, vector float);
@ -11669,6 +11684,92 @@ int vec_any_numeric (vector float);
int vec_any_out (vector float, vector float); int vec_any_out (vector float, vector float);
@end smallexample @end smallexample
If the vector/scalar (VSX) instruction set is available, the following
additional functions are available:
@smallexample
vector double vec_abs (vector double);
vector double vec_add (vector double, vector double);
vector double vec_and (vector double, vector double);
vector double vec_and (vector double, vector bool long);
vector double vec_and (vector bool long, vector double);
vector double vec_andc (vector double, vector double);
vector double vec_andc (vector double, vector bool long);
vector double vec_andc (vector bool long, vector double);
vector double vec_ceil (vector double);
vector bool long vec_cmpeq (vector double, vector double);
vector bool long vec_cmpge (vector double, vector double);
vector bool long vec_cmpgt (vector double, vector double);
vector bool long vec_cmple (vector double, vector double);
vector bool long vec_cmplt (vector double, vector double);
vector float vec_div (vector float, vector float);
vector double vec_div (vector double, vector double);
vector double vec_floor (vector double);
vector double vec_madd (vector double, vector double, vector double);
vector double vec_max (vector double, vector double);
vector double vec_min (vector double, vector double);
vector float vec_msub (vector float, vector float, vector float);
vector double vec_msub (vector double, vector double, vector double);
vector float vec_mul (vector float, vector float);
vector double vec_mul (vector double, vector double);
vector float vec_nearbyint (vector float);
vector double vec_nearbyint (vector double);
vector float vec_nmadd (vector float, vector float, vector float);
vector double vec_nmadd (vector double, vector double, vector double);
vector double vec_nmsub (vector double, vector double, vector double);
vector double vec_nor (vector double, vector double);
vector double vec_or (vector double, vector double);
vector double vec_or (vector double, vector bool long);
vector double vec_or (vector bool long, vector double);
vector double vec_perm (vector double,
vector double,
vector unsigned char);
vector float vec_rint (vector float);
vector double vec_rint (vector double);
vector double vec_sel (vector double, vector double, vector bool long);
vector double vec_sel (vector double, vector double, vector unsigned long);
vector double vec_sub (vector double, vector double);
vector float vec_sqrt (vector float);
vector double vec_sqrt (vector double);
vector double vec_trunc (vector double);
vector double vec_xor (vector double, vector double);
vector double vec_xor (vector double, vector bool long);
vector double vec_xor (vector bool long, vector double);
int vec_all_eq (vector double, vector double);
int vec_all_ge (vector double, vector double);
int vec_all_gt (vector double, vector double);
int vec_all_le (vector double, vector double);
int vec_all_lt (vector double, vector double);
int vec_all_nan (vector double);
int vec_all_ne (vector double, vector double);
int vec_all_nge (vector double, vector double);
int vec_all_ngt (vector double, vector double);
int vec_all_nle (vector double, vector double);
int vec_all_nlt (vector double, vector double);
int vec_all_numeric (vector double);
int vec_any_eq (vector double, vector double);
int vec_any_ge (vector double, vector double);
int vec_any_gt (vector double, vector double);
int vec_any_le (vector double, vector double);
int vec_any_lt (vector double, vector double);
int vec_any_nan (vector double);
int vec_any_ne (vector double, vector double);
int vec_any_nge (vector double, vector double);
int vec_any_ngt (vector double, vector double);
int vec_any_nle (vector double, vector double);
int vec_any_nlt (vector double, vector double);
int vec_any_numeric (vector double);
@end smallexample
GCC provides a few other builtins on Powerpc to access certain instructions:
@smallexample
float __builtin_recipdivf (float, float);
float __builtin_rsqrtf (float);
double __builtin_recipdiv (double, double);
long __builtin_bpermd (long, long);
int __builtin_bswap16 (int);
@end smallexample
@node SPARC VIS Built-in Functions @node SPARC VIS Built-in Functions
@subsection SPARC VIS Built-in Functions @subsection SPARC VIS Built-in Functions

View File

@ -738,7 +738,8 @@ See RS/6000 and PowerPC Options.
-maltivec -mno-altivec @gol -maltivec -mno-altivec @gol
-mpowerpc-gpopt -mno-powerpc-gpopt @gol -mpowerpc-gpopt -mno-powerpc-gpopt @gol
-mpowerpc-gfxopt -mno-powerpc-gfxopt @gol -mpowerpc-gfxopt -mno-powerpc-gfxopt @gol
-mmfcrf -mno-mfcrf -mpopcntb -mno-popcntb -mfprnd -mno-fprnd @gol -mmfcrf -mno-mfcrf -mpopcntb -mno-popcntb -mpopcntd -mno-popcntd @gol
-mfprnd -mno-fprnd @gol
-mcmpb -mno-cmpb -mmfpgpr -mno-mfpgpr -mhard-dfp -mno-hard-dfp @gol -mcmpb -mno-cmpb -mmfpgpr -mno-mfpgpr -mhard-dfp -mno-hard-dfp @gol
-mnew-mnemonics -mold-mnemonics @gol -mnew-mnemonics -mold-mnemonics @gol
-mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol -mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol
@ -14116,6 +14117,8 @@ These @samp{-m} options are defined for the IBM RS/6000 and PowerPC:
@itemx -mno-mfcrf @itemx -mno-mfcrf
@itemx -mpopcntb @itemx -mpopcntb
@itemx -mno-popcntb @itemx -mno-popcntb
@itemx -mpopcntd
@itemx -mno-popcntd
@itemx -mfprnd @itemx -mfprnd
@itemx -mno-fprnd @itemx -mno-fprnd
@itemx -mcmpb @itemx -mcmpb
@ -14140,6 +14143,8 @@ These @samp{-m} options are defined for the IBM RS/6000 and PowerPC:
@opindex mno-mfcrf @opindex mno-mfcrf
@opindex mpopcntb @opindex mpopcntb
@opindex mno-popcntb @opindex mno-popcntb
@opindex mpopcntd
@opindex mno-popcntd
@opindex mfprnd @opindex mfprnd
@opindex mno-fprnd @opindex mno-fprnd
@opindex mcmpb @opindex mcmpb
@ -14189,6 +14194,9 @@ The @option{-mpopcntb} option allows GCC to generate the popcount and
double precision FP reciprocal estimate instruction implemented on the double precision FP reciprocal estimate instruction implemented on the
POWER5 processor and other processors that support the PowerPC V2.02 POWER5 processor and other processors that support the PowerPC V2.02
architecture. architecture.
The @option{-mpopcntd} option allows GCC to generate the popcount
instruction implemented on the POWER7 processor and other processors
that support the PowerPC V2.06 architecture.
The @option{-mfprnd} option allows GCC to generate the FP round to The @option{-mfprnd} option allows GCC to generate the FP round to
integer instructions implemented on the POWER5+ processor and other integer instructions implemented on the POWER5+ processor and other
processors that support the PowerPC V2.03 architecture. processors that support the PowerPC V2.03 architecture.
@ -14267,9 +14275,9 @@ The @option{-mcpu} options automatically enable or disable the
following options: following options:
@gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol @gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol
-mnew-mnemonics -mpopcntb -mpower -mpower2 -mpowerpc64 @gol -mnew-mnemonics -mpopcntb -mpopcntd -mpower -mpower2 -mpowerpc64 @gol
-mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol -mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol
-msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr} -msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr -mvsx}
The particular options set for any particular CPU will vary between The particular options set for any particular CPU will vary between
compiler versions, depending on what setting seems to produce optimal compiler versions, depending on what setting seems to produce optimal
@ -14370,6 +14378,14 @@ instructions.
This option has been deprecated. Use @option{-mspe} and This option has been deprecated. Use @option{-mspe} and
@option{-mno-spe} instead. @option{-mno-spe} instead.
@item -mvsx
@itemx -mno-vsx
@opindex mvsx
@opindex mno-vsx
Generate code that uses (does not use) vector/scalar (VSX)
instructions, and also enable the use of built-in functions that allow
more direct access to the VSX instruction set.
@item -mfloat-gprs=@var{yes/single/double/no} @item -mfloat-gprs=@var{yes/single/double/no}
@itemx -mfloat-gprs @itemx -mfloat-gprs
@opindex mfloat-gprs @opindex mfloat-gprs

View File

@ -1916,7 +1916,19 @@ Floating point register (containing 64-bit value)
Floating point register (containing 32-bit value) Floating point register (containing 32-bit value)
@item v @item v
Vector register Altivec vector register
@item wd
VSX vector register to hold vector double data
@item wf
VSX vector register to hold vector float data
@item ws
VSX vector register to hold scalar float data
@item wa
Any VSX register
@item h @item h
@samp{MQ}, @samp{CTR}, or @samp{LINK} register @samp{MQ}, @samp{CTR}, or @samp{LINK} register
@ -2029,6 +2041,9 @@ AND masks that can be performed by two rldic@{l, r@} instructions
@item W @item W
Vector constant that does not require memory Vector constant that does not require memory
@item j
Vector constant that is all zeros.
@end table @end table
@item Intel 386---@file{config/i386/constraints.md} @item Intel 386---@file{config/i386/constraints.md}

View File

@ -1,3 +1,53 @@
2009-07-30 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Revital Eres <ERES@il.ibm.com>
* testsuite/gcc.target/powerpc/altivec-32.c: New file to test
Altivec simple math function vectorization.
* testsuite/gcc.target/powerpc/bswap-run.c: New file to test swap
builtins.
* testsuite/gcc.target/powerpc/bswap16.c: Ditto.
* testsuite/gcc.target/powerpc/bswap32.c: Ditto.
* testsuite/gcc.target/powerpc/bswap64-1.c: Ditto.
* testsuite/gcc.target/powerpc/bswap64-2.c: Ditto.
* testsuite/gcc.target/powerpc/bswap64-3.c: Ditto.
* testsuite/gcc.target/powerpc/optimize-bswapdi-2.c: Ditto.
* testsuite/gcc.target/powerpc/optimize-bswapdi-3.c: Ditto.
* testsuite/gcc.target/powerpc/optimize-bswapsi-2.c: Ditto.
* testsuite/gcc.target/powerpc/popcount-2.c: New file to test
power7 popcntd instructions.
* testsuite/gcc.target/powerpc/popcount-3.c: Ditto.
* testsuite/gcc.target/powerpc/pr39457.c: New VSX test.
* testsuite/gcc.target/powerpc/vsx-builtin-1.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-builtin-2.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-builtin-3.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-builtin-4.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-builtin-5.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-builtin-6.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-1.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-2.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-3.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-4.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-5.c: Ditto.
* testsuite/gcc.target/powerpc/vsx-vector-6.c: Ditto.
* testsuite/gcc.target/powerpc/altivec-6.c: Store the result of
vec_add, so the optimizer doesn't remove it.
* testsuite/gcc.dg/optimize-bswapdi-1.c: Add powerpc 64-bit to
systems that support bswap64.
* testsuite/gcc.dg/vmx/vmx.exp: Explicitly add -mno-vsx to
prevent VSX code generation.
* testsuite/lib/target-supports.exp (check_vsx_hw_available): New
function to test if VSX available.
(check_effective_target_powerpc_vsx_ok): Ditto.
(check_vmx_hw_available): Add explicit -mno-vsx.
2009-07-30 Janis Johnson <janis187@us.ibm.com> 2009-07-30 Janis Johnson <janis187@us.ibm.com>
PR c/39902 PR c/39902

View File

@ -1,4 +1,4 @@
/* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* } } */ /* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* powerpc*-*-* rs6000-*-* } } */
/* { dg-require-effective-target stdint_types } */ /* { dg-require-effective-target stdint_types } */
/* { dg-require-effective-target lp64 } */ /* { dg-require-effective-target lp64 } */
/* { dg-options "-O2 -fdump-tree-bswap" } */ /* { dg-options "-O2 -fdump-tree-bswap" } */

View File

@ -31,7 +31,7 @@ if {![istarget powerpc*-*-*]
# nothing but extensions. # nothing but extensions.
global DEFAULT_VMXCFLAGS global DEFAULT_VMXCFLAGS
if ![info exists DEFAULT_VMXCFLAGS] then { if ![info exists DEFAULT_VMXCFLAGS] then {
set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99" set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99 -mno-vsx"
} }
# If the target system supports AltiVec instructions, the default action # If the target system supports AltiVec instructions, the default action

View File

@ -0,0 +1,59 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-O2 -ftree-vectorize -mcpu=power6 -m64 -maltivec" } */
/* { dg-final { scan-assembler "vsel" } } */
/* { dg-final { scan-assembler "vrfim" } } */
/* { dg-final { scan-assembler "vrfip" } } */
/* { dg-final { scan-assembler "vrfiz" } } */
#ifndef SIZE
#define SIZE 1024
#endif
float a[SIZE] __attribute__((__aligned__(32)));
float b[SIZE] __attribute__((__aligned__(32)));
float c[SIZE] __attribute__((__aligned__(32)));
float d[SIZE] __attribute__((__aligned__(32)));
float e[SIZE] __attribute__((__aligned__(32)));
extern float floorf (float);
extern float ceilf (float);
extern float truncf (float);
extern float copysignf (float, float);
void
vector_floor (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = floorf (b[i]);
}
void
vector_ceil (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = ceilf (b[i]);
}
void
vector_trunc (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = truncf (b[i]);
}
void
vector_copysign (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = copysignf (b[i], c[i]);
}

View File

@ -5,7 +5,7 @@
#include <altivec.h> #include <altivec.h>
/* These denote "generic" GCC vectors. */ /* These denote "generic" GCC vectors. */
static int __attribute__((vector_size(16))) x, y; static int __attribute__((vector_size(16))) x, y, z;
static vector signed int i,j; static vector signed int i,j;
static vector signed short s,t; static vector signed short s,t;
@ -21,7 +21,7 @@ static int int1, int2;
void void
b() b()
{ {
vec_add (x, y); z = vec_add (x, y);
/* Make sure the predicates accept correct argument types. */ /* Make sure the predicates accept correct argument types. */

View File

@ -0,0 +1,102 @@
/* { dg-do run { target powerpc*-*-* } } */
/* { dg-options "-O2 -std=gnu99" } */
extern void abort (void);
static unsigned char bytes[] = { 0, 1, 2, 0x80, 0xff };
unsigned short b16a (unsigned short *p) { return __builtin_bswap16 (*p); }
void b16b (unsigned short *p, unsigned short a) { *p = __builtin_bswap16 (a); }
int b16c (unsigned short a) { return __builtin_bswap16 (a); }
unsigned int b32a (unsigned int *p) { return __builtin_bswap32 (*p); }
void b32b (unsigned int *p, unsigned int a) { *p = __builtin_bswap32 (a); }
static unsigned int b32c (unsigned int a) { return __builtin_bswap32 (a); }
unsigned long long b64a (unsigned long long *p) { return __builtin_bswap64 (*p); }
void b64b (unsigned long long *p, unsigned long long a) { *p = __builtin_bswap64 (a); }
unsigned long long b64c (unsigned long long a) { return __builtin_bswap64 (a); }
int
main (void)
{
unsigned i1, i2, i3, i4, i5;
unsigned b1, b2, b3, b4, b5;
unsigned short b16_inp, b16_exp, b16_var;
unsigned int b32_inp, b32_exp, b32_var;
unsigned long long b64_inp, b64_exp, b64_var;
for (i1 = 0; i1 < sizeof (bytes); i1++)
{
b1 = bytes[i1];
for (i2 = 0; i2 < sizeof (bytes); i2++)
{
b2 = bytes[i2];
b16_inp = (b1 << 8) | b2;
b16_exp = (b2 << 8) | b1;
if (b16a (&b16_inp) != b16_exp)
abort ();
b16b (&b16_var, b16_inp);
if (b16_var != b16_exp)
abort ();
if (b16c (b16_inp) != b16_exp)
abort ();
for (i3 = 0; i3 < sizeof (bytes); i3++)
{
b3 = bytes[i3];
for (i4 = 0; i4 < sizeof (bytes); i4++)
{
b4 = bytes[i4];
b32_inp = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
b32_exp = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
if (b32a (&b32_inp) != b32_exp)
abort ();
b32b (&b32_var, b32_inp);
if (b32_var != b32_exp)
abort ();
if (b32c (b32_inp) != b32_exp)
abort ();
for (i5 = 0; i5 < sizeof (bytes); i5++)
{
b5 = bytes[i5];
b64_inp = (((unsigned long long)b32_inp) << 32) | b5;
b64_exp = (((unsigned long long)b5) << 56) | b32_exp;
if (b64a (&b64_inp) != b64_exp)
abort ();
b64b (&b64_var, b64_inp);
if (b64_var != b64_exp)
abort ();
if (b64c (b64_inp) != b64_exp)
abort ();
b64_inp = (((unsigned long long)b5) << 56) | b32_inp;
b64_exp = (((unsigned long long)b32_exp) << 32) | b5;
if (b64a (&b64_inp) != b64_exp)
abort ();
b64b (&b64_var, b64_inp);
if (b64_var != b64_exp)
abort ();
if (b64c (b64_inp) != b64_exp)
abort ();
}
}
}
}
}
return 0;
}

View File

@ -0,0 +1,8 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "lhbrx" } } */
/* { dg-final { scan-assembler "sthbrx" } } */
unsigned short us;
unsigned int load_bswap16 (unsigned short *p) { return __builtin_bswap16 (*p); }
void store_bswap16 (unsigned int a) { us = __builtin_bswap16 (a); }

View File

@ -0,0 +1,8 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "lwbrx" } } */
/* { dg-final { scan-assembler "stwbrx" } } */
unsigned int ui;
unsigned int load_bswap32 (unsigned int *p) { return __builtin_bswap32 (*p); }
void store_bswap32 (unsigned int a) { ui = __builtin_bswap32 (a); }

View File

@ -0,0 +1,9 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-options "-O2 -mno-popcntd -mcpu=power5" } */
/* { dg-require-effective-target lp64 } */
/* { dg-final { scan-assembler "lwbrx" } } */
/* { dg-final { scan-assembler "stwbrx" } } */
unsigned long ul;
unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); }
void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); }

View File

@ -0,0 +1,10 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-options "-O2 -mpopcntd" } */
/* { dg-require-effective-target lp64 } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-final { scan-assembler "ldbrx" } } */
/* { dg-final { scan-assembler "stdbrx" } } */
unsigned long ul;
unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); }
void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); }

View File

@ -0,0 +1,10 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-options "-O2 -mcpu=cell" } */
/* { dg-require-effective-target lp64 } */
/* { dg-require-effective-target powerpc_ppu_ok } */
/* { dg-final { scan-assembler "ldbrx" } } */
/* { dg-final { scan-assembler "stdbrx" } } */
unsigned long ul;
unsigned long load_bswap64 (unsigned long *p) { return __builtin_bswap64 (*p); }
void store_bswap64 (unsigned long a) { ul = __builtin_bswap64 (a); }

View File

@ -0,0 +1,36 @@
/* { dg-require-effective-target stdint_types } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-O2 -mcpu=power5" } */
/* This is a clone of gcc-dg/optimize-bswapdi-1.c, redone to use load and stores
to test whether lwbrx/stwbrx is generated for normal power systems. */
#include <stdint.h>
#define __const_swab64(x) ((uint64_t)( \
(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
/* This byte swap implementation is used by the Linux kernel and the
GNU C library. */
uint64_t
swap64_load (uint64_t *in)
{
return __const_swab64 (*in);
}
void
swap64_store (uint64_t *out, uint64_t in)
{
*out = __const_swab64 (in);
}
/* { dg-final { scan-assembler-times "lwbrx" 2 } } */
/* { dg-final { scan-assembler-times "stwbrx" 2 } } */

View File

@ -0,0 +1,36 @@
/* { dg-require-effective-target stdint_types } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-O2 -mcpu=power7" } */
/* This is a clone of gcc-dg/optimize-bswapdi-1.c, redone to use load and stores
to test whether ldbrx/stdbrx is generated for power7. */
#include <stdint.h>
#define __const_swab64(x) ((uint64_t)( \
(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
/* This byte swap implementation is used by the Linux kernel and the
GNU C library. */
uint64_t
swap64_load (uint64_t *in)
{
return __const_swab64 (*in);
}
void
swap64_store (uint64_t *out, uint64_t in)
{
*out = __const_swab64 (in);
}
/* { dg-final { scan-assembler "ldbrx" } } */
/* { dg-final { scan-assembler "stdbrx" } } */

View File

@ -0,0 +1,55 @@
/* { dg-require-effective-target stdint_types } */
/* { dg-options "-O2 -mcpu=power5" } */
#include <stdint.h>
/* This is a clone of gcc-dg/optimize-bswapsi-1.c, redone to use load and stores
to test whether lwbrx/stwbrx is generated for normal power systems. */
#define __const_swab32(x) ((uint32_t)( \
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
/* This byte swap implementation is used by the Linux kernel and the
GNU C library. */
uint32_t
swap32_a_load (uint32_t *in)
{
return __const_swab32 (*in);
}
/* The OpenSSH byte swap implementation. */
uint32_t
swap32_b_load (uint32_t *in)
{
uint32_t a;
a = (*in << 16) | (*in >> 16);
a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8);
return a;
}
void
swap32_a_store (uint32_t *out, uint32_t in)
{
*out = __const_swab32 (in);
}
/* The OpenSSH byte swap implementation. */
void
swap32_b_store (uint32_t *out, uint32_t in)
{
uint32_t a;
a = (in << 16) | (in >> 16);
a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8);
*out = a;
}
/* { dg-final { scan-assembler-times "lwbrx" 2 } } */
/* { dg-final { scan-assembler-times "stwbrx" 2 } } */

View File

@ -0,0 +1,9 @@
/* { dg-do compile { target { ilp32 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-options "-O2 -mcpu=power7 -m32" } */
/* { dg-final { scan-assembler "popcntw" } } */
int foo(int x)
{
return __builtin_popcount(x);
}

View File

@ -0,0 +1,9 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-options "-O2 -mcpu=power7 -m64" } */
/* { dg-final { scan-assembler "popcntd" } } */
long foo(int x)
{
return __builtin_popcountl(x);
}

View File

@ -0,0 +1,56 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-options "-m64 -O2 -mminimal-toc" } */
/* PR 39457 -- fix breakage because the compiler ran out of registers and
wanted to stash a floating point value to the LR/CTR register. */
/* -O2 -m64 -mminimal-toc */
typedef struct { void *s; } S;
typedef void (*T1) (void);
typedef void (*T2) (void *, void *, int, void *);
char *fn1 (const char *, ...);
void *fn2 (void);
int fn3 (char *, int);
int fn4 (const void *);
int fn5 (const void *);
long fn6 (void) __attribute__ ((__const__));
int fn7 (void *, void *, void *);
void *fn8 (void *, long);
void *fn9 (void *, long, const char *, ...);
void *fn10 (void *);
long fn11 (void) __attribute__ ((__const__));
long fn12 (void *, const char *, T1, T2, void *);
void *fn13 (void *);
long fn14 (void) __attribute__ ((__const__));
extern void *v1;
extern char *v2;
extern int v3;
void
foo (void *x, char *z)
{
void *i1, *i2;
int y;
if (v1)
return;
v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0);
y = 520 - (520 - fn4 (x)) / 2;
fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0,
"y", 16.0, "wid", 80.0, "hi", 500.0, 0);
fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2",
500.0, "f", fn3 ("fff", 0x0D0DFA00), 0);
fn13 (((S *) fn8 (v1, fn6 ()))->s);
fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ()));
fn9 (fn8 (v1, fn6 ()), fn6 (), "wig",
fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi",
500.0, 0);
v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2",
500.0, "f", fn3 ("gc", 0x0D0DFA00), 0);
fn1 (z, 0);
i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x",
800 - fn5 (x) / 2, "y", y - fn4 (x), 0);
fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/");
fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0);
i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x",
800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0);
}

View File

@ -0,0 +1,38 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* { dg-final { scan-assembler "xvadddp" } } */
/* { dg-final { scan-assembler "xvsubdp" } } */
/* { dg-final { scan-assembler "xvmuldp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
/* { dg-final { scan-assembler "xvnmadd" } } */
/* { dg-final { scan-assembler "xvnmsub" } } */
/* { dg-final { scan-assembler "xvdivdp" } } */
/* { dg-final { scan-assembler "xvmaxdp" } } */
/* { dg-final { scan-assembler "xvmindp" } } */
/* { dg-final { scan-assembler "xvsqrtdp" } } */
/* { dg-final { scan-assembler "xvrsqrtedp" } } */
/* { dg-final { scan-assembler "xvabsdp" } } */
/* { dg-final { scan-assembler "xvnabsdp" } } */
/* { dg-final { scan-assembler "xvredp" } } */
void use_builtins (__vector double *p, __vector double *q, __vector double *r, __vector double *s)
{
p[0] = __builtin_vsx_xvadddp (q[0], r[0]);
p[1] = __builtin_vsx_xvsubdp (q[1], r[1]);
p[2] = __builtin_vsx_xvmuldp (q[2], r[2]);
p[3] = __builtin_vsx_xvdivdp (q[3], r[3]);
p[4] = __builtin_vsx_xvmaxdp (q[4], r[4]);
p[5] = __builtin_vsx_xvmindp (q[5], r[5]);
p[6] = __builtin_vsx_xvabsdp (q[6]);
p[7] = __builtin_vsx_xvnabsdp (q[7]);
p[8] = __builtin_vsx_xvsqrtdp (q[8]);
p[9] = __builtin_vsx_xvmadddp (q[9], r[9], s[9]);
p[10] = __builtin_vsx_xvmsubdp (q[10], r[10], s[10]);
p[11] = __builtin_vsx_xvnmadddp (q[11], r[11], s[11]);
p[12] = __builtin_vsx_xvnmsubdp (q[12], r[12], s[12]);
p[13] = __builtin_vsx_xvredp (q[13]);
p[14] = __builtin_vsx_xvrsqrtedp (q[14]);
}

View File

@ -0,0 +1,38 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* { dg-final { scan-assembler "xvaddsp" } } */
/* { dg-final { scan-assembler "xvsubsp" } } */
/* { dg-final { scan-assembler "xvmulsp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
/* { dg-final { scan-assembler "xvnmadd" } } */
/* { dg-final { scan-assembler "xvnmsub" } } */
/* { dg-final { scan-assembler "xvdivsp" } } */
/* { dg-final { scan-assembler "xvmaxsp" } } */
/* { dg-final { scan-assembler "xvminsp" } } */
/* { dg-final { scan-assembler "xvsqrtsp" } } */
/* { dg-final { scan-assembler "xvabssp" } } */
/* { dg-final { scan-assembler "xvnabssp" } } */
/* { dg-final { scan-assembler "xvresp" } } */
/* { dg-final { scan-assembler "xvrsqrtesp" } } */
void use_builtins (__vector float *p, __vector float *q, __vector float *r, __vector float *s)
{
p[0] = __builtin_vsx_xvaddsp (q[0], r[0]);
p[1] = __builtin_vsx_xvsubsp (q[1], r[1]);
p[2] = __builtin_vsx_xvmulsp (q[2], r[2]);
p[3] = __builtin_vsx_xvdivsp (q[3], r[3]);
p[4] = __builtin_vsx_xvmaxsp (q[4], r[4]);
p[5] = __builtin_vsx_xvminsp (q[5], r[5]);
p[6] = __builtin_vsx_xvabssp (q[6]);
p[7] = __builtin_vsx_xvnabssp (q[7]);
p[8] = __builtin_vsx_xvsqrtsp (q[8]);
p[9] = __builtin_vsx_xvmaddsp (q[9], r[9], s[9]);
p[10] = __builtin_vsx_xvmsubsp (q[10], r[10], s[10]);
p[11] = __builtin_vsx_xvnmaddsp (q[11], r[11], s[11]);
p[12] = __builtin_vsx_xvnmsubsp (q[12], r[12], s[12]);
p[13] = __builtin_vsx_xvresp (q[13]);
p[14] = __builtin_vsx_xvrsqrtesp (q[14]);
}

View File

@ -0,0 +1,212 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* { dg-final { scan-assembler "xxsel" } } */
/* { dg-final { scan-assembler "vperm" } } */
/* { dg-final { scan-assembler "xvrdpi" } } */
/* { dg-final { scan-assembler "xvrdpic" } } */
/* { dg-final { scan-assembler "xvrdpim" } } */
/* { dg-final { scan-assembler "xvrdpip" } } */
/* { dg-final { scan-assembler "xvrdpiz" } } */
/* { dg-final { scan-assembler "xvrspi" } } */
/* { dg-final { scan-assembler "xvrspic" } } */
/* { dg-final { scan-assembler "xvrspim" } } */
/* { dg-final { scan-assembler "xvrspip" } } */
/* { dg-final { scan-assembler "xvrspiz" } } */
/* { dg-final { scan-assembler "xsrdpi" } } */
/* { dg-final { scan-assembler "xsrdpic" } } */
/* { dg-final { scan-assembler "xsrdpim" } } */
/* { dg-final { scan-assembler "xsrdpip" } } */
/* { dg-final { scan-assembler "xsrdpiz" } } */
/* { dg-final { scan-assembler "xsmaxdp" } } */
/* { dg-final { scan-assembler "xsmindp" } } */
/* { dg-final { scan-assembler "xxland" } } */
/* { dg-final { scan-assembler "xxlandc" } } */
/* { dg-final { scan-assembler "xxlnor" } } */
/* { dg-final { scan-assembler "xxlor" } } */
/* { dg-final { scan-assembler "xxlxor" } } */
/* { dg-final { scan-assembler "xvcmpeqdp" } } */
/* { dg-final { scan-assembler "xvcmpgtdp" } } */
/* { dg-final { scan-assembler "xvcmpgedp" } } */
/* { dg-final { scan-assembler "xvcmpeqsp" } } */
/* { dg-final { scan-assembler "xvcmpgtsp" } } */
/* { dg-final { scan-assembler "xvcmpgesp" } } */
/* { dg-final { scan-assembler "xxsldwi" } } */
/* { dg-final { scan-assembler-not "call" } } */
extern __vector int si[][4];
extern __vector short ss[][4];
extern __vector signed char sc[][4];
extern __vector float f[][4];
extern __vector unsigned int ui[][4];
extern __vector unsigned short us[][4];
extern __vector unsigned char uc[][4];
extern __vector __bool int bi[][4];
extern __vector __bool short bs[][4];
extern __vector __bool char bc[][4];
extern __vector __pixel p[][4];
#ifdef __VSX__
extern __vector double d[][4];
extern __vector long sl[][4];
extern __vector unsigned long ul[][4];
extern __vector __bool long bl[][4];
#endif
int do_sel(void)
{
int i = 0;
si[i][0] = __builtin_vsx_xxsel_4si (si[i][1], si[i][2], si[i][3]); i++;
ss[i][0] = __builtin_vsx_xxsel_8hi (ss[i][1], ss[i][2], ss[i][3]); i++;
sc[i][0] = __builtin_vsx_xxsel_16qi (sc[i][1], sc[i][2], sc[i][3]); i++;
f[i][0] = __builtin_vsx_xxsel_4sf (f[i][1], f[i][2], f[i][3]); i++;
d[i][0] = __builtin_vsx_xxsel_2df (d[i][1], d[i][2], d[i][3]); i++;
si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], bi[i][3]); i++;
ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], bs[i][3]); i++;
sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], bc[i][3]); i++;
f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], bi[i][3]); i++;
d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], bl[i][3]); i++;
si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], ui[i][3]); i++;
ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], us[i][3]); i++;
sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], uc[i][3]); i++;
f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], ui[i][3]); i++;
d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], ul[i][3]); i++;
return i;
}
int do_perm(void)
{
int i = 0;
si[i][0] = __builtin_vsx_vperm_4si (si[i][1], si[i][2], uc[i][3]); i++;
ss[i][0] = __builtin_vsx_vperm_8hi (ss[i][1], ss[i][2], uc[i][3]); i++;
sc[i][0] = __builtin_vsx_vperm_16qi (sc[i][1], sc[i][2], uc[i][3]); i++;
f[i][0] = __builtin_vsx_vperm_4sf (f[i][1], f[i][2], uc[i][3]); i++;
d[i][0] = __builtin_vsx_vperm_2df (d[i][1], d[i][2], uc[i][3]); i++;
si[i][0] = __builtin_vsx_vperm (si[i][1], si[i][2], uc[i][3]); i++;
ss[i][0] = __builtin_vsx_vperm (ss[i][1], ss[i][2], uc[i][3]); i++;
sc[i][0] = __builtin_vsx_vperm (sc[i][1], sc[i][2], uc[i][3]); i++;
f[i][0] = __builtin_vsx_vperm (f[i][1], f[i][2], uc[i][3]); i++;
d[i][0] = __builtin_vsx_vperm (d[i][1], d[i][2], uc[i][3]); i++;
return i;
}
int do_xxperm (void)
{
int i = 0;
d[i][0] = __builtin_vsx_xxpermdi_2df (d[i][1], d[i][2], 0); i++;
d[i][0] = __builtin_vsx_xxpermdi (d[i][1], d[i][2], 1); i++;
return i;
}
double x, y;
void do_concat (void)
{
d[0][0] = __builtin_vsx_concat_2df (x, y);
}
void do_set (void)
{
d[0][0] = __builtin_vsx_set_2df (d[0][1], x, 0);
d[1][0] = __builtin_vsx_set_2df (d[1][1], y, 1);
}
extern double z[][4];
int do_math (void)
{
int i = 0;
d[i][0] = __builtin_vsx_xvrdpi (d[i][1]); i++;
d[i][0] = __builtin_vsx_xvrdpic (d[i][1]); i++;
d[i][0] = __builtin_vsx_xvrdpim (d[i][1]); i++;
d[i][0] = __builtin_vsx_xvrdpip (d[i][1]); i++;
d[i][0] = __builtin_vsx_xvrdpiz (d[i][1]); i++;
f[i][0] = __builtin_vsx_xvrspi (f[i][1]); i++;
f[i][0] = __builtin_vsx_xvrspic (f[i][1]); i++;
f[i][0] = __builtin_vsx_xvrspim (f[i][1]); i++;
f[i][0] = __builtin_vsx_xvrspip (f[i][1]); i++;
f[i][0] = __builtin_vsx_xvrspiz (f[i][1]); i++;
z[i][0] = __builtin_vsx_xsrdpi (z[i][1]); i++;
z[i][0] = __builtin_vsx_xsrdpic (z[i][1]); i++;
z[i][0] = __builtin_vsx_xsrdpim (z[i][1]); i++;
z[i][0] = __builtin_vsx_xsrdpip (z[i][1]); i++;
z[i][0] = __builtin_vsx_xsrdpiz (z[i][1]); i++;
z[i][0] = __builtin_vsx_xsmaxdp (z[i][1], z[i][0]); i++;
z[i][0] = __builtin_vsx_xsmindp (z[i][1], z[i][0]); i++;
return i;
}
int do_cmp (void)
{
int i = 0;
d[i][0] = __builtin_vsx_xvcmpeqdp (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xvcmpgtdp (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xvcmpgedp (d[i][1], d[i][2]); i++;
f[i][0] = __builtin_vsx_xvcmpeqsp (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xvcmpgtsp (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xvcmpgesp (f[i][1], f[i][2]); i++;
return i;
}
int do_logical (void)
{
int i = 0;
si[i][0] = __builtin_vsx_xxland (si[i][1], si[i][2]); i++;
si[i][0] = __builtin_vsx_xxlandc (si[i][1], si[i][2]); i++;
si[i][0] = __builtin_vsx_xxlnor (si[i][1], si[i][2]); i++;
si[i][0] = __builtin_vsx_xxlor (si[i][1], si[i][2]); i++;
si[i][0] = __builtin_vsx_xxlxor (si[i][1], si[i][2]); i++;
ss[i][0] = __builtin_vsx_xxland (ss[i][1], ss[i][2]); i++;
ss[i][0] = __builtin_vsx_xxlandc (ss[i][1], ss[i][2]); i++;
ss[i][0] = __builtin_vsx_xxlnor (ss[i][1], ss[i][2]); i++;
ss[i][0] = __builtin_vsx_xxlor (ss[i][1], ss[i][2]); i++;
ss[i][0] = __builtin_vsx_xxlxor (ss[i][1], ss[i][2]); i++;
sc[i][0] = __builtin_vsx_xxland (sc[i][1], sc[i][2]); i++;
sc[i][0] = __builtin_vsx_xxlandc (sc[i][1], sc[i][2]); i++;
sc[i][0] = __builtin_vsx_xxlnor (sc[i][1], sc[i][2]); i++;
sc[i][0] = __builtin_vsx_xxlor (sc[i][1], sc[i][2]); i++;
sc[i][0] = __builtin_vsx_xxlxor (sc[i][1], sc[i][2]); i++;
d[i][0] = __builtin_vsx_xxland (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xxlandc (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xxlnor (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xxlor (d[i][1], d[i][2]); i++;
d[i][0] = __builtin_vsx_xxlxor (d[i][1], d[i][2]); i++;
f[i][0] = __builtin_vsx_xxland (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xxlandc (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xxlnor (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xxlor (f[i][1], f[i][2]); i++;
f[i][0] = __builtin_vsx_xxlxor (f[i][1], f[i][2]); i++;
return i;
}
int do_xxsldwi (void)
{
int i = 0;
si[i][0] = __builtin_vsx_xxsldwi (si[i][1], si[i][2], 0); i++;
ss[i][0] = __builtin_vsx_xxsldwi (ss[i][1], ss[i][2], 1); i++;
sc[i][0] = __builtin_vsx_xxsldwi (sc[i][1], sc[i][2], 2); i++;
ui[i][0] = __builtin_vsx_xxsldwi (ui[i][1], ui[i][2], 3); i++;
us[i][0] = __builtin_vsx_xxsldwi (us[i][1], us[i][2], 0); i++;
uc[i][0] = __builtin_vsx_xxsldwi (uc[i][1], uc[i][2], 1); i++;
f[i][0] = __builtin_vsx_xxsldwi (f[i][1], f[i][2], 2); i++;
d[i][0] = __builtin_vsx_xxsldwi (d[i][1], d[i][2], 3); i++;
return i;
}

View File

@ -0,0 +1,142 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* { dg-final { scan-assembler "xvcmpeqdp." } } */
/* { dg-final { scan-assembler "xvcmpgtdp." } } */
/* { dg-final { scan-assembler "xvcmpgedp." } } */
/* { dg-final { scan-assembler "xvcmpeqsp." } } */
/* { dg-final { scan-assembler "xvcmpgtsp." } } */
/* { dg-final { scan-assembler "xvcmpgesp." } } */
/* { dg-final { scan-assembler "vcmpbfp." } } */
/* { dg-final { scan-assembler "vcmpequb." } } */
/* { dg-final { scan-assembler "vcmpequh." } } */
/* { dg-final { scan-assembler "vcmpequw." } } */
/* { dg-final { scan-assembler "vcmpgtub." } } */
/* { dg-final { scan-assembler "vcmpgtuh." } } */
/* { dg-final { scan-assembler "vcmpgtuw." } } */
/* { dg-final { scan-assembler "vcmpgtsb." } } */
/* { dg-final { scan-assembler "vcmpgtsh." } } */
/* { dg-final { scan-assembler "vcmpgtsw." } } */
/* { dg-final { scan-assembler-not "vcmpeqfp" } } */
/* { dg-final { scan-assembler-not "vcmpgtfp" } } */
/* { dg-final { scan-assembler-not "vcmpgefp" } } */
/* check that Altivec builtins generate VSX if -mvsx. */
#include <altivec.h>
int *v16qi_s (vector signed char *a, vector signed char *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v16qi_u (vector unsigned char *a, vector unsigned char *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v8hi_s (vector short *a, vector short *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v8hi_u (vector unsigned short *a, vector unsigned short *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v4si_s (vector int *a, vector int *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v4si_u (vector unsigned int *a, vector unsigned int *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 2;
return p;
}
int *v4sf (vector float *a, vector float *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 3;
if (vec_all_in (*a, *b)) /* veccmpbfp. */
*p++ = 4;
return p;
}
int *v2df (vector double *a, vector double *b, int *p)
{
if (vec_all_eq (*a, *b))
*p++ = 1;
if (vec_all_gt (*a, *b))
*p++ = 2;
if (vec_all_ge (*a, *b))
*p++ = 3;
return p;
}

View File

@ -0,0 +1,14 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* { dg-final { scan-assembler "xxpermdi" } } */
/* { dg-final { scan-assembler-not "stxvd2x" } } */
/* Make sure double extract doesn't use a store instruction. */
double d0(__vector double v){ return __builtin_vec_extract (v, 0); }
double d1(__vector double v){ return __builtin_vec_extract (v, 1); }
double e0(vector double v){ return __builtin_vec_ext_v2df (v, 0); }
double e1(vector double v){ return __builtin_vec_ext_v2df (v, 1); }

View File

@ -0,0 +1,146 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* Check whether tdiv and tsqrt instructions generate the correct code. */
/* Each of the *tdiv* and *tsqrt* instructions should be generated exactly 3
times (the two calls in the _1 function should be combined). */
/* { dg-final { scan-assembler-times "xstdivdp" 3 } } */
/* { dg-final { scan-assembler-times "xvtdivdp" 3 } } */
/* { dg-final { scan-assembler-times "xvtdivsp" 3 } } */
/* { dg-final { scan-assembler-times "xstsqrtdp" 3 } } */
/* { dg-final { scan-assembler-times "xvtsqrtdp" 3 } } */
/* { dg-final { scan-assembler-times "xvtsqrtsp" 3 } } */
void test_div_df_1 (double a, double b, int *p)
{
p[0] = __builtin_vsx_xstdivdp_fe (a, b);
p[1] = __builtin_vsx_xstdivdp_fg (a, b);
}
int *test_div_df_2 (double a, double b, int *p)
{
if (__builtin_vsx_xstdivdp_fe (a, b))
*p++ = 1;
return p;
}
int *test_div_df_3 (double a, double b, int *p)
{
if (__builtin_vsx_xstdivdp_fg (a, b))
*p++ = 1;
return p;
}
void test_sqrt_df_1 (double a, int *p)
{
p[0] = __builtin_vsx_xstsqrtdp_fe (a);
p[1] = __builtin_vsx_xstsqrtdp_fg (a);
}
int *test_sqrt_df_2 (double a, int *p)
{
if (__builtin_vsx_xstsqrtdp_fe (a))
*p++ = 1;
return p;
}
int *test_sqrt_df_3 (double a, int *p)
{
if (__builtin_vsx_xstsqrtdp_fg (a))
*p++ = 1;
return p;
}
void test_div_v2df_1 (__vector double *a, __vector double *b, int *p)
{
p[0] = __builtin_vsx_xvtdivdp_fe (*a, *b);
p[1] = __builtin_vsx_xvtdivdp_fg (*a, *b);
}
int *test_div_v2df_2 (__vector double *a, __vector double *b, int *p)
{
if (__builtin_vsx_xvtdivdp_fe (*a, *b))
*p++ = 1;
return p;
}
int *test_div_v2df_3 (__vector double *a, __vector double *b, int *p)
{
if (__builtin_vsx_xvtdivdp_fg (*a, *b))
*p++ = 1;
return p;
}
void test_sqrt_v2df_1 (__vector double *a, int *p)
{
p[0] = __builtin_vsx_xvtsqrtdp_fe (*a);
p[1] = __builtin_vsx_xvtsqrtdp_fg (*a);
}
int *test_sqrt_v2df_2 (__vector double *a, int *p)
{
if (__builtin_vsx_xvtsqrtdp_fe (*a))
*p++ = 1;
return p;
}
int *test_sqrt_v2df_3 (__vector double *a, int *p)
{
if (__builtin_vsx_xvtsqrtdp_fg (*a))
*p++ = 1;
return p;
}
void test_div_v4sf_1 (__vector float *a, __vector float *b, int *p)
{
p[0] = __builtin_vsx_xvtdivsp_fe (*a, *b);
p[1] = __builtin_vsx_xvtdivsp_fg (*a, *b);
}
int *test_div_v4sf_2 (__vector float *a, __vector float *b, int *p)
{
if (__builtin_vsx_xvtdivsp_fe (*a, *b))
*p++ = 1;
return p;
}
int *test_div_v4sf_3 (__vector float *a, __vector float *b, int *p)
{
if (__builtin_vsx_xvtdivsp_fg (*a, *b))
*p++ = 1;
return p;
}
void test_sqrt_v4sf_1 (__vector float *a, int *p)
{
p[0] = __builtin_vsx_xvtsqrtsp_fe (*a);
p[1] = __builtin_vsx_xvtsqrtsp_fg (*a);
}
int *test_sqrt_v4sf_2 (__vector float *a, int *p)
{
if (__builtin_vsx_xvtsqrtsp_fe (*a))
*p++ = 1;
return p;
}
int *test_sqrt_v4sf_3 (__vector float *a, int *p)
{
if (__builtin_vsx_xvtsqrtsp_fg (*a))
*p++ = 1;
return p;
}

View File

@ -0,0 +1,150 @@
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
/* Test simple extract/insert/slat operations. Make sure all types are
supported with various options. */
#include <altivec.h>
double extract_df_0_reg (vector double p) { return vec_extract (p, 0); }
double extract_df_1_reg (vector double p) { return vec_extract (p, 1); }
double extract_df_n_reg (vector double p, int n) { return vec_extract (p, n); }
double extract_df_0_mem (vector double *p) { return vec_extract (*p, 0); }
double extract_df_1_mem (vector double *p) { return vec_extract (*p, 1); }
double extract_df_n_mem (vector double *p, int n) { return vec_extract (*p, n); }
vector double insert_df_0 (vector double p, double x) { return vec_insert (x, p, 0); }
vector double insert_df_1 (vector double p, double x) { return vec_insert (x, p, 1); }
vector double insert_df_n (vector double p, double x, int n) { return vec_insert (x, p, n); }
vector double splat_df_reg (double x) { return vec_splats (x); }
vector double splat_df_mem (double *x) { return vec_splats (*x); }
#ifdef _ARCH_PPC64
#define ll long
#else
#define ll long long
#endif
ll extract_di_0_reg (vector ll p) { return vec_extract (p, 0); }
ll extract_di_1_reg (vector ll p) { return vec_extract (p, 1); }
ll extract_di_n_reg (vector ll p, int n) { return vec_extract (p, n); }
ll extract_di_0_mem (vector ll *p) { return vec_extract (*p, 0); }
ll extract_di_1_mem (vector ll *p) { return vec_extract (*p, 1); }
ll extract_di_n_mem (vector ll *p, int n) { return vec_extract (*p, n); }
vector ll insert_di_0 (vector ll p, ll x) { return vec_insert (x, p, 0); }
vector ll insert_di_1 (vector ll p, ll x) { return vec_insert (x, p, 1); }
vector ll insert_di_n (vector ll p, ll x, int n) { return vec_insert (x, p, n); }
vector ll splat_di_reg (ll x) { return vec_splats (x); }
vector ll splat_di_mem (ll *x) { return vec_splats (*x); }
float extract_sf_0_reg (vector float p) { return vec_extract (p, 0); }
float extract_sf_3_reg (vector float p) { return vec_extract (p, 3); }
float extract_sf_n_reg (vector float p, int n) { return vec_extract (p, n); }
float extract_sf_0_mem (vector float *p) { return vec_extract (*p, 0); }
float extract_sf_3_mem (vector float *p) { return vec_extract (*p, 3); }
float extract_sf_n_mem (vector float *p, int n) { return vec_extract (*p, n); }
vector float insert_sf_0 (vector float p, float x) { return vec_insert (x, p, 0); }
vector float insert_sf_3 (vector float p, float x) { return vec_insert (x, p, 3); }
vector float insert_sf_n (vector float p, float x, int n) { return vec_insert (x, p, n); }
vector float splat_sf_reg (float x) { return vec_splats (x); }
vector float splat_sf_mem (float *x) { return vec_splats (*x); }
int extract_si_0_reg (vector int p) { return vec_extract (p, 0); }
int extract_si_3_reg (vector int p) { return vec_extract (p, 3); }
int extract_si_n_reg (vector int p, int n) { return vec_extract (p, n); }
int extract_si_0_mem (vector int *p) { return vec_extract (*p, 0); }
int extract_si_3_mem (vector int *p) { return vec_extract (*p, 3); }
int extract_si_n_mem (vector int *p, int n) { return vec_extract (*p, n); }
vector int insert_si_0 (vector int p, int x) { return vec_insert (x, p, 0); }
vector int insert_si_3 (vector int p, int x) { return vec_insert (x, p, 3); }
vector int insert_si_n (vector int p, int x, int n) { return vec_insert (x, p, n); }
vector int splat_si_reg (int x) { return vec_splats (x); }
vector int splat_si_mem (int *x) { return vec_splats (*x); }
unsigned int extract_usi_0_reg (vector unsigned int p) { return vec_extract (p, 0); }
unsigned int extract_usi_3_reg (vector unsigned int p) { return vec_extract (p, 3); }
unsigned int extract_usi_n_reg (vector unsigned int p, int n) { return vec_extract (p, n); }
unsigned int extract_usi_0_mem (vector unsigned int *p) { return vec_extract (*p, 0); }
unsigned int extract_usi_3_mem (vector unsigned int *p) { return vec_extract (*p, 3); }
unsigned int extract_usi_n_mem (vector unsigned int *p, int n) { return vec_extract (*p, n); }
vector unsigned int insert_usi_0 (vector unsigned int p, unsigned int x) { return vec_insert (x, p, 0); }
vector unsigned int insert_usi_3 (vector unsigned int p, unsigned int x) { return vec_insert (x, p, 3); }
vector unsigned int insert_usi_n (vector unsigned int p, unsigned int x, int n) { return vec_insert (x, p, n); }
vector unsigned int splat_usi_reg (unsigned int x) { return vec_splats (x); }
vector unsigned int splat_usi_mem (unsigned int *x) { return vec_splats (*x); }
short extract_hi_0_reg (vector short p) { return vec_extract (p, 0); }
short extract_hi_7_reg (vector short p) { return vec_extract (p, 7); }
short extract_hi_n_reg (vector short p, int n) { return vec_extract (p, n); }
short extract_hi_0_mem (vector short *p) { return vec_extract (*p, 0); }
short extract_hi_7_mem (vector short *p) { return vec_extract (*p, 7); }
short extract_hi_n_mem (vector short *p, int n) { return vec_extract (*p, n); }
vector short insert_hi_0 (vector short p, short x) { return vec_insert (x, p, 0); }
vector short insert_hi_7 (vector short p, short x) { return vec_insert (x, p, 7); }
vector short insert_hi_n (vector short p, short x, int n) { return vec_insert (x, p, n); }
vector short splat_hi_reg (short x) { return vec_splats (x); }
vector short splat_hi_mem (short *x) { return vec_splats (*x); }
unsigned short extract_uhi_0_reg (vector unsigned short p) { return vec_extract (p, 0); }
unsigned short extract_uhi_7_reg (vector unsigned short p) { return vec_extract (p, 7); }
unsigned short extract_uhi_n_reg (vector unsigned short p, int n) { return vec_extract (p, n); }
unsigned short extract_uhi_0_mem (vector unsigned short *p) { return vec_extract (*p, 0); }
unsigned short extract_uhi_7_mem (vector unsigned short *p) { return vec_extract (*p, 7); }
unsigned short extract_uhi_n_mem (vector unsigned short *p, int n) { return vec_extract (*p, n); }
vector unsigned short insert_uhi_0 (vector unsigned short p, unsigned short x) { return vec_insert (x, p, 0); }
vector unsigned short insert_uhi_7 (vector unsigned short p, unsigned short x) { return vec_insert (x, p, 7); }
vector unsigned short insert_uhi_n (vector unsigned short p, unsigned short x, int n) { return vec_insert (x, p, n); }
vector unsigned short splat_uhi_reg (unsigned short x) { return vec_splats (x); }
vector unsigned short splat_uhi_mem (unsigned short *x) { return vec_splats (*x); }
signed char extract_qi_0_reg (vector signed char p) { return vec_extract (p, 0); }
signed char extract_qi_1_reg5 (vector signed char p) { return vec_extract (p, 15); }
signed char extract_qi_n_reg (vector signed char p, int n) { return vec_extract (p, n); }
signed char extract_qi_0_mem (vector signed char *p) { return vec_extract (*p, 0); }
signed char extract_qi_1_mem5 (vector signed char *p) { return vec_extract (*p, 15); }
signed char extract_qi_n_mem (vector signed char *p, int n) { return vec_extract (*p, n); }
vector signed char insert_qi_0 (vector signed char p, signed char x) { return vec_insert (x, p, 0); }
vector signed char insert_qi_15 (vector signed char p, signed char x) { return vec_insert (x, p, 15); }
vector signed char insert_qi_n (vector signed char p, signed char x, int n) { return vec_insert (x, p, n); }
vector signed char splat_qi_reg (signed char x) { return vec_splats (x); }
vector signed char splat_qi_mem (signed char *x) { return vec_splats (*x); }
unsigned char extract_uqi_0_reg (vector unsigned char p) { return vec_extract (p, 0); }
unsigned char extract_uqi_1_reg5 (vector unsigned char p) { return vec_extract (p, 15); }
unsigned char extract_uqi_n_reg (vector unsigned char p, int n) { return vec_extract (p, n); }
unsigned char extract_uqi_0_mem (vector unsigned char *p) { return vec_extract (*p, 0); }
unsigned char extract_uqi_1_mem5 (vector unsigned char *p) { return vec_extract (*p, 15); }
unsigned char extract_uqi_n_mem (vector unsigned char *p, int n) { return vec_extract (*p, n); }
vector unsigned char insert_uqi_0 (vector unsigned char p, unsigned char x) { return vec_insert (x, p, 0); }
vector unsigned char insert_uqi_15 (vector unsigned char p, unsigned char x) { return vec_insert (x, p, 15); }
vector unsigned char insert_uqi_n (vector unsigned char p, unsigned char x, int n) { return vec_insert (x, p, n); }
vector unsigned char splat_uqi_reg (unsigned char x) { return vec_splats (x); }
vector unsigned char splat_uqi_mem (unsigned char *x) { return vec_splats (*x); }

View File

@ -0,0 +1,152 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64 -ffast-math" } */
/* { dg-final { scan-assembler "xvadddp" } } */
/* { dg-final { scan-assembler "xvsubdp" } } */
/* { dg-final { scan-assembler "xvmuldp" } } */
/* { dg-final { scan-assembler "xvdivdp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
/* { dg-final { scan-assembler "xvsqrtdp" } } */
/* { dg-final { scan-assembler "xvcpsgndp" } } */
/* { dg-final { scan-assembler "xvrdpim" } } */
/* { dg-final { scan-assembler "xvrdpip" } } */
/* { dg-final { scan-assembler "xvrdpiz" } } */
/* { dg-final { scan-assembler "xvrdpic" } } */
/* { dg-final { scan-assembler "xvrdpi " } } */
#ifndef SIZE
#define SIZE 1024
#endif
double a[SIZE] __attribute__((__aligned__(32)));
double b[SIZE] __attribute__((__aligned__(32)));
double c[SIZE] __attribute__((__aligned__(32)));
double d[SIZE] __attribute__((__aligned__(32)));
double e[SIZE] __attribute__((__aligned__(32)));
void
vector_add (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] + c[i];
}
void
vector_subtract (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] - c[i];
}
void
vector_multiply (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] * c[i];
}
void
vector_multiply_add (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = (b[i] * c[i]) + d[i];
}
void
vector_multiply_subtract (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = (b[i] * c[i]) - d[i];
}
void
vector_divide (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] / c[i];
}
extern double sqrt (double);
extern double floor (double);
extern double ceil (double);
extern double trunc (double);
extern double nearbyint (double);
extern double rint (double);
extern double copysign (double, double);
void
vector_sqrt (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = sqrt (b[i]);
}
void
vector_floor (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = floor (b[i]);
}
void
vector_ceil (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = ceil (b[i]);
}
void
vector_trunc (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = trunc (b[i]);
}
void
vector_nearbyint (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = nearbyint (b[i]);
}
void
vector_rint (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = rint (b[i]);
}
void
vector_copysign (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = copysign (b[i], c[i]);
}

View File

@ -0,0 +1,152 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64 -ffast-math" } */
/* { dg-final { scan-assembler "xvaddsp" } } */
/* { dg-final { scan-assembler "xvsubsp" } } */
/* { dg-final { scan-assembler "xvmulsp" } } */
/* { dg-final { scan-assembler "xvdivsp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
/* { dg-final { scan-assembler "xvsqrtsp" } } */
/* { dg-final { scan-assembler "xvcpsgnsp" } } */
/* { dg-final { scan-assembler "xvrspim" } } */
/* { dg-final { scan-assembler "xvrspip" } } */
/* { dg-final { scan-assembler "xvrspiz" } } */
/* { dg-final { scan-assembler "xvrspic" } } */
/* { dg-final { scan-assembler "xvrspi " } } */
#ifndef SIZE
#define SIZE 1024
#endif
float a[SIZE] __attribute__((__aligned__(32)));
float b[SIZE] __attribute__((__aligned__(32)));
float c[SIZE] __attribute__((__aligned__(32)));
float d[SIZE] __attribute__((__aligned__(32)));
float e[SIZE] __attribute__((__aligned__(32)));
void
vector_add (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] + c[i];
}
void
vector_subtract (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] - c[i];
}
void
vector_multiply (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] * c[i];
}
void
vector_multiply_add (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = (b[i] * c[i]) + d[i];
}
void
vector_multiply_subtract (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = (b[i] * c[i]) - d[i];
}
void
vector_divide (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = b[i] / c[i];
}
extern float sqrtf (float);
extern float floorf (float);
extern float ceilf (float);
extern float truncf (float);
extern float nearbyintf (float);
extern float rintf (float);
extern float copysignf (float, float);
void
vector_sqrt (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = sqrtf (b[i]);
}
void
vector_floor (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = floorf (b[i]);
}
void
vector_ceil (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = ceilf (b[i]);
}
void
vector_trunc (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = truncf (b[i]);
}
void
vector_nearbyint (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = nearbyintf (b[i]);
}
void
vector_rint (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = rintf (b[i]);
}
void
vector_copysign (void)
{
int i;
for (i = 0; i < SIZE; i++)
a[i] = copysignf (b[i], c[i]);
}

View File

@ -0,0 +1,48 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64" } */
/* { dg-final { scan-assembler "xvadddp" } } */
/* { dg-final { scan-assembler "xvsubdp" } } */
/* { dg-final { scan-assembler "xvmuldp" } } */
/* { dg-final { scan-assembler "xvdivdp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
__vector double a, b, c, d;
void
vector_add (void)
{
a = b + c;
}
void
vector_subtract (void)
{
a = b - c;
}
void
vector_multiply (void)
{
a = b * c;
}
void
vector_multiply_add (void)
{
a = (b * c) + d;
}
void
vector_multiply_subtract (void)
{
a = (b * c) - d;
}
void
vector_divide (void)
{
a = b / c;
}

View File

@ -0,0 +1,48 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -ftree-vectorize -mcpu=power7 -m64" } */
/* { dg-final { scan-assembler "xvaddsp" } } */
/* { dg-final { scan-assembler "xvsubsp" } } */
/* { dg-final { scan-assembler "xvmulsp" } } */
/* { dg-final { scan-assembler "xvdivsp" } } */
/* { dg-final { scan-assembler "xvmadd" } } */
/* { dg-final { scan-assembler "xvmsub" } } */
__vector float a, b, c, d;
void
vector_add (void)
{
a = b + c;
}
void
vector_subtract (void)
{
a = b - c;
}
void
vector_multiply (void)
{
a = b * c;
}
void
vector_multiply_add (void)
{
a = (b * c) + d;
}
void
vector_multiply_subtract (void)
{
a = (b * c) - d;
}
void
vector_divide (void)
{
a = b / c;
}

View File

@ -0,0 +1,392 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-mvsx -O2" } */
/* This will run, and someday we should add the support to test whether we are
running on VSX hardware. */
#include <altivec.h>
#include <stdlib.h>
#ifdef DEBUG
#include <stdio.h>
static int errors = 0;
#endif
union args {
double scalar[2];
vector double vect;
};
union largs {
unsigned long scalar[2];
vector bool long vect;
};
static void
do_test (union args *expected, union args *got, const char *name)
{
if (expected->scalar[0] != got->scalar[0]
|| expected->scalar[1] != got->scalar[1])
{
#ifdef DEBUG
printf ("%s failed!\n", name);
errors++;
#else
abort ();
#endif
}
}
static void
do_ltest (union largs *expected, union largs *got, const char *name)
{
if (expected->scalar[0] != got->scalar[0]
|| expected->scalar[1] != got->scalar[1])
{
#ifdef DEBUG
printf ("%s failed!\n", name);
errors++;
#else
abort ();
#endif
}
}
/* Vec functions taking a single argument. */
static vector double
vabs (vector double arg)
{
return vec_abs (arg);
}
static vector double
vceil (vector double arg)
{
return vec_ceil (arg);
}
static vector double
vfloor (vector double arg)
{
return vec_floor (arg);
}
static vector double
vnearbyint (vector double arg)
{
return vec_nearbyint (arg);
}
static vector double
vrint (vector double arg)
{
return vec_rint (arg);
}
static vector double
vsqrt (vector double arg)
{
return vec_sqrt (arg);
}
/* Single argument tests. */
static struct
{
union args result;
union args input;
vector double (*func) (vector double);
const char *name;
} arg1_tests[] = {
/* result input function name */
{ { 1.0, 2.0 }, { -1.0, 2.0 }, vabs, "vabs" },
{ { 1.0, 2.0 }, { 1.0, -2.0 }, vabs, "vabs" },
{ { 2.0, 2.0 }, { 1.1, 1.7 }, vceil, "vceil" },
{ { -1.0, -1.0 }, { -1.1, -1.7 }, vceil, "vceil" },
{ { -1.0, 2.0 }, { -1.5, 1.5 }, vceil, "vceil" },
{ { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor, "vfloor" },
{ { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor, "vfloor" },
{ { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor, "vfloor" },
{ { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint, "vnearbyint" },
{ { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint, "vnearbyint" },
{ { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint, "vnearbyint" },
{ { 1.0, 2.0 }, { 1.1, 1.7 }, vrint, "vrint" },
{ { -1.0, -2.0 }, { -1.1, -1.7 }, vrint, "vrint" },
{ { -2.0, 2.0 }, { -1.5, 1.5 }, vrint, "vrint" },
{ { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt, "vsqrt" },
};
static void
test_arg1 (void)
{
unsigned i;
#ifdef DEBUG
printf ("Single argument tests:\n");
#endif
for (i = 0; i < sizeof (arg1_tests) / sizeof (arg1_tests[0]); i++)
{
union args u;
u.vect = arg1_tests[i].func (arg1_tests[i].input.vect);
#ifdef DEBUG
printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n",
arg1_tests[i].name,
arg1_tests[i].result.scalar[0],
arg1_tests[i].result.scalar[1],
u.scalar[0],
u.scalar[1],
arg1_tests[i].input.scalar[0],
arg1_tests[i].input.scalar[1]);
#endif
do_test (&arg1_tests[i].result, &u, arg1_tests[i].name);
}
return;
}
/* Vect functions taking 2 arguments. */
static vector double
vadd (vector double arg1, vector double arg2)
{
return vec_add (arg1, arg2);
}
static vector double
vadd2 (vector double arg1, vector double arg2)
{
return arg1 + arg2;
}
static vector double
vsub (vector double arg1, vector double arg2)
{
return vec_sub (arg1, arg2);
}
static vector double
vsub2 (vector double arg1, vector double arg2)
{
return arg1 - arg2;
}
static vector double
vmul (vector double arg1, vector double arg2)
{
return vec_mul (arg1, arg2);
}
static vector double
vmul2 (vector double arg1, vector double arg2)
{
return arg1 * arg2;
}
static vector double
vdiv (vector double arg1, vector double arg2)
{
return vec_div (arg1, arg2);
}
static vector double
vdiv2 (vector double arg1, vector double arg2)
{
return arg1 / arg2;
}
static vector double
vmax (vector double arg1, vector double arg2)
{
return vec_max (arg1, arg2);
}
static vector double
vmin (vector double arg1, vector double arg2)
{
return vec_min (arg1, arg2);
}
/* 2 argument tests. */
static struct
{
union args result;
union args input[2];
vector double (*func) (vector double, vector double);
const char *name;
} arg2_tests[] = {
/* result */
{ { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd, "vadd" },
{ { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd, "vadd" },
{ { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd2, "vadd2" },
{ { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd2, "vadd2" },
{ { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub, "vsub" },
{ { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub, "vsub" },
{ { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub2, "vsub2" },
{ { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub2, "vsub2" },
{ { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul, "vmul" },
{ { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul2, "vmul2" },
{ { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv, "vdiv" },
{ { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv2, "vdiv2" },
{ { 3.0, 4.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmax, "vmax" },
{ { 1.0, 4.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmax, "vmax" },
{ { 1.0, 2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmin, "vmin" },
{ { -3.0, -2.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmin, "vmin" },
};
static void
test_arg2 (void)
{
unsigned i;
#ifdef DEBUG
printf ("\nTwo argument tests:\n");
#endif
for (i = 0; i < sizeof (arg2_tests) / sizeof (arg2_tests[0]); i++)
{
union args u;
u.vect = arg2_tests[i].func (arg2_tests[i].input[0].vect,
arg2_tests[i].input[1].vect);
#ifdef DEBUG
printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }, { %4g, %4g }\n",
arg2_tests[i].name,
arg2_tests[i].result.scalar[0],
arg2_tests[i].result.scalar[1],
u.scalar[0],
u.scalar[1],
arg2_tests[i].input[0].scalar[0],
arg2_tests[i].input[0].scalar[1],
arg2_tests[i].input[1].scalar[0],
arg2_tests[i].input[1].scalar[1]);
#endif
do_test (&arg2_tests[i].result, &u, arg2_tests[i].name);
}
return;
}
/* Comparisons, returnning a boolean vector. */
static vector bool long
vcmpeq (vector double arg1, vector double arg2)
{
return vec_cmpeq (arg1, arg2);
}
static vector bool long
vcmplt (vector double arg1, vector double arg2)
{
return vec_cmplt (arg1, arg2);
}
static vector bool long
vcmple (vector double arg1, vector double arg2)
{
return vec_cmple (arg1, arg2);
}
static vector bool long
vcmpgt (vector double arg1, vector double arg2)
{
return vec_cmpgt (arg1, arg2);
}
static vector bool long
vcmpge (vector double arg1, vector double arg2)
{
return vec_cmpge (arg1, arg2);
}
#define ONE 0xffffffffffffffffUL
#define ZERO 0x0000000000000000UL
/* comparison tests. */
static struct
{
union largs result;
union args input[2];
vector bool long (*func) (vector double, vector double);
const char *name;
} argcmp_tests[] = {
{ { ONE, ZERO }, { { 1.0, 2.0 }, { 1.0, -2.0 } }, vcmpeq, "vcmpeq" },
{ { ZERO, ONE }, { { -1.0, 2.0 }, { 1.0, 2.0 } }, vcmpeq, "vcmpeq" },
{ { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" },
{ { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmple, "vcmple" },
{ { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" },
{ { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" },
{ { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmplt, "vcmplt" },
{ { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" },
{ { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" },
{ { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpgt, "vcmpgt" },
{ { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" },
{ { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" },
{ { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpge, "vcmpge" },
{ { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" },
};
static void
test_argcmp (void)
{
unsigned i;
#ifdef DEBUG
printf ("\nComparison tests:\n");
#endif
for (i = 0; i < sizeof (argcmp_tests) / sizeof (argcmp_tests[0]); i++)
{
union largs u;
u.vect = argcmp_tests[i].func (argcmp_tests[i].input[0].vect,
argcmp_tests[i].input[1].vect);
#ifdef DEBUG
printf ("test %-16s: expected { 0x%016lx, 0x%016lx }, got { 0x%016lx, 0x%016lx }, input { %4g, %4g }, { %4g, %4g }\n",
argcmp_tests[i].name,
argcmp_tests[i].result.scalar[0],
argcmp_tests[i].result.scalar[1],
u.scalar[0],
u.scalar[1],
argcmp_tests[i].input[0].scalar[0],
argcmp_tests[i].input[0].scalar[1],
argcmp_tests[i].input[1].scalar[0],
argcmp_tests[i].input[1].scalar[1]);
#endif
do_ltest (&argcmp_tests[i].result, &u, argcmp_tests[i].name);
}
return;
}
int
main (int argc, char *argv[])
{
test_arg1 ();
test_arg2 ();
test_argcmp ();
#ifdef DEBUG
if (errors)
{
printf ("There were %d error(s)\n", errors);
return errors;
}
else
printf ("There were no errors\n");
#endif
return 0;
}

View File

@ -0,0 +1,81 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-mvsx -O2" } */
#include <altivec.h>
void foo (vector double *out, vector double *in, vector long *p_l, vector bool long *p_b, vector unsigned char *p_uc, int *i)
{
vector double in0 = in[0];
vector double in1 = in[1];
vector double in2 = in[2];
vector long inl = *p_l;
vector bool long inb = *p_b;
vector unsigned char uc = *p_uc;
*out++ = vec_abs (in0);
*out++ = vec_add (in0, in1);
*out++ = vec_and (in0, in1);
*out++ = vec_and (in0, inb);
*out++ = vec_and (inb, in0);
*out++ = vec_andc (in0, in1);
*out++ = vec_andc (in0, inb);
*out++ = vec_andc (inb, in0);
*out++ = vec_ceil (in0);
*p_b++ = vec_cmpeq (in0, in1);
*p_b++ = vec_cmpgt (in0, in1);
*p_b++ = vec_cmpge (in0, in1);
*p_b++ = vec_cmplt (in0, in1);
*p_b++ = vec_cmple (in0, in1);
*out++ = vec_div (in0, in1);
*out++ = vec_floor (in0);
*out++ = vec_madd (in0, in1, in2);
*out++ = vec_msub (in0, in1, in2);
*out++ = vec_max (in0, in1);
*out++ = vec_min (in0, in1);
*out++ = vec_msub (in0, in1, in2);
*out++ = vec_mul (in0, in1);
*out++ = vec_nearbyint (in0);
*out++ = vec_nmadd (in0, in1, in2);
*out++ = vec_nmsub (in0, in1, in2);
*out++ = vec_nor (in0, in1);
*out++ = vec_or (in0, in1);
*out++ = vec_or (in0, inb);
*out++ = vec_or (inb, in0);
*out++ = vec_perm (in0, in1, uc);
*out++ = vec_rint (in0);
*out++ = vec_sel (in0, in1, inl);
*out++ = vec_sel (in0, in1, inb);
*out++ = vec_sub (in0, in1);
*out++ = vec_sqrt (in0);
*out++ = vec_trunc (in0);
*out++ = vec_xor (in0, in1);
*out++ = vec_xor (in0, inb);
*out++ = vec_xor (inb, in0);
*i++ = vec_all_eq (in0, in1);
*i++ = vec_all_ge (in0, in1);
*i++ = vec_all_gt (in0, in1);
*i++ = vec_all_le (in0, in1);
*i++ = vec_all_lt (in0, in1);
*i++ = vec_all_nan (in0);
*i++ = vec_all_ne (in0, in1);
*i++ = vec_all_nge (in0, in1);
*i++ = vec_all_ngt (in0, in1);
*i++ = vec_all_nle (in0, in1);
*i++ = vec_all_nlt (in0, in1);
*i++ = vec_all_numeric (in0);
*i++ = vec_any_eq (in0, in1);
*i++ = vec_any_ge (in0, in1);
*i++ = vec_any_gt (in0, in1);
*i++ = vec_any_le (in0, in1);
*i++ = vec_any_lt (in0, in1);
*i++ = vec_any_nan (in0);
*i++ = vec_any_ne (in0, in1);
*i++ = vec_any_nge (in0, in1);
*i++ = vec_any_ngt (in0, in1);
*i++ = vec_any_nle (in0, in1);
*i++ = vec_any_nlt (in0, in1);
*i++ = vec_any_numeric (in0);
}

View File

@ -902,6 +902,32 @@ proc check_sse2_hw_available { } {
}] }]
} }
# Return 1 if the target supports executing VSX instructions, 0
# otherwise. Cache the result.
proc check_vsx_hw_available { } {
return [check_cached_effective_target vsx_hw_available {
# Some simulators are known to not support VSX instructions.
# For now, disable on Darwin
if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mvsx"
check_runtime_nocache vsx_hw_available {
int main()
{
#ifdef __MACH__
asm volatile ("xxlor vs0,vs0,vs0");
#else
asm volatile ("xxlor 0,0,0");
#endif
return 0;
}
} $options
}
}]
}
# Return 1 if the target supports executing AltiVec instructions, 0 # Return 1 if the target supports executing AltiVec instructions, 0
# otherwise. Cache the result. # otherwise. Cache the result.
@ -912,12 +938,13 @@ proc check_vmx_hw_available { } {
expr 0 expr 0
} else { } else {
# Most targets don't require special flags for this test case, but # Most targets don't require special flags for this test case, but
# Darwin does. # Darwin does. Just to be sure, make sure VSX is not enabled for
# the altivec tests.
if { [istarget *-*-darwin*] if { [istarget *-*-darwin*]
|| [istarget *-*-aix*] } { || [istarget *-*-aix*] } {
set options "-maltivec" set options "-maltivec -mno-vsx"
} else { } else {
set options "" set options "-mno-vsx"
} }
check_runtime_nocache vmx_hw_available { check_runtime_nocache vmx_hw_available {
int main() int main()
@ -1632,6 +1659,33 @@ proc check_effective_target_powerpc_altivec_ok { } {
} }
} }
# Return 1 if this is a PowerPC target supporting -mvsx
proc check_effective_target_powerpc_vsx_ok { } {
if { ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
|| [istarget powerpc*-*-aix5.1*]
|| [istarget powerpc*-*-aix5.2*] } {
return 0
}
return [check_no_compiler_messages powerpc_vsx_ok object {
int main (void) {
#ifdef __MACH__
asm volatile ("xxlor vs0,vs0,vs0");
#else
asm volatile ("xxlor 0,0,0");
#endif
return 0;
}
} "-mvsx"]
} else {
return 0
}
}
# Return 1 if this is a PowerPC target supporting -mcpu=cell. # Return 1 if this is a PowerPC target supporting -mcpu=cell.
proc check_effective_target_powerpc_ppu_ok { } { proc check_effective_target_powerpc_ppu_ok { } {