mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-16 05:49:56 +08:00
Commit patch #3 of 4 for Power7 VSX support
Co-Authored-By: Pat Haugen <pthaugen@us.ibm.com> Co-Authored-By: Revital Eres <eres@il.ibm.com> From-SVN: r150018
This commit is contained in:
parent
2304116044
commit
a72c65c754
@ -1,3 +1,12 @@
|
||||
2009-07-17 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR boehm-gc/40785
|
||||
* include/private/gc_locks.h (GC_test_and_set): If GCC 4.4, use
|
||||
the __sync_lock_test_and _set and __sync_lock_release builtins on
|
||||
the powerpc. If not GCC 4.4, fix up the constraints so that it
|
||||
builds without error.
|
||||
(GC_clear): Ditto.
|
||||
|
||||
2009-07-17 Kai Tietz <kai.tietz@onevision.com>
|
||||
|
||||
* configure.ac: Add rule for mingw targets to add -DGC_BUILD=1 to
|
||||
|
@ -139,49 +139,35 @@
|
||||
# define GC_TEST_AND_SET_DEFINED
|
||||
# endif
|
||||
# if defined(POWERPC)
|
||||
# if 0 /* CPP_WORDSZ == 64 totally broken to use int locks with ldarx */
|
||||
inline static int GC_test_and_set(volatile unsigned int *addr) {
|
||||
unsigned long oldval;
|
||||
unsigned long temp = 1; /* locked value */
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\tldarx %0,0,%3\n" /* load and reserve */
|
||||
"\tcmpdi %0, 0\n" /* if load is */
|
||||
"\tbne 2f\n" /* non-zero, return already set */
|
||||
"\tstdcx. %2,0,%1\n" /* else store conditional */
|
||||
"\tbne- 1b\n" /* retry if lost reservation */
|
||||
"\tsync\n" /* import barrier */
|
||||
"2:\t\n" /* oldval is zero if we set */
|
||||
: "=&r"(oldval), "=p"(addr)
|
||||
: "r"(temp), "1"(addr)
|
||||
: "cr0","memory");
|
||||
return (int)oldval;
|
||||
}
|
||||
# define GC_TEST_AND_SET_DEFINED
|
||||
# define GC_CLEAR_DEFINED
|
||||
# if (__GNUC__>4)||((__GNUC__==4)&&(__GNUC_MINOR__>=4))
|
||||
# define GC_test_and_set(addr) __sync_lock_test_and_set (addr, 1)
|
||||
# define GC_clear(addr) __sync_lock_release (addr)
|
||||
# else
|
||||
inline static int GC_test_and_set(volatile unsigned int *addr) {
|
||||
int oldval;
|
||||
int temp = 1; /* locked value */
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1:\tlwarx %0,0,%3\n" /* load and reserve */
|
||||
"\n1:\n"
|
||||
"\tlwarx %0,%y3\n" /* load and reserve, 32-bits */
|
||||
"\tcmpwi %0, 0\n" /* if load is */
|
||||
"\tbne 2f\n" /* non-zero, return already set */
|
||||
"\tstwcx. %2,0,%1\n" /* else store conditional */
|
||||
"\tstwcx. %2,%y3\n" /* else store conditional */
|
||||
"\tbne- 1b\n" /* retry if lost reservation */
|
||||
"\tsync\n" /* import barrier */
|
||||
"2:\t\n" /* oldval is zero if we set */
|
||||
: "=&r"(oldval), "=p"(addr)
|
||||
: "r"(temp), "1"(addr)
|
||||
: "=&r"(oldval), "=m"(addr)
|
||||
: "r"(temp), "Z"(addr)
|
||||
: "cr0","memory");
|
||||
return oldval;
|
||||
}
|
||||
# endif
|
||||
# define GC_TEST_AND_SET_DEFINED
|
||||
inline static void GC_clear(volatile unsigned int *addr) {
|
||||
__asm__ __volatile__("lwsync" : : : "memory");
|
||||
*(addr) = 0;
|
||||
}
|
||||
# define GC_CLEAR_DEFINED
|
||||
# endif
|
||||
# endif
|
||||
# if defined(ALPHA)
|
||||
inline static int GC_test_and_set(volatile unsigned int * addr)
|
||||
|
185
gcc/ChangeLog
185
gcc/ChangeLog
@ -1,3 +1,188 @@
|
||||
2009-07-22 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
Pat Haugen <pthaugen@us.ibm.com>
|
||||
Revital Eres <ERES@il.ibm.com>
|
||||
|
||||
* config/rs6000/vector.md: New file. Move most of the vector
|
||||
expander support here from altivec.md to allow for the VSX vector
|
||||
unit in the future. Add support for secondary_reload patterns.
|
||||
Rewrite the patterns for vector comparison, and vector comparison
|
||||
predicate instructions so that the RTL expresses the desired
|
||||
behavior, instead of using unspec.
|
||||
|
||||
* config/rs6000/constraints.md ("f" constraint): Use
|
||||
rs6000_constraints to hold the precalculated register class.
|
||||
("d" constraint): Ditto.
|
||||
("wd" constraint): New constraint for VSX.
|
||||
("wf" constraint): Ditto.
|
||||
("ws" constraint): Ditto.
|
||||
("wa" constraint): Ditto.
|
||||
("wZ" constraint): Ditto.
|
||||
("j" constraint): Ditto.
|
||||
|
||||
* config/rs6000/predicates.md (vsx_register_operand): New
|
||||
predicate for VSX.
|
||||
(vfloat_operand): New predicate for vector.md.
|
||||
(vint_operand): Ditto.
|
||||
(vlogical_operand): Ditto.
|
||||
(easy_fp_constant): If VSX, 0.0 is an easy constant.
|
||||
(easy_vector_constant): Add VSX support.
|
||||
(altivec_indexed_or_indirect_operand): New predicate for
|
||||
recognizing Altivec style memory references with AND -16.
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_vector_reload): New static global
|
||||
for vector secondary reload support.
|
||||
(rs6000_vector_reg_class): Delete, replacing it with rs6000_constraints.
|
||||
(rs6000_vsx_reg_class): Ditto.
|
||||
(rs6000_constraints): New array to hold the register classes of
|
||||
each of the register constraints that can vary at runtime.
|
||||
(builtin_mode_to_type): New static array for builtin function type
|
||||
creation.
|
||||
(builtin_hash_table): New static hash table for builtin function
|
||||
type creation.
|
||||
(TARGET_SECONDARY_RELOAD): Define target hook.
|
||||
(TARGET_IRA_COVER_CLASSES): Ditto.
|
||||
(rs6000_hard_regno_nregs_internal): If -mvsx, floating point
|
||||
registers are 128 bits if VSX memory reference instructions are
|
||||
used.
|
||||
(rs6000_hard_regno_mode_ok): For VSX, only check if the VSX memory
|
||||
unit is being used.
|
||||
(rs6000_debug_vector_unit): Move into rs6000_debug_reg_global.
|
||||
(rs6000_debug_reg_global): Move -mdebug=reg statements here.
|
||||
Print several of the scheduling related parameters.
|
||||
(rs6000_init_hard_regno_mode_ok): Switch to putting constraints in
|
||||
rs6000_constraints instead of rs6000_vector_reg_class. Move
|
||||
-mdebug=reg code to rs6000_debug_reg_global. Add support for
|
||||
-mvsx-align-128 debug switch. Drop testing float_p if VSX or
|
||||
Altivec. Add VSX support. Setup for secondary reload support on
|
||||
Altivec/VSX registers.
|
||||
(rs6000_override_options): Make power7 set the scheduling groups
|
||||
like the power5. Add support for new debug switches to override
|
||||
the scheduling defaults. Temporarily disable -mcpu=power7 from
|
||||
setting -mvsx. Add support for debug switches -malways-hint,
|
||||
-msched-groups, and -malign-branch-targets.
|
||||
(rs6000_buitlin_conversion): Add support for returning unsigned
|
||||
vector conversion functions to fix regressions due to stricter
|
||||
type checking.
|
||||
(rs6000_builtin_mul_widen_even): Ditto.
|
||||
(rs6000_builtin_mul_widen_odd): Ditto.
|
||||
(rs6000_builtin_vec_perm): Ditto.
|
||||
(rs6000_vec_const_move): On VSX, use xxlxor to clear register.
|
||||
(rs6000_expand_vector_init): Initial VSX support for using xxlxor
|
||||
to zero a register.
|
||||
(rs6000_emit_move): Fixup invalid const symbol_ref+reg that is
|
||||
generated upstream.
|
||||
(bdesc_3arg): Add builtins for unsigned types. Add builtins for
|
||||
VSX types for bit operations. Changes to accomidate vector.md.
|
||||
(bdesc_2arg): Ditto.
|
||||
(bdesc_1arg): Ditto.
|
||||
(struct builtin_description_predicates): Rewrite predicate
|
||||
handling so that RTL describes the operation, instead of passing
|
||||
the instruction to be used as a string argument.
|
||||
(bdesc_altivec_preds): Ditto.
|
||||
(altivec_expand_predicate_builtin): Ditto.
|
||||
(altivec_expand_builtin): Ditto.
|
||||
(rs6000_expand_ternop_builtin): Use a switch instead of an if
|
||||
statement for vsldoi support.
|
||||
(altivec_expand_ld_builtin): Change to use new names from
|
||||
vector.md.
|
||||
(altivec_expand_st_builtin): Ditto.
|
||||
(paired_expand_builtin): Whitespace changes.
|
||||
(rs6000_init_builtins): Add V2DF/V2DI types. Initialize the
|
||||
builtin_mode_to_type table for secondary reload. Call
|
||||
builtin_function_type to build random builtin functions.
|
||||
(altivec_init_builtins): Change to use builtin_function_type to
|
||||
create builtin function types dynamically as we need them.
|
||||
(builtin_hash_function): New support for hashing the tree types
|
||||
for builtin function as we need it, rather than trying to build
|
||||
all of the trees that we need. Add initial preliminary VSX
|
||||
support.
|
||||
(builtin_function_type): Ditto.
|
||||
(builtin_function_eq): Ditto.
|
||||
(builtin_hash_struct): Ditto.
|
||||
(rs6000_init_builtins): Ditto.
|
||||
(rs6000_common_init_builtins): Ditto.
|
||||
(altivec_init_builtins): Ditto.
|
||||
(rs6000_common_init_builtins): Ditto.
|
||||
(enum reload_reg_type): New enum for simplifing reg classes.
|
||||
(rs6000_reload_register_type): Simplify register classes into GPR,
|
||||
Vector, and other registers.
|
||||
Altivec and VSX addresses in reload.
|
||||
(rs6000_secondary_reload_inner): Ditto.
|
||||
(rs6000_ira_cover_classes): New target hook, that returns the
|
||||
appropriate cover classes, based on -mvsx being used or not.
|
||||
(rs6000_secondary_reload_class): Add VSX support.
|
||||
(get_vec_cmp_insn): Delete, rewrite vector conditionals.
|
||||
(get_vsel_insn): Ditto.
|
||||
(rs6000_emit_vector_compare): Rewrite vector conditional support
|
||||
so that where we can, we use RTL operators, instead of blindly use
|
||||
UNSPEC.
|
||||
(rs6000_emit_vector_select): Ditto.
|
||||
(rs6000_emit_vector_cond_expr): Ditto.
|
||||
(rs6000_emit_minmax): Directly generate min/max under altivec,
|
||||
vsx.
|
||||
(create_TOC_reference): Add -mdebug=addr support.
|
||||
(emit_frame_save): VSX loads/stores need register indexed
|
||||
addressing.
|
||||
|
||||
* config/rs6000/rs6000.md: Include vector.md.
|
||||
|
||||
* config/rs6000/t-rs6000 (MD_INCLUDES): Add vector.md.
|
||||
|
||||
* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
|
||||
support for V2DI, V2DF in logical, permute, select operations.
|
||||
|
||||
* config/rs6000/rs6000.opt (-mvsx-scalar-double): Add new debug
|
||||
switch for vsx/power7.
|
||||
(-mvsx-scalar-memory): Ditto.
|
||||
(-mvsx-align-128): Ditto.
|
||||
(-mallow-movmisalign): Ditto.
|
||||
(-mallow-df-permute): Ditto.
|
||||
(-msched-groups): Ditto.
|
||||
(-malways-hint): Ditto.
|
||||
(-malign-branch-targets): Ditto.
|
||||
|
||||
* config/rs6000/rs6000.h (IRA_COVER_CLASSES): Delete, use target
|
||||
hook instead.
|
||||
(IRA_COVER_CLASSES_PRE_VSX): Cover classes if not -mvsx.
|
||||
(IRA_COVER_CLASSES_VSX): Cover classes if -mvsx.
|
||||
(rs6000_vector_reg_class): Delete.
|
||||
(rs6000_vsx_reg_class): Ditto.
|
||||
(enum rs6000_reg_class_enum): New enum for the constraints that
|
||||
vary based on target switches.
|
||||
(rs6000_constraints): New array to hold the register class for all
|
||||
of the register constraints that vary based on the switches used.
|
||||
(ALTIVEC_BUILTIN_*_UNS): Add unsigned builtin functions.
|
||||
(enum rs6000_builtins): Add unsigned varients for the builtin
|
||||
declarations returned by target hooks for expanding multiplies,
|
||||
select, and permute operations. Add VSX builtins.
|
||||
(enum rs6000_builtin_type_index): Add entries for VSX.
|
||||
(V2DI_type_node): Ditto.
|
||||
(V2DF_type_node): Ditto.
|
||||
(unsigned_V2DI_type_node): Ditto.
|
||||
(bool_long_type_node): Ditto.
|
||||
(intDI_type_internal_node): Ditto.
|
||||
(uintDI_type_internal_node): Ditto.
|
||||
(double_type_internal_node): Ditto.
|
||||
|
||||
* config/rs6000/altivec.md (whole file): Move all expanders to
|
||||
vector.md from altivec.md. Rename insn matching functions to be
|
||||
altivec_foo.
|
||||
(UNSPEC_VCMP*): Delete, rewrite vector comparisons.
|
||||
(altivec_vcmp*): Ditto.
|
||||
(UNSPEC_VPERM_UNS): New, add for unsigned types using vperm.
|
||||
(VM): New iterator for moves that includes the VSX types.
|
||||
(altivec_vperm_<mode>): Add VSX types. Add unsigned types.
|
||||
(altivec_vperm_<mode>_uns): New, for unsigned types.
|
||||
(altivec_vsel_*): Rewrite vector comparisons and predicate
|
||||
builtins.
|
||||
(altivec_eq<mode>): Ditto.
|
||||
(altivec_gt<mode>): Ditto.
|
||||
(altivec_gtu<mode>): Ditto.
|
||||
(altivec_eqv4sf): Ditto.
|
||||
(altivec_gev4sf): Ditto.
|
||||
(altivec_gtv4sf): Ditto.
|
||||
(altivec_vcmpbfp_p): Ditto.
|
||||
|
||||
2009-07-23 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
(split for ior/xor with shift and zero-extend): Cast op3 to
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,14 +17,14 @@
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;; Available constraint letters: "e", "k", "u", "A", "B", "C", "D"
|
||||
|
||||
;; Register constraints
|
||||
|
||||
(define_register_constraint "f" "TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
? FLOAT_REGS : NO_REGS"
|
||||
(define_register_constraint "f" "rs6000_constraints[RS6000_CONSTRAINT_f]"
|
||||
"@internal")
|
||||
|
||||
(define_register_constraint "d" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
? FLOAT_REGS : NO_REGS"
|
||||
(define_register_constraint "d" "rs6000_constraints[RS6000_CONSTRAINT_d]"
|
||||
"@internal")
|
||||
|
||||
(define_register_constraint "b" "BASE_REGS"
|
||||
@ -54,6 +54,28 @@
|
||||
(define_register_constraint "z" "XER_REGS"
|
||||
"@internal")
|
||||
|
||||
;; Use w as a prefix to add VSX modes
|
||||
;; vector double (V2DF)
|
||||
(define_register_constraint "wd" "rs6000_constraints[RS6000_CONSTRAINT_wd]"
|
||||
"@internal")
|
||||
|
||||
;; vector float (V4SF)
|
||||
(define_register_constraint "wf" "rs6000_constraints[RS6000_CONSTRAINT_wf]"
|
||||
"@internal")
|
||||
|
||||
;; scalar double (DF)
|
||||
(define_register_constraint "ws" "rs6000_constraints[RS6000_CONSTRAINT_ws]"
|
||||
"@internal")
|
||||
|
||||
;; any VSX register
|
||||
(define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]"
|
||||
"@internal")
|
||||
|
||||
;; Altivec style load/store that ignores the bottom bits of the address
|
||||
(define_memory_constraint "wZ"
|
||||
"Indexed or indirect memory operand, ignoring the bottom 4 bits"
|
||||
(match_operand 0 "altivec_indexed_or_indirect_operand"))
|
||||
|
||||
;; Integer constraints
|
||||
|
||||
(define_constraint "I"
|
||||
@ -173,3 +195,7 @@ usually better to use @samp{m} or @samp{es} in @code{asm} statements)"
|
||||
(define_constraint "W"
|
||||
"vector constant that does not require memory"
|
||||
(match_operand 0 "easy_vector_constant"))
|
||||
|
||||
(define_constraint "j"
|
||||
"Zero vector constant"
|
||||
(match_test "(op == const0_rtx || op == CONST0_RTX (GET_MODE (op)))"))
|
||||
|
@ -38,6 +38,37 @@
|
||||
|| ALTIVEC_REGNO_P (REGNO (op))
|
||||
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
|
||||
|
||||
;; Return 1 if op is a VSX register.
|
||||
(define_predicate "vsx_register_operand"
|
||||
(and (match_operand 0 "register_operand")
|
||||
(match_test "GET_CODE (op) != REG
|
||||
|| VSX_REGNO_P (REGNO (op))
|
||||
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
|
||||
|
||||
;; Return 1 if op is a vector register that operates on floating point vectors
|
||||
;; (either altivec or VSX).
|
||||
(define_predicate "vfloat_operand"
|
||||
(and (match_operand 0 "register_operand")
|
||||
(match_test "GET_CODE (op) != REG
|
||||
|| VFLOAT_REGNO_P (REGNO (op))
|
||||
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
|
||||
|
||||
;; Return 1 if op is a vector register that operates on integer vectors
|
||||
;; (only altivec, VSX doesn't support integer vectors)
|
||||
(define_predicate "vint_operand"
|
||||
(and (match_operand 0 "register_operand")
|
||||
(match_test "GET_CODE (op) != REG
|
||||
|| VINT_REGNO_P (REGNO (op))
|
||||
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
|
||||
|
||||
;; Return 1 if op is a vector register to do logical operations on (and, or,
|
||||
;; xor, etc.)
|
||||
(define_predicate "vlogical_operand"
|
||||
(and (match_operand 0 "register_operand")
|
||||
(match_test "GET_CODE (op) != REG
|
||||
|| VLOGICAL_REGNO_P (REGNO (op))
|
||||
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
|
||||
|
||||
;; Return 1 if op is XER register.
|
||||
(define_predicate "xer_operand"
|
||||
(and (match_code "reg")
|
||||
@ -234,6 +265,10 @@
|
||||
&& num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
|
||||
|
||||
case DFmode:
|
||||
/* The constant 0.f is easy under VSX. */
|
||||
if (op == CONST0_RTX (DFmode) && VECTOR_UNIT_VSX_P (DFmode))
|
||||
return 1;
|
||||
|
||||
/* Force constants to memory before reload to utilize
|
||||
compress_float_constant.
|
||||
Avoid this when flag_unsafe_math_optimizations is enabled
|
||||
@ -292,6 +327,9 @@
|
||||
if (TARGET_PAIRED_FLOAT)
|
||||
return false;
|
||||
|
||||
if ((VSX_VECTOR_MODE (mode) || mode == TImode) && zero_constant (op, mode))
|
||||
return true;
|
||||
|
||||
if (ALTIVEC_VECTOR_MODE (mode))
|
||||
{
|
||||
if (zero_constant (op, mode))
|
||||
@ -394,16 +432,36 @@
|
||||
(match_code "mem")
|
||||
{
|
||||
op = XEXP (op, 0);
|
||||
if (TARGET_ALTIVEC
|
||||
&& ALTIVEC_VECTOR_MODE (mode)
|
||||
if (VECTOR_MEM_ALTIVEC_P (mode)
|
||||
&& GET_CODE (op) == AND
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (op, 1)) == -16)
|
||||
op = XEXP (op, 0);
|
||||
|
||||
else if (VECTOR_MEM_VSX_P (mode)
|
||||
&& GET_CODE (op) == PRE_MODIFY)
|
||||
op = XEXP (op, 1);
|
||||
|
||||
return indexed_or_indirect_address (op, mode);
|
||||
})
|
||||
|
||||
;; Return 1 if the operand is an indexed or indirect memory operand with an
|
||||
;; AND -16 in it, used to recognize when we need to switch to Altivec loads
|
||||
;; to realign loops instead of VSX (altivec silently ignores the bottom bits,
|
||||
;; while VSX uses the full address and traps)
|
||||
(define_predicate "altivec_indexed_or_indirect_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
op = XEXP (op, 0);
|
||||
if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
|
||||
&& GET_CODE (op) == AND
|
||||
&& GET_CODE (XEXP (op, 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (op, 1)) == -16)
|
||||
return indexed_or_indirect_address (XEXP (op, 0), mode);
|
||||
|
||||
return 0;
|
||||
})
|
||||
|
||||
;; Return 1 if the operand is an indexed or indirect address.
|
||||
(define_special_predicate "indexed_or_indirect_address"
|
||||
(and (match_test "REG_P (op)
|
||||
|
@ -670,6 +670,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
|
||||
@ -718,6 +724,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
|
||||
@ -1482,6 +1494,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
|
||||
@ -1506,6 +1520,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
|
||||
@ -2122,6 +2142,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
|
||||
@ -2366,6 +2392,10 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI },
|
||||
{ ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
|
||||
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI },
|
||||
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI },
|
||||
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SF,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI },
|
||||
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI,
|
||||
@ -2392,10 +2422,28 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||
RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI },
|
||||
{ ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI,
|
||||
RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
|
||||
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI },
|
||||
{ ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1280,11 +1280,23 @@ enum reg_class
|
||||
purpose. Any move between two registers of a cover class should be
|
||||
cheaper than load or store of the registers. The macro value is
|
||||
array of register classes with LIM_REG_CLASSES used as the end
|
||||
marker. */
|
||||
marker.
|
||||
|
||||
#define IRA_COVER_CLASSES \
|
||||
We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
|
||||
account for the Altivec and Floating registers being subsets of the VSX
|
||||
register set. */
|
||||
|
||||
#define IRA_COVER_CLASSES_PRE_VSX \
|
||||
{ \
|
||||
GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, \
|
||||
GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, /* VSX_REGS, */ \
|
||||
/* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
|
||||
/* MQ_REGS, LINK_REGS, CTR_REGS, */ \
|
||||
CR_REGS, XER_REGS, LIM_REG_CLASSES \
|
||||
}
|
||||
|
||||
#define IRA_COVER_CLASSES_VSX \
|
||||
{ \
|
||||
GENERAL_REGS, SPECIAL_REGS, /* FLOAT_REGS, ALTIVEC_REGS, */ VSX_REGS, \
|
||||
/* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
|
||||
/* MQ_REGS, LINK_REGS, CTR_REGS, */ \
|
||||
CR_REGS, XER_REGS, LIM_REG_CLASSES \
|
||||
@ -1306,9 +1318,20 @@ extern enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
|
||||
#define REGNO_REG_CLASS(REGNO) rs6000_regno_regclass[(REGNO)]
|
||||
#endif
|
||||
|
||||
/* Register classes for altivec registers (and eventually other vector
|
||||
units). */
|
||||
extern enum reg_class rs6000_vector_reg_class[];
|
||||
/* Register classes for various constraints that are based on the target
|
||||
switches. */
|
||||
enum r6000_reg_class_enum {
|
||||
RS6000_CONSTRAINT_d, /* fpr registers for double values */
|
||||
RS6000_CONSTRAINT_f, /* fpr registers for single values */
|
||||
RS6000_CONSTRAINT_v, /* Altivec registers */
|
||||
RS6000_CONSTRAINT_wa, /* Any VSX register */
|
||||
RS6000_CONSTRAINT_wd, /* VSX register for V2DF */
|
||||
RS6000_CONSTRAINT_wf, /* VSX register for V4SF */
|
||||
RS6000_CONSTRAINT_ws, /* VSX register for DF */
|
||||
RS6000_CONSTRAINT_MAX
|
||||
};
|
||||
|
||||
extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
|
||||
|
||||
/* The class value for index registers, and the one for base regs. */
|
||||
#define INDEX_REG_CLASS GENERAL_REGS
|
||||
@ -2493,24 +2516,40 @@ enum rs6000_builtins
|
||||
ALTIVEC_BUILTIN_VMINSW,
|
||||
ALTIVEC_BUILTIN_VMINFP,
|
||||
ALTIVEC_BUILTIN_VMULEUB,
|
||||
ALTIVEC_BUILTIN_VMULEUB_UNS,
|
||||
ALTIVEC_BUILTIN_VMULESB,
|
||||
ALTIVEC_BUILTIN_VMULEUH,
|
||||
ALTIVEC_BUILTIN_VMULEUH_UNS,
|
||||
ALTIVEC_BUILTIN_VMULESH,
|
||||
ALTIVEC_BUILTIN_VMULOUB,
|
||||
ALTIVEC_BUILTIN_VMULOUB_UNS,
|
||||
ALTIVEC_BUILTIN_VMULOSB,
|
||||
ALTIVEC_BUILTIN_VMULOUH,
|
||||
ALTIVEC_BUILTIN_VMULOUH_UNS,
|
||||
ALTIVEC_BUILTIN_VMULOSH,
|
||||
ALTIVEC_BUILTIN_VNMSUBFP,
|
||||
ALTIVEC_BUILTIN_VNOR,
|
||||
ALTIVEC_BUILTIN_VOR,
|
||||
ALTIVEC_BUILTIN_VSEL_2DF, /* needed for VSX */
|
||||
ALTIVEC_BUILTIN_VSEL_2DI, /* needed for VSX */
|
||||
ALTIVEC_BUILTIN_VSEL_4SI,
|
||||
ALTIVEC_BUILTIN_VSEL_4SF,
|
||||
ALTIVEC_BUILTIN_VSEL_8HI,
|
||||
ALTIVEC_BUILTIN_VSEL_16QI,
|
||||
ALTIVEC_BUILTIN_VSEL_2DI_UNS,
|
||||
ALTIVEC_BUILTIN_VSEL_4SI_UNS,
|
||||
ALTIVEC_BUILTIN_VSEL_8HI_UNS,
|
||||
ALTIVEC_BUILTIN_VSEL_16QI_UNS,
|
||||
ALTIVEC_BUILTIN_VPERM_2DF, /* needed for VSX */
|
||||
ALTIVEC_BUILTIN_VPERM_2DI, /* needed for VSX */
|
||||
ALTIVEC_BUILTIN_VPERM_4SI,
|
||||
ALTIVEC_BUILTIN_VPERM_4SF,
|
||||
ALTIVEC_BUILTIN_VPERM_8HI,
|
||||
ALTIVEC_BUILTIN_VPERM_16QI,
|
||||
ALTIVEC_BUILTIN_VPERM_2DI_UNS,
|
||||
ALTIVEC_BUILTIN_VPERM_4SI_UNS,
|
||||
ALTIVEC_BUILTIN_VPERM_8HI_UNS,
|
||||
ALTIVEC_BUILTIN_VPERM_16QI_UNS,
|
||||
ALTIVEC_BUILTIN_VPKUHUM,
|
||||
ALTIVEC_BUILTIN_VPKUWUM,
|
||||
ALTIVEC_BUILTIN_VPKPX,
|
||||
@ -3138,6 +3177,219 @@ enum rs6000_builtins
|
||||
RS6000_BUILTIN_RSQRTF,
|
||||
RS6000_BUILTIN_BSWAP_HI,
|
||||
|
||||
/* VSX builtins. */
|
||||
VSX_BUILTIN_LXSDUX,
|
||||
VSX_BUILTIN_LXSDX,
|
||||
VSX_BUILTIN_LXVD2UX,
|
||||
VSX_BUILTIN_LXVD2X,
|
||||
VSX_BUILTIN_LXVDSX,
|
||||
VSX_BUILTIN_LXVW4UX,
|
||||
VSX_BUILTIN_LXVW4X,
|
||||
VSX_BUILTIN_STXSDUX,
|
||||
VSX_BUILTIN_STXSDX,
|
||||
VSX_BUILTIN_STXVD2UX,
|
||||
VSX_BUILTIN_STXVD2X,
|
||||
VSX_BUILTIN_STXVW4UX,
|
||||
VSX_BUILTIN_STXVW4X,
|
||||
VSX_BUILTIN_XSABSDP,
|
||||
VSX_BUILTIN_XSADDDP,
|
||||
VSX_BUILTIN_XSCMPODP,
|
||||
VSX_BUILTIN_XSCMPUDP,
|
||||
VSX_BUILTIN_XSCPSGNDP,
|
||||
VSX_BUILTIN_XSCVDPSP,
|
||||
VSX_BUILTIN_XSCVDPSXDS,
|
||||
VSX_BUILTIN_XSCVDPSXWS,
|
||||
VSX_BUILTIN_XSCVDPUXDS,
|
||||
VSX_BUILTIN_XSCVDPUXWS,
|
||||
VSX_BUILTIN_XSCVSPDP,
|
||||
VSX_BUILTIN_XSCVSXDDP,
|
||||
VSX_BUILTIN_XSCVUXDDP,
|
||||
VSX_BUILTIN_XSDIVDP,
|
||||
VSX_BUILTIN_XSMADDADP,
|
||||
VSX_BUILTIN_XSMADDMDP,
|
||||
VSX_BUILTIN_XSMAXDP,
|
||||
VSX_BUILTIN_XSMINDP,
|
||||
VSX_BUILTIN_XSMOVDP,
|
||||
VSX_BUILTIN_XSMSUBADP,
|
||||
VSX_BUILTIN_XSMSUBMDP,
|
||||
VSX_BUILTIN_XSMULDP,
|
||||
VSX_BUILTIN_XSNABSDP,
|
||||
VSX_BUILTIN_XSNEGDP,
|
||||
VSX_BUILTIN_XSNMADDADP,
|
||||
VSX_BUILTIN_XSNMADDMDP,
|
||||
VSX_BUILTIN_XSNMSUBADP,
|
||||
VSX_BUILTIN_XSNMSUBMDP,
|
||||
VSX_BUILTIN_XSRDPI,
|
||||
VSX_BUILTIN_XSRDPIC,
|
||||
VSX_BUILTIN_XSRDPIM,
|
||||
VSX_BUILTIN_XSRDPIP,
|
||||
VSX_BUILTIN_XSRDPIZ,
|
||||
VSX_BUILTIN_XSREDP,
|
||||
VSX_BUILTIN_XSRSQRTEDP,
|
||||
VSX_BUILTIN_XSSQRTDP,
|
||||
VSX_BUILTIN_XSSUBDP,
|
||||
VSX_BUILTIN_XSTDIVDP_FE,
|
||||
VSX_BUILTIN_XSTDIVDP_FG,
|
||||
VSX_BUILTIN_XSTSQRTDP_FE,
|
||||
VSX_BUILTIN_XSTSQRTDP_FG,
|
||||
VSX_BUILTIN_XVABSDP,
|
||||
VSX_BUILTIN_XVABSSP,
|
||||
VSX_BUILTIN_XVADDDP,
|
||||
VSX_BUILTIN_XVADDSP,
|
||||
VSX_BUILTIN_XVCMPEQDP,
|
||||
VSX_BUILTIN_XVCMPEQSP,
|
||||
VSX_BUILTIN_XVCMPGEDP,
|
||||
VSX_BUILTIN_XVCMPGESP,
|
||||
VSX_BUILTIN_XVCMPGTDP,
|
||||
VSX_BUILTIN_XVCMPGTSP,
|
||||
VSX_BUILTIN_XVCMPEQDP_P,
|
||||
VSX_BUILTIN_XVCMPEQSP_P,
|
||||
VSX_BUILTIN_XVCMPGEDP_P,
|
||||
VSX_BUILTIN_XVCMPGESP_P,
|
||||
VSX_BUILTIN_XVCMPGTDP_P,
|
||||
VSX_BUILTIN_XVCMPGTSP_P,
|
||||
VSX_BUILTIN_XVCPSGNDP,
|
||||
VSX_BUILTIN_XVCPSGNSP,
|
||||
VSX_BUILTIN_XVCVDPSP,
|
||||
VSX_BUILTIN_XVCVDPSXDS,
|
||||
VSX_BUILTIN_XVCVDPSXWS,
|
||||
VSX_BUILTIN_XVCVDPUXDS,
|
||||
VSX_BUILTIN_XVCVDPUXDS_UNS,
|
||||
VSX_BUILTIN_XVCVDPUXWS,
|
||||
VSX_BUILTIN_XVCVSPDP,
|
||||
VSX_BUILTIN_XVCVSPSXDS,
|
||||
VSX_BUILTIN_XVCVSPSXWS,
|
||||
VSX_BUILTIN_XVCVSPUXDS,
|
||||
VSX_BUILTIN_XVCVSPUXWS,
|
||||
VSX_BUILTIN_XVCVSXDDP,
|
||||
VSX_BUILTIN_XVCVSXDSP,
|
||||
VSX_BUILTIN_XVCVSXWDP,
|
||||
VSX_BUILTIN_XVCVSXWSP,
|
||||
VSX_BUILTIN_XVCVUXDDP,
|
||||
VSX_BUILTIN_XVCVUXDDP_UNS,
|
||||
VSX_BUILTIN_XVCVUXDSP,
|
||||
VSX_BUILTIN_XVCVUXWDP,
|
||||
VSX_BUILTIN_XVCVUXWSP,
|
||||
VSX_BUILTIN_XVDIVDP,
|
||||
VSX_BUILTIN_XVDIVSP,
|
||||
VSX_BUILTIN_XVMADDDP,
|
||||
VSX_BUILTIN_XVMADDSP,
|
||||
VSX_BUILTIN_XVMAXDP,
|
||||
VSX_BUILTIN_XVMAXSP,
|
||||
VSX_BUILTIN_XVMINDP,
|
||||
VSX_BUILTIN_XVMINSP,
|
||||
VSX_BUILTIN_XVMSUBDP,
|
||||
VSX_BUILTIN_XVMSUBSP,
|
||||
VSX_BUILTIN_XVMULDP,
|
||||
VSX_BUILTIN_XVMULSP,
|
||||
VSX_BUILTIN_XVNABSDP,
|
||||
VSX_BUILTIN_XVNABSSP,
|
||||
VSX_BUILTIN_XVNEGDP,
|
||||
VSX_BUILTIN_XVNEGSP,
|
||||
VSX_BUILTIN_XVNMADDDP,
|
||||
VSX_BUILTIN_XVNMADDSP,
|
||||
VSX_BUILTIN_XVNMSUBDP,
|
||||
VSX_BUILTIN_XVNMSUBSP,
|
||||
VSX_BUILTIN_XVRDPI,
|
||||
VSX_BUILTIN_XVRDPIC,
|
||||
VSX_BUILTIN_XVRDPIM,
|
||||
VSX_BUILTIN_XVRDPIP,
|
||||
VSX_BUILTIN_XVRDPIZ,
|
||||
VSX_BUILTIN_XVREDP,
|
||||
VSX_BUILTIN_XVRESP,
|
||||
VSX_BUILTIN_XVRSPI,
|
||||
VSX_BUILTIN_XVRSPIC,
|
||||
VSX_BUILTIN_XVRSPIM,
|
||||
VSX_BUILTIN_XVRSPIP,
|
||||
VSX_BUILTIN_XVRSPIZ,
|
||||
VSX_BUILTIN_XVRSQRTEDP,
|
||||
VSX_BUILTIN_XVRSQRTESP,
|
||||
VSX_BUILTIN_XVSQRTDP,
|
||||
VSX_BUILTIN_XVSQRTSP,
|
||||
VSX_BUILTIN_XVSUBDP,
|
||||
VSX_BUILTIN_XVSUBSP,
|
||||
VSX_BUILTIN_XVTDIVDP_FE,
|
||||
VSX_BUILTIN_XVTDIVDP_FG,
|
||||
VSX_BUILTIN_XVTDIVSP_FE,
|
||||
VSX_BUILTIN_XVTDIVSP_FG,
|
||||
VSX_BUILTIN_XVTSQRTDP_FE,
|
||||
VSX_BUILTIN_XVTSQRTDP_FG,
|
||||
VSX_BUILTIN_XVTSQRTSP_FE,
|
||||
VSX_BUILTIN_XVTSQRTSP_FG,
|
||||
VSX_BUILTIN_XXSEL_2DI,
|
||||
VSX_BUILTIN_XXSEL_2DF,
|
||||
VSX_BUILTIN_XXSEL_4SI,
|
||||
VSX_BUILTIN_XXSEL_4SF,
|
||||
VSX_BUILTIN_XXSEL_8HI,
|
||||
VSX_BUILTIN_XXSEL_16QI,
|
||||
VSX_BUILTIN_XXSEL_2DI_UNS,
|
||||
VSX_BUILTIN_XXSEL_4SI_UNS,
|
||||
VSX_BUILTIN_XXSEL_8HI_UNS,
|
||||
VSX_BUILTIN_XXSEL_16QI_UNS,
|
||||
VSX_BUILTIN_VPERM_2DI,
|
||||
VSX_BUILTIN_VPERM_2DF,
|
||||
VSX_BUILTIN_VPERM_4SI,
|
||||
VSX_BUILTIN_VPERM_4SF,
|
||||
VSX_BUILTIN_VPERM_8HI,
|
||||
VSX_BUILTIN_VPERM_16QI,
|
||||
VSX_BUILTIN_VPERM_2DI_UNS,
|
||||
VSX_BUILTIN_VPERM_4SI_UNS,
|
||||
VSX_BUILTIN_VPERM_8HI_UNS,
|
||||
VSX_BUILTIN_VPERM_16QI_UNS,
|
||||
VSX_BUILTIN_XXPERMDI_2DF,
|
||||
VSX_BUILTIN_XXPERMDI_2DI,
|
||||
VSX_BUILTIN_XXPERMDI_4SF,
|
||||
VSX_BUILTIN_XXPERMDI_4SI,
|
||||
VSX_BUILTIN_XXPERMDI_8HI,
|
||||
VSX_BUILTIN_XXPERMDI_16QI,
|
||||
VSX_BUILTIN_CONCAT_2DF,
|
||||
VSX_BUILTIN_CONCAT_2DI,
|
||||
VSX_BUILTIN_SET_2DF,
|
||||
VSX_BUILTIN_SET_2DI,
|
||||
VSX_BUILTIN_SPLAT_2DF,
|
||||
VSX_BUILTIN_SPLAT_2DI,
|
||||
VSX_BUILTIN_XXMRGHW_4SF,
|
||||
VSX_BUILTIN_XXMRGHW_4SI,
|
||||
VSX_BUILTIN_XXMRGLW_4SF,
|
||||
VSX_BUILTIN_XXMRGLW_4SI,
|
||||
VSX_BUILTIN_XXSLDWI_16QI,
|
||||
VSX_BUILTIN_XXSLDWI_8HI,
|
||||
VSX_BUILTIN_XXSLDWI_4SI,
|
||||
VSX_BUILTIN_XXSLDWI_4SF,
|
||||
VSX_BUILTIN_XXSLDWI_2DI,
|
||||
VSX_BUILTIN_XXSLDWI_2DF,
|
||||
VSX_BUILTIN_VEC_INIT_V2DF,
|
||||
VSX_BUILTIN_VEC_INIT_V2DI,
|
||||
VSX_BUILTIN_VEC_SET_V2DF,
|
||||
VSX_BUILTIN_VEC_SET_V2DI,
|
||||
VSX_BUILTIN_VEC_EXT_V2DF,
|
||||
VSX_BUILTIN_VEC_EXT_V2DI,
|
||||
|
||||
/* VSX overloaded builtins, add the overloaded functions not present in
|
||||
Altivec. */
|
||||
VSX_BUILTIN_VEC_MUL,
|
||||
VSX_BUILTIN_OVERLOADED_FIRST = VSX_BUILTIN_VEC_MUL,
|
||||
VSX_BUILTIN_VEC_MSUB,
|
||||
VSX_BUILTIN_VEC_NMADD,
|
||||
VSX_BUITLIN_VEC_NMSUB,
|
||||
VSX_BUILTIN_VEC_DIV,
|
||||
VSX_BUILTIN_VEC_XXMRGHW,
|
||||
VSX_BUILTIN_VEC_XXMRGLW,
|
||||
VSX_BUILTIN_VEC_XXPERMDI,
|
||||
VSX_BUILTIN_VEC_XXSLDWI,
|
||||
VSX_BUILTIN_VEC_XXSPLTD,
|
||||
VSX_BUILTIN_VEC_XXSPLTW,
|
||||
VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_XXSPLTW,
|
||||
|
||||
/* Combined VSX/Altivec builtins. */
|
||||
VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
|
||||
VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF,
|
||||
VECTOR_BUILTIN_FIX_V4SF_V4SI,
|
||||
VECTOR_BUILTIN_FIXUNS_V4SF_V4SI,
|
||||
|
||||
/* Power7 builtins, that aren't VSX instructions. */
|
||||
POWER7_BUILTIN_BPERMD,
|
||||
|
||||
RS6000_BUILTIN_COUNT
|
||||
};
|
||||
|
||||
@ -3151,6 +3403,8 @@ enum rs6000_builtin_type_index
|
||||
RS6000_BTI_V16QI,
|
||||
RS6000_BTI_V2SI,
|
||||
RS6000_BTI_V2SF,
|
||||
RS6000_BTI_V2DI,
|
||||
RS6000_BTI_V2DF,
|
||||
RS6000_BTI_V4HI,
|
||||
RS6000_BTI_V4SI,
|
||||
RS6000_BTI_V4SF,
|
||||
@ -3158,13 +3412,16 @@ enum rs6000_builtin_type_index
|
||||
RS6000_BTI_unsigned_V16QI,
|
||||
RS6000_BTI_unsigned_V8HI,
|
||||
RS6000_BTI_unsigned_V4SI,
|
||||
RS6000_BTI_unsigned_V2DI,
|
||||
RS6000_BTI_bool_char, /* __bool char */
|
||||
RS6000_BTI_bool_short, /* __bool short */
|
||||
RS6000_BTI_bool_int, /* __bool int */
|
||||
RS6000_BTI_bool_long, /* __bool long */
|
||||
RS6000_BTI_pixel, /* __pixel */
|
||||
RS6000_BTI_bool_V16QI, /* __vector __bool char */
|
||||
RS6000_BTI_bool_V8HI, /* __vector __bool short */
|
||||
RS6000_BTI_bool_V4SI, /* __vector __bool int */
|
||||
RS6000_BTI_bool_V2DI, /* __vector __bool long */
|
||||
RS6000_BTI_pixel_V8HI, /* __vector __pixel */
|
||||
RS6000_BTI_long, /* long_integer_type_node */
|
||||
RS6000_BTI_unsigned_long, /* long_unsigned_type_node */
|
||||
@ -3174,7 +3431,10 @@ enum rs6000_builtin_type_index
|
||||
RS6000_BTI_UINTHI, /* unsigned_intHI_type_node */
|
||||
RS6000_BTI_INTSI, /* intSI_type_node */
|
||||
RS6000_BTI_UINTSI, /* unsigned_intSI_type_node */
|
||||
RS6000_BTI_INTDI, /* intDI_type_node */
|
||||
RS6000_BTI_UINTDI, /* unsigned_intDI_type_node */
|
||||
RS6000_BTI_float, /* float_type_node */
|
||||
RS6000_BTI_double, /* double_type_node */
|
||||
RS6000_BTI_void, /* void_type_node */
|
||||
RS6000_BTI_MAX
|
||||
};
|
||||
@ -3185,6 +3445,8 @@ enum rs6000_builtin_type_index
|
||||
#define opaque_p_V2SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_p_V2SI])
|
||||
#define opaque_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V4SI])
|
||||
#define V16QI_type_node (rs6000_builtin_types[RS6000_BTI_V16QI])
|
||||
#define V2DI_type_node (rs6000_builtin_types[RS6000_BTI_V2DI])
|
||||
#define V2DF_type_node (rs6000_builtin_types[RS6000_BTI_V2DF])
|
||||
#define V2SI_type_node (rs6000_builtin_types[RS6000_BTI_V2SI])
|
||||
#define V2SF_type_node (rs6000_builtin_types[RS6000_BTI_V2SF])
|
||||
#define V4HI_type_node (rs6000_builtin_types[RS6000_BTI_V4HI])
|
||||
@ -3194,13 +3456,16 @@ enum rs6000_builtin_type_index
|
||||
#define unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
|
||||
#define unsigned_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
|
||||
#define unsigned_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
|
||||
#define unsigned_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI])
|
||||
#define bool_char_type_node (rs6000_builtin_types[RS6000_BTI_bool_char])
|
||||
#define bool_short_type_node (rs6000_builtin_types[RS6000_BTI_bool_short])
|
||||
#define bool_int_type_node (rs6000_builtin_types[RS6000_BTI_bool_int])
|
||||
#define bool_long_type_node (rs6000_builtin_types[RS6000_BTI_bool_long])
|
||||
#define pixel_type_node (rs6000_builtin_types[RS6000_BTI_pixel])
|
||||
#define bool_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
|
||||
#define bool_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
|
||||
#define bool_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
|
||||
#define bool_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V2DI])
|
||||
#define pixel_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
|
||||
|
||||
#define long_integer_type_internal_node (rs6000_builtin_types[RS6000_BTI_long])
|
||||
@ -3211,7 +3476,10 @@ enum rs6000_builtin_type_index
|
||||
#define uintHI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTHI])
|
||||
#define intSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTSI])
|
||||
#define uintSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTSI])
|
||||
#define intDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTDI])
|
||||
#define uintDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTDI])
|
||||
#define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float])
|
||||
#define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double])
|
||||
#define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void])
|
||||
|
||||
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
|
||||
|
@ -15322,6 +15322,7 @@
|
||||
|
||||
|
||||
(include "sync.md")
|
||||
(include "vector.md")
|
||||
(include "altivec.md")
|
||||
(include "spe.md")
|
||||
(include "dfp.md")
|
||||
|
@ -119,6 +119,38 @@ mvsx
|
||||
Target Report Mask(VSX)
|
||||
Use vector/scalar (VSX) instructions
|
||||
|
||||
mvsx-scalar-double
|
||||
Target Undocumented Report Var(TARGET_VSX_SCALAR_DOUBLE) Init(-1)
|
||||
; If -mvsx, use VSX arithmetic instructions for scalar double (on by default)
|
||||
|
||||
mvsx-scalar-memory
|
||||
Target Undocumented Report Var(TARGET_VSX_SCALAR_MEMORY)
|
||||
; If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default)
|
||||
|
||||
mvsx-align-128
|
||||
Target Undocumented Report Var(TARGET_VSX_ALIGN_128)
|
||||
; If -mvsx, set alignment to 128 bits instead of 32/64
|
||||
|
||||
mallow-movmisalign
|
||||
Target Undocumented Var(TARGET_ALLOW_MOVMISALIGN) Init(-1)
|
||||
; Allow/disallow the movmisalign in DF/DI vectors
|
||||
|
||||
mallow-df-permute
|
||||
Target Undocumented Var(TARGET_ALLOW_DF_PERMUTE)
|
||||
; Allow/disallow permutation of DF/DI vectors
|
||||
|
||||
msched-groups
|
||||
Target Undocumented Report Var(TARGET_SCHED_GROUPS) Init(-1)
|
||||
; Explicitly set/unset whether rs6000_sched_groups is set
|
||||
|
||||
malways-hint
|
||||
Target Undocumented Report Var(TARGET_ALWAYS_HINT) Init(-1)
|
||||
; Explicitly set/unset whether rs6000_always_hint is set
|
||||
|
||||
malign-branch-targets
|
||||
Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1)
|
||||
; Explicitly set/unset whether rs6000_align_branch_targets is set
|
||||
|
||||
mupdate
|
||||
Target Report Var(TARGET_UPDATE) Init(1)
|
||||
Generate load/store with update instructions
|
||||
|
@ -59,6 +59,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \
|
||||
$(srcdir)/config/rs6000/constraints.md \
|
||||
$(srcdir)/config/rs6000/darwin.md \
|
||||
$(srcdir)/config/rs6000/sync.md \
|
||||
$(srcdir)/config/rs6000/vector.md \
|
||||
$(srcdir)/config/rs6000/altivec.md \
|
||||
$(srcdir)/config/rs6000/spe.md \
|
||||
$(srcdir)/config/rs6000/dfp.md \
|
||||
|
700
gcc/config/rs6000/vector.md
Normal file
700
gcc/config/rs6000/vector.md
Normal file
@ -0,0 +1,700 @@
|
||||
;; Expander definitions for vector support. No instructions are in this file,
|
||||
;; this file provides the generic vector expander, and the actual vector
|
||||
;; instructions will be in altivec.md.
|
||||
|
||||
;; Copyright (C) 2009
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Michael Meissner <meissner@linux.vnet.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/>.
|
||||
|
||||
|
||||
;; Vector int modes
|
||||
(define_mode_iterator VEC_I [V16QI V8HI V4SI])
|
||||
|
||||
;; Vector float modes
|
||||
(define_mode_iterator VEC_F [V4SF])
|
||||
|
||||
;; Vector arithmetic modes
|
||||
(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF])
|
||||
|
||||
;; Vector modes that need alginment via permutes
|
||||
(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
|
||||
|
||||
;; Vector logical modes
|
||||
(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
|
||||
|
||||
;; Vector modes for moves. Don't do TImode here.
|
||||
(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF])
|
||||
|
||||
;; Vector comparison modes
|
||||
(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF])
|
||||
|
||||
;; Vector init/extract modes
|
||||
(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF])
|
||||
|
||||
;; Vector reload iterator
|
||||
(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI])
|
||||
|
||||
;; Base type from vector mode
|
||||
(define_mode_attr VEC_base [(V16QI "QI")
|
||||
(V8HI "HI")
|
||||
(V4SI "SI")
|
||||
(V2DI "DI")
|
||||
(V4SF "SF")
|
||||
(V2DF "DF")
|
||||
(TI "TI")])
|
||||
|
||||
;; Same size integer type for floating point data
|
||||
(define_mode_attr VEC_int [(V4SF "v4si")
|
||||
(V2DF "v2di")])
|
||||
|
||||
(define_mode_attr VEC_INT [(V4SF "V4SI")
|
||||
(V2DF "V2DI")])
|
||||
|
||||
;; constants for unspec
|
||||
(define_constants
|
||||
[(UNSPEC_PREDICATE 400)])
|
||||
|
||||
|
||||
;; Vector move instructions.
|
||||
(define_expand "mov<mode>"
|
||||
[(set (match_operand:VEC_M 0 "nonimmediate_operand" "")
|
||||
(match_operand:VEC_M 1 "any_operand" ""))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
{
|
||||
if (can_create_pseudo_p ())
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& !easy_vector_constant (operands[1], <MODE>mode))
|
||||
operands[1] = force_const_mem (<MODE>mode, operands[1]);
|
||||
|
||||
else if (!vlogical_operand (operands[0], <MODE>mode)
|
||||
&& !vlogical_operand (operands[1], <MODE>mode))
|
||||
operands[1] = force_reg (<MODE>mode, operands[1]);
|
||||
}
|
||||
})
|
||||
|
||||
;; Generic vector floating point load/store instructions.
|
||||
(define_expand "vector_load_<mode>"
|
||||
[(set (match_operand:VEC_M 0 "vfloat_operand" "")
|
||||
(match_operand:VEC_M 1 "memory_operand" ""))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_store_<mode>"
|
||||
[(set (match_operand:VEC_M 0 "memory_operand" "")
|
||||
(match_operand:VEC_M 1 "vfloat_operand" ""))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
;; Splits if a GPR register was chosen for the move
|
||||
(define_split
|
||||
[(set (match_operand:VEC_L 0 "nonimmediate_operand" "")
|
||||
(match_operand:VEC_L 1 "input_operand" ""))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)
|
||||
&& reload_completed
|
||||
&& gpr_or_gpr_p (operands[0], operands[1])"
|
||||
[(pc)]
|
||||
{
|
||||
rs6000_split_multireg_move (operands[0], operands[1]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
||||
;; Reload patterns for vector operations. We may need an addtional base
|
||||
;; register to convert the reg+offset addressing to reg+reg for vector
|
||||
;; registers and reg+reg or (reg+reg)&(-16) addressing to just an index
|
||||
;; register for gpr registers.
|
||||
(define_expand "reload_<VEC_R:mode>_<P:mptrsize>_store"
|
||||
[(parallel [(match_operand:VEC_R 0 "memory_operand" "m")
|
||||
(match_operand:VEC_R 1 "gpc_reg_operand" "r")
|
||||
(match_operand:P 2 "register_operand" "=&b")])]
|
||||
"<P:tptrsize>"
|
||||
{
|
||||
rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "reload_<VEC_R:mode>_<P:mptrsize>_load"
|
||||
[(parallel [(match_operand:VEC_R 0 "gpc_reg_operand" "=&r")
|
||||
(match_operand:VEC_R 1 "memory_operand" "m")
|
||||
(match_operand:P 2 "register_operand" "=&b")])]
|
||||
"<P:tptrsize>"
|
||||
{
|
||||
rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Reload sometimes tries to move the address to a GPR, and can generate
|
||||
;; invalid RTL for addresses involving AND -16. Allow addresses involving
|
||||
;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
|
||||
|
||||
(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
|
||||
[(set (match_operand:P 0 "gpc_reg_operand" "=b")
|
||||
(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
|
||||
(match_operand:P 2 "reg_or_cint_operand" "rI"))
|
||||
(const_int -16)))]
|
||||
"TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 0)
|
||||
(plus:P (match_dup 1)
|
||||
(match_dup 2)))
|
||||
(parallel [(set (match_dup 0)
|
||||
(and:P (match_dup 0)
|
||||
(const_int -16)))
|
||||
(clobber:CC (scratch:CC))])])
|
||||
|
||||
;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16
|
||||
;; address to a register because there is no clobber of a (scratch), so we add
|
||||
;; it here.
|
||||
(define_insn_and_split "*vec_reload_and_reg_<mptrsize>"
|
||||
[(set (match_operand:P 0 "gpc_reg_operand" "=b")
|
||||
(and:P (match_operand:P 1 "gpc_reg_operand" "r")
|
||||
(const_int -16)))]
|
||||
"TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0)
|
||||
(and:P (match_dup 1)
|
||||
(const_int -16)))
|
||||
(clobber:CC (scratch:CC))])])
|
||||
|
||||
;; Generic floating point vector arithmetic support
|
||||
(define_expand "add<mode>3"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 2 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "sub<mode>3"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 2 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "mul<mode>3"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 2 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && TARGET_FUSED_MADD"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "neg<mode>2"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "abs<mode>2"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "smin<mode>3"
|
||||
[(set (match_operand:VEC_F 0 "register_operand" "")
|
||||
(smin:VEC_F (match_operand:VEC_F 1 "register_operand" "")
|
||||
(match_operand:VEC_F 2 "register_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "smax<mode>3"
|
||||
[(set (match_operand:VEC_F 0 "register_operand" "")
|
||||
(smax:VEC_F (match_operand:VEC_F 1 "register_operand" "")
|
||||
(match_operand:VEC_F 2 "register_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
|
||||
(define_expand "ftrunc<mode>2"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
|
||||
;; Vector comparisons
|
||||
(define_expand "vcond<mode>"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(if_then_else:VEC_F
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand:VEC_F 4 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 5 "vfloat_operand" "")])
|
||||
(match_operand:VEC_F 1 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 2 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
|
||||
operands[3], operands[4], operands[5]))
|
||||
DONE;
|
||||
else
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
(define_expand "vcond<mode>"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(if_then_else:VEC_I
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand:VEC_I 4 "vint_operand" "")
|
||||
(match_operand:VEC_I 5 "vint_operand" "")])
|
||||
(match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
|
||||
operands[3], operands[4], operands[5]))
|
||||
DONE;
|
||||
else
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
(define_expand "vcondu<mode>"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(if_then_else:VEC_I
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand:VEC_I 4 "vint_operand" "")
|
||||
(match_operand:VEC_I 5 "vint_operand" "")])
|
||||
(match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
|
||||
operands[3], operands[4], operands[5]))
|
||||
DONE;
|
||||
else
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
(define_expand "vector_eq<mode>"
|
||||
[(set (match_operand:VEC_C 0 "vlogical_operand" "")
|
||||
(eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_C 2 "vlogical_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_gt<mode>"
|
||||
[(set (match_operand:VEC_C 0 "vlogical_operand" "")
|
||||
(gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_C 2 "vlogical_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_ge<mode>"
|
||||
[(set (match_operand:VEC_C 0 "vlogical_operand" "")
|
||||
(ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_C 2 "vlogical_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_gtu<mode>"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(gtu:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_geu<mode>"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(geu:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask
|
||||
;; which is in the reverse order that we want
|
||||
(define_expand "vector_select_<mode>"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(if_then_else:VEC_L
|
||||
(ne:CC (match_operand:VEC_L 3 "vlogical_operand" "")
|
||||
(const_int 0))
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_select_<mode>_uns"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(if_then_else:VEC_L
|
||||
(ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand" "")
|
||||
(const_int 0))
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
;; Expansions that compare vectors producing a vector result and a predicate,
|
||||
;; setting CR6 to indicate a combined status
|
||||
(define_expand "vector_eq_<mode>_p"
|
||||
[(parallel
|
||||
[(set (reg:CC 74)
|
||||
(unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_A 2 "vlogical_operand" ""))]
|
||||
UNSPEC_PREDICATE))
|
||||
(set (match_operand:VEC_A 0 "vlogical_operand" "")
|
||||
(eq:VEC_A (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_gt_<mode>_p"
|
||||
[(parallel
|
||||
[(set (reg:CC 74)
|
||||
(unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_A 2 "vlogical_operand" ""))]
|
||||
UNSPEC_PREDICATE))
|
||||
(set (match_operand:VEC_A 0 "vlogical_operand" "")
|
||||
(gt:VEC_A (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_ge_<mode>_p"
|
||||
[(parallel
|
||||
[(set (reg:CC 74)
|
||||
(unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand" "")
|
||||
(match_operand:VEC_F 2 "vfloat_operand" ""))]
|
||||
UNSPEC_PREDICATE))
|
||||
(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(ge:VEC_F (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "vector_gtu_<mode>_p"
|
||||
[(parallel
|
||||
[(set (reg:CC 74)
|
||||
(unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" ""))]
|
||||
UNSPEC_PREDICATE))
|
||||
(set (match_operand:VEC_I 0 "vlogical_operand" "")
|
||||
(gtu:VEC_I (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
;; AltiVec predicates.
|
||||
|
||||
(define_expand "cr6_test_for_zero"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(eq:SI (reg:CC 74)
|
||||
(const_int 0)))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
(define_expand "cr6_test_for_zero_reverse"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(eq:SI (reg:CC 74)
|
||||
(const_int 0)))
|
||||
(set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
(define_expand "cr6_test_for_lt"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(lt:SI (reg:CC 74)
|
||||
(const_int 0)))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
(define_expand "cr6_test_for_lt_reverse"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(lt:SI (reg:CC 74)
|
||||
(const_int 0)))
|
||||
(set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
|
||||
;; Vector logical instructions
|
||||
(define_expand "xor<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "ior<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "and<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "one_cmpl<mode>2"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "nor<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 2 "vlogical_operand" ""))))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
(define_expand "andc<mode>3"
|
||||
[(set (match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" ""))
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")))]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
"")
|
||||
|
||||
;; Same size conversions
|
||||
(define_expand "float<VEC_int><mode>2"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "unsigned_float<VEC_int><mode>2"
|
||||
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
|
||||
(unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "fix_trunc<mode><VEC_int>2"
|
||||
[(set (match_operand:<VEC_INT> 0 "vint_operand" "")
|
||||
(fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "fixuns_trunc<mode><VEC_int>2"
|
||||
[(set (match_operand:<VEC_INT> 0 "vint_operand" "")
|
||||
(unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
|
||||
"
|
||||
{
|
||||
emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
|
||||
;; Vector initialization, set, extract
|
||||
(define_expand "vec_init<mode>"
|
||||
[(match_operand:VEC_E 0 "vlogical_operand" "")
|
||||
(match_operand:VEC_E 1 "" "")]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
{
|
||||
rs6000_expand_vector_init (operands[0], operands[1]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "vec_set<mode>"
|
||||
[(match_operand:VEC_E 0 "vlogical_operand" "")
|
||||
(match_operand:<VEC_base> 1 "register_operand" "")
|
||||
(match_operand 2 "const_int_operand" "")]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
{
|
||||
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "vec_extract<mode>"
|
||||
[(match_operand:<VEC_base> 0 "register_operand" "")
|
||||
(match_operand:VEC_E 1 "vlogical_operand" "")
|
||||
(match_operand 2 "const_int_operand" "")]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
{
|
||||
rs6000_expand_vector_extract (operands[0], operands[1],
|
||||
INTVAL (operands[2]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Interleave patterns
|
||||
(define_expand "vec_interleave_highv4sf"
|
||||
[(set (match_operand:V4SF 0 "vfloat_operand" "")
|
||||
(vec_merge:V4SF
|
||||
(vec_select:V4SF (match_operand:V4SF 1 "vfloat_operand" "")
|
||||
(parallel [(const_int 0)
|
||||
(const_int 2)
|
||||
(const_int 1)
|
||||
(const_int 3)]))
|
||||
(vec_select:V4SF (match_operand:V4SF 2 "vfloat_operand" "")
|
||||
(parallel [(const_int 2)
|
||||
(const_int 0)
|
||||
(const_int 3)
|
||||
(const_int 1)]))
|
||||
(const_int 5)))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
|
||||
"")
|
||||
|
||||
(define_expand "vec_interleave_lowv4sf"
|
||||
[(set (match_operand:V4SF 0 "vfloat_operand" "")
|
||||
(vec_merge:V4SF
|
||||
(vec_select:V4SF (match_operand:V4SF 1 "vfloat_operand" "")
|
||||
(parallel [(const_int 2)
|
||||
(const_int 0)
|
||||
(const_int 3)
|
||||
(const_int 1)]))
|
||||
(vec_select:V4SF (match_operand:V4SF 2 "vfloat_operand" "")
|
||||
(parallel [(const_int 0)
|
||||
(const_int 2)
|
||||
(const_int 1)
|
||||
(const_int 3)]))
|
||||
(const_int 5)))]
|
||||
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
|
||||
"")
|
||||
|
||||
|
||||
;; Align vector loads with a permute.
|
||||
(define_expand "vec_realign_load_<mode>"
|
||||
[(match_operand:VEC_K 0 "vlogical_operand" "")
|
||||
(match_operand:VEC_K 1 "vlogical_operand" "")
|
||||
(match_operand:VEC_K 2 "vlogical_operand" "")
|
||||
(match_operand:V16QI 3 "vlogical_operand" "")]
|
||||
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
|
||||
{
|
||||
emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2],
|
||||
operands[3]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
||||
;; Vector shift left in bits. Currently supported ony for shift
|
||||
;; amounts that can be expressed as byte shifts (divisible by 8).
|
||||
;; General shift amounts can be supported using vslo + vsl. We're
|
||||
;; not expecting to see these yet (the vectorizer currently
|
||||
;; generates only shifts divisible by byte_size).
|
||||
(define_expand "vec_shl_<mode>"
|
||||
[(match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:QI 2 "reg_or_short_operand" "")]
|
||||
"TARGET_ALTIVEC"
|
||||
"
|
||||
{
|
||||
rtx bitshift = operands[2];
|
||||
rtx shift;
|
||||
rtx insn;
|
||||
HOST_WIDE_INT bitshift_val;
|
||||
HOST_WIDE_INT byteshift_val;
|
||||
|
||||
if (! CONSTANT_P (bitshift))
|
||||
FAIL;
|
||||
bitshift_val = INTVAL (bitshift);
|
||||
if (bitshift_val & 0x7)
|
||||
FAIL;
|
||||
byteshift_val = bitshift_val >> 3;
|
||||
shift = gen_rtx_CONST_INT (QImode, byteshift_val);
|
||||
insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
|
||||
shift);
|
||||
|
||||
emit_insn (insn);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
;; Vector shift right in bits. Currently supported ony for shift
|
||||
;; amounts that can be expressed as byte shifts (divisible by 8).
|
||||
;; General shift amounts can be supported using vsro + vsr. We're
|
||||
;; not expecting to see these yet (the vectorizer currently
|
||||
;; generates only shifts divisible by byte_size).
|
||||
(define_expand "vec_shr_<mode>"
|
||||
[(match_operand:VEC_L 0 "vlogical_operand" "")
|
||||
(match_operand:VEC_L 1 "vlogical_operand" "")
|
||||
(match_operand:QI 2 "reg_or_short_operand" "")]
|
||||
"TARGET_ALTIVEC"
|
||||
"
|
||||
{
|
||||
rtx bitshift = operands[2];
|
||||
rtx shift;
|
||||
rtx insn;
|
||||
HOST_WIDE_INT bitshift_val;
|
||||
HOST_WIDE_INT byteshift_val;
|
||||
|
||||
if (! CONSTANT_P (bitshift))
|
||||
FAIL;
|
||||
bitshift_val = INTVAL (bitshift);
|
||||
if (bitshift_val & 0x7)
|
||||
FAIL;
|
||||
byteshift_val = 16 - (bitshift_val >> 3);
|
||||
shift = gen_rtx_CONST_INT (QImode, byteshift_val);
|
||||
insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
|
||||
shift);
|
||||
|
||||
emit_insn (insn);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
;; Expanders for rotate each element in a vector
|
||||
(define_expand "vrotl<mode>3"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
;; Expanders for arithmetic shift left on each vector element
|
||||
(define_expand "vashl<mode>3"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
;; Expanders for logical shift right on each vector element
|
||||
(define_expand "vlshr<mode>3"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
||||
|
||||
;; Expanders for arithmetic shift right on each vector element
|
||||
(define_expand "vashr<mode>3"
|
||||
[(set (match_operand:VEC_I 0 "vint_operand" "")
|
||||
(ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "")
|
||||
(match_operand:VEC_I 2 "vint_operand" "")))]
|
||||
"TARGET_ALTIVEC"
|
||||
"")
|
Loading…
Reference in New Issue
Block a user