Commit a72c65c7 by Michael Meissner Committed by Michael Meissner

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
parent 23041160
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)
......
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
......
......@@ -21,18 +21,7 @@
(define_constants
[(UNSPEC_VCMPBFP 50)
(UNSPEC_VCMPEQUB 51)
(UNSPEC_VCMPEQUH 52)
(UNSPEC_VCMPEQUW 53)
(UNSPEC_VCMPEQFP 54)
(UNSPEC_VCMPGEFP 55)
(UNSPEC_VCMPGTUB 56)
(UNSPEC_VCMPGTSB 57)
(UNSPEC_VCMPGTUH 58)
(UNSPEC_VCMPGTSH 59)
(UNSPEC_VCMPGTUW 60)
(UNSPEC_VCMPGTSW 61)
(UNSPEC_VCMPGTFP 62)
;; 51-62 deleted
(UNSPEC_VMSUMU 65)
(UNSPEC_VMSUMM 66)
(UNSPEC_VMSUMSHM 68)
......@@ -63,7 +52,7 @@
(UNSPEC_VPKSHUS 101)
(UNSPEC_VPKUWUS 102)
(UNSPEC_VPKSWUS 103)
(UNSPEC_VRL 104)
;; 104 deleted
(UNSPEC_VSLV4SI 110)
(UNSPEC_VSLO 111)
(UNSPEC_VSR 118)
......@@ -76,6 +65,7 @@
(UNSPEC_VSUM2SWS 134)
(UNSPEC_VSUMSWS 135)
(UNSPEC_VPERM 144)
(UNSPEC_VPERM_UNS 145)
(UNSPEC_VRFIP 148)
(UNSPEC_VRFIN 149)
(UNSPEC_VRFIM 150)
......@@ -87,10 +77,7 @@
(UNSPEC_VEXPTEFP 156)
(UNSPEC_VRSQRTEFP 157)
(UNSPEC_VREFP 158)
(UNSPEC_VSEL4SI 159)
(UNSPEC_VSEL4SF 160)
(UNSPEC_VSEL8HI 161)
(UNSPEC_VSEL16QI 162)
;; 159-162 deleted
(UNSPEC_VLSDOI 163)
(UNSPEC_VUPKHSB 167)
(UNSPEC_VUPKHPX 168)
......@@ -98,7 +85,7 @@
(UNSPEC_VUPKLSB 170)
(UNSPEC_VUPKLPX 171)
(UNSPEC_VUPKLSH 172)
(UNSPEC_PREDICATE 173)
;; 173 deleted
(UNSPEC_DST 190)
(UNSPEC_DSTT 191)
(UNSPEC_DSTST 192)
......@@ -111,7 +98,7 @@
(UNSPEC_STVE 203)
(UNSPEC_SET_VSCR 213)
(UNSPEC_GET_VRSAVE 214)
(UNSPEC_REALIGN_LOAD 215)
;; 215 deleted
(UNSPEC_REDUC_PLUS 217)
(UNSPEC_VECSH 219)
(UNSPEC_EXTEVEN_V4SI 220)
......@@ -125,11 +112,11 @@
(UNSPEC_INTERHI_V4SI 228)
(UNSPEC_INTERHI_V8HI 229)
(UNSPEC_INTERHI_V16QI 230)
(UNSPEC_INTERHI_V4SF 231)
;; delete 231
(UNSPEC_INTERLO_V4SI 232)
(UNSPEC_INTERLO_V8HI 233)
(UNSPEC_INTERLO_V16QI 234)
(UNSPEC_INTERLO_V4SF 235)
;; delete 235
(UNSPEC_LVLX 236)
(UNSPEC_LVLXL 237)
(UNSPEC_LVRX 238)
......@@ -176,39 +163,20 @@
(define_mode_iterator VF [V4SF])
;; Vec modes, pity mode iterators are not composable
(define_mode_iterator V [V4SI V8HI V16QI V4SF])
;; Vec modes for move/logical/permute ops, include vector types for move not
;; otherwise handled by altivec (v2df, v2di, ti)
(define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
(define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
;; Generic LVX load instruction.
(define_insn "altivec_lvx_<mode>"
[(set (match_operand:V 0 "altivec_register_operand" "=v")
(match_operand:V 1 "memory_operand" "Z"))]
"TARGET_ALTIVEC"
"lvx %0,%y1"
[(set_attr "type" "vecload")])
;; Like VM, except don't do TImode
(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
;; Generic STVX store instruction.
(define_insn "altivec_stvx_<mode>"
[(set (match_operand:V 0 "memory_operand" "=Z")
(match_operand:V 1 "altivec_register_operand" "v"))]
"TARGET_ALTIVEC"
"stvx %1,%y0"
[(set_attr "type" "vecstore")])
(define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
;; Vector move instructions.
(define_expand "mov<mode>"
[(set (match_operand:V 0 "nonimmediate_operand" "")
(match_operand:V 1 "any_operand" ""))]
"TARGET_ALTIVEC"
{
rs6000_emit_move (operands[0], operands[1], <MODE>mode);
DONE;
})
(define_insn "*mov<mode>_internal"
[(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,o,r,r,v")
(match_operand:V 1 "input_operand" "v,Z,v,r,o,r,W"))]
"TARGET_ALTIVEC
(define_insn "*altivec_mov<mode>"
[(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
(match_operand:VM2 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
{
......@@ -220,52 +188,42 @@
case 3: return "#";
case 4: return "#";
case 5: return "#";
case 6: return output_vec_const_move (operands);
case 6: return "vxor %0,%0,%0";
case 7: return output_vec_const_move (operands);
default: gcc_unreachable ();
}
}
[(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
(define_split
[(set (match_operand:V4SI 0 "nonimmediate_operand" "")
(match_operand:V4SI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed
&& gpr_or_gpr_p (operands[0], operands[1])"
[(pc)]
[(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
;; is for unions. However for plain data movement, slightly favor the vector
;; loads
(define_insn "*altivec_movti"
[(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?o,?r,?r,v,v")
(match_operand:TI 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
"VECTOR_MEM_ALTIVEC_P (TImode)
&& (register_operand (operands[0], TImode)
|| register_operand (operands[1], TImode))"
{
rs6000_split_multireg_move (operands[0], operands[1]); DONE;
})
(define_split
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
(match_operand:V8HI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed
&& gpr_or_gpr_p (operands[0], operands[1])"
[(pc)]
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_split
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
(match_operand:V16QI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed
&& gpr_or_gpr_p (operands[0], operands[1])"
[(pc)]
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_split
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
(match_operand:V4SF 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed
&& gpr_or_gpr_p (operands[0], operands[1])"
[(pc)]
{
rs6000_split_multireg_move (operands[0], operands[1]); DONE;
})
switch (which_alternative)
{
case 0: return "stvx %1,%y0";
case 1: return "lvx %0,%y1";
case 2: return "vor %0,%1,%1";
case 3: return "#";
case 4: return "#";
case 5: return "#";
case 6: return "vxor %0,%0,%0";
case 7: return output_vec_const_move (operands);
default: gcc_unreachable ();
}
}
[(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
(define_split
[(set (match_operand:V 0 "altivec_register_operand" "")
(match_operand:V 1 "easy_vector_constant_add_self" ""))]
"TARGET_ALTIVEC && reload_completed"
[(set (match_operand:VM 0 "altivec_register_operand" "")
(match_operand:VM 1 "easy_vector_constant_add_self" ""))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && reload_completed"
[(set (match_dup 0) (match_dup 3))
(set (match_dup 0) (match_dup 4))]
{
......@@ -346,11 +304,11 @@
"vaddu<VI_char>m %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "addv4sf3"
(define_insn "*altivec_addv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vaddfp %0,%1,%2"
[(set_attr "type" "vecfloat")])
......@@ -392,11 +350,11 @@
"vsubu<VI_char>m %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "subv4sf3"
(define_insn "*altivec_subv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vsubfp %0,%1,%2"
[(set_attr "type" "vecfloat")])
......@@ -457,113 +415,75 @@
"vcmpbfp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpequb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")]
UNSPEC_VCMPEQUB))]
(define_insn "*altivec_eq<mode>"
[(set (match_operand:VI 0 "altivec_register_operand" "=v")
(eq:VI (match_operand:VI 1 "altivec_register_operand" "v")
(match_operand:VI 2 "altivec_register_operand" "v")))]
"TARGET_ALTIVEC"
"vcmpequb %0,%1,%2"
[(set_attr "type" "vecsimple")])
"vcmpequ<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpequh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")]
UNSPEC_VCMPEQUH))]
(define_insn "*altivec_gt<mode>"
[(set (match_operand:VI 0 "altivec_register_operand" "=v")
(gt:VI (match_operand:VI 1 "altivec_register_operand" "v")
(match_operand:VI 2 "altivec_register_operand" "v")))]
"TARGET_ALTIVEC"
"vcmpequh %0,%1,%2"
[(set_attr "type" "vecsimple")])
"vcmpgts<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpequw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")]
UNSPEC_VCMPEQUW))]
(define_insn "*altivec_gtu<mode>"
[(set (match_operand:VI 0 "altivec_register_operand" "=v")
(gtu:VI (match_operand:VI 1 "altivec_register_operand" "v")
(match_operand:VI 2 "altivec_register_operand" "v")))]
"TARGET_ALTIVEC"
"vcmpequw %0,%1,%2"
[(set_attr "type" "vecsimple")])
"vcmpgtu<VI_char> %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpeqfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")]
UNSPEC_VCMPEQFP))]
"TARGET_ALTIVEC"
(define_insn "*altivec_eqv4sf"
[(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
(eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
(match_operand:V4SF 2 "altivec_register_operand" "v")))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpeqfp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpgefp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")]
UNSPEC_VCMPGEFP))]
"TARGET_ALTIVEC"
"vcmpgefp %0,%1,%2"
(define_insn "*altivec_gtv4sf"
[(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
(gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
(match_operand:V4SF 2 "altivec_register_operand" "v")))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpgtfp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpgtub"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")]
UNSPEC_VCMPGTUB))]
"TARGET_ALTIVEC"
"vcmpgtub %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vcmpgtsb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")]
UNSPEC_VCMPGTSB))]
"TARGET_ALTIVEC"
"vcmpgtsb %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vcmpgtuh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")]
UNSPEC_VCMPGTUH))]
"TARGET_ALTIVEC"
"vcmpgtuh %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vcmpgtsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")]
UNSPEC_VCMPGTSH))]
"TARGET_ALTIVEC"
"vcmpgtsh %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_vcmpgtuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")]
UNSPEC_VCMPGTUW))]
"TARGET_ALTIVEC"
"vcmpgtuw %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "*altivec_gev4sf"
[(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
(ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
(match_operand:V4SF 2 "altivec_register_operand" "v")))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpgefp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_vcmpgtsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")]
UNSPEC_VCMPGTSW))]
"TARGET_ALTIVEC"
"vcmpgtsw %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "*altivec_vsel<mode>"
[(set (match_operand:VM 0 "altivec_register_operand" "=v")
(if_then_else:VM
(ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
(const_int 0))
(match_operand:VM 2 "altivec_register_operand" "v")
(match_operand:VM 3 "altivec_register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vsel %0,%3,%2,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vcmpgtfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")]
UNSPEC_VCMPGTFP))]
"TARGET_ALTIVEC"
"vcmpgtfp %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "*altivec_vsel<mode>_uns"
[(set (match_operand:VM 0 "altivec_register_operand" "=v")
(if_then_else:VM
(ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
(const_int 0))
(match_operand:VM 2 "altivec_register_operand" "v")
(match_operand:VM 3 "altivec_register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vsel %0,%3,%2,%1"
[(set_attr "type" "vecperm")])
;; Fused multiply add
(define_insn "altivec_vmaddfp"
......@@ -571,17 +491,17 @@
(plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))
(match_operand:V4SF 3 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vmaddfp %0,%1,%2,%3"
[(set_attr "type" "vecfloat")])
;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
(define_expand "mulv4sf3"
(define_expand "altivec_mulv4sf3"
[(use (match_operand:V4SF 0 "register_operand" ""))
(use (match_operand:V4SF 1 "register_operand" ""))
(use (match_operand:V4SF 2 "register_operand" ""))]
"TARGET_ALTIVEC && TARGET_FUSED_MADD"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD"
"
{
rtx neg0;
......@@ -631,7 +551,7 @@
emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16)));
swap = gen_reg_rtx (V4SImode);
emit_insn (gen_altivec_vrlw (swap, operands[2], sixteen));
emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
one = gen_reg_rtx (V8HImode);
convert_move (one, operands[1], 0);
......@@ -684,7 +604,7 @@
(neg:V4SF (minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))
(match_operand:V4SF 3 "register_operand" "v"))))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vnmsubfp %0,%1,%2,%3"
[(set_attr "type" "vecfloat")])
......@@ -758,11 +678,11 @@
"vmaxs<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "smaxv4sf3"
(define_insn "*altivec_smaxv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vmaxfp %0,%1,%2"
[(set_attr "type" "veccmp")])
......@@ -782,11 +702,11 @@
"vmins<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "sminv4sf3"
(define_insn "*altivec_sminv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vminfp %0,%1,%2"
[(set_attr "type" "veccmp")])
......@@ -901,11 +821,11 @@
(const_int 3)
(const_int 1)]))
(const_int 5)))]
"TARGET_ALTIVEC"
"VECTOR_MEM_ALTIVEC_P (V4SImode)"
"vmrghw %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vmrghsf"
(define_insn "*altivec_vmrghsf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
(parallel [(const_int 0)
......@@ -918,7 +838,7 @@
(const_int 3)
(const_int 1)]))
(const_int 5)))]
"TARGET_ALTIVEC"
"VECTOR_MEM_ALTIVEC_P (V4SFmode)"
"vmrghw %0,%1,%2"
[(set_attr "type" "vecperm")])
......@@ -990,7 +910,8 @@
(define_insn "altivec_vmrglw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
(vec_merge:V4SI
(vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
(parallel [(const_int 2)
(const_int 0)
(const_int 3)
......@@ -1001,13 +922,14 @@
(const_int 1)
(const_int 3)]))
(const_int 5)))]
"TARGET_ALTIVEC"
"VECTOR_MEM_ALTIVEC_P (V4SImode)"
"vmrglw %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vmrglsf"
(define_insn "*altivec_vmrglsf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
(vec_merge:V4SF
(vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
(parallel [(const_int 2)
(const_int 0)
(const_int 3)
......@@ -1018,7 +940,7 @@
(const_int 1)
(const_int 3)]))
(const_int 5)))]
"TARGET_ALTIVEC"
"VECTOR_MEM_ALTIVEC_P (V4SFmode)"
"vmrglw %0,%1,%2"
[(set_attr "type" "vecperm")])
......@@ -1095,68 +1017,53 @@
[(set_attr "type" "veccomplex")])
;; logical ops
;; logical ops. Have the logical ops follow the memory ops in
;; terms of whether to prefer VSX or Altivec
(define_insn "and<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(and:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
(define_insn "*altivec_and<mode>3"
[(set (match_operand:VM 0 "register_operand" "=v")
(and:VM (match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vand %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "ior<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(ior:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
(define_insn "*altivec_ior<mode>3"
[(set (match_operand:VM 0 "register_operand" "=v")
(ior:VM (match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vor %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "xor<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(xor:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vxor %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "xorv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(xor:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
(define_insn "*altivec_xor<mode>3"
[(set (match_operand:VM 0 "register_operand" "=v")
(xor:VM (match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vxor %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "one_cmpl<mode>2"
[(set (match_operand:VI 0 "register_operand" "=v")
(not:VI (match_operand:VI 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
(define_insn "*altivec_one_cmpl<mode>2"
[(set (match_operand:VM 0 "register_operand" "=v")
(not:VM (match_operand:VM 1 "register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vnor %0,%1,%1"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_nor<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(not:VI (ior:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v"))))]
"TARGET_ALTIVEC"
(define_insn "*altivec_nor<mode>3"
[(set (match_operand:VM 0 "register_operand" "=v")
(not:VM (ior:VM (match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v"))))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vnor %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "andc<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(and:VI (not:VI (match_operand:VI 2 "register_operand" "v"))
(match_operand:VI 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vandc %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "*andc3_v4sf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(and:V4SF (not:V4SF (match_operand:V4SF 2 "register_operand" "v"))
(match_operand:V4SF 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
(define_insn "*altivec_andc<mode>3"
[(set (match_operand:VM 0 "register_operand" "=v")
(and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
(match_operand:VM 1 "register_operand" "v")))]
"VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
"vandc %0,%1,%2"
[(set_attr "type" "vecsimple")])
......@@ -1247,11 +1154,10 @@
"vpkswus %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vrl<VI_char>"
(define_insn "*altivec_vrl<VI_char>"
[(set (match_operand:VI 0 "register_operand" "=v")
(unspec:VI [(match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")]
UNSPEC_VRL))]
(rotate:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vrl<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
......@@ -1274,26 +1180,26 @@
"vslo %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "vashl<mode>3"
(define_insn "*altivec_vsl<VI_char>"
[(set (match_operand:VI 0 "register_operand" "=v")
(ashift:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v") ))]
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vsl<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "vlshr<mode>3"
(define_insn "*altivec_vsr<VI_char>"
[(set (match_operand:VI 0 "register_operand" "=v")
(lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v") ))]
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vsr<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "vashr<mode>3"
(define_insn "*altivec_vsra<VI_char>"
[(set (match_operand:VI 0 "register_operand" "=v")
(ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v") ))]
(match_operand:VI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"vsra<VI_char> %0,%1,%2"
[(set_attr "type" "vecsimple")])
......@@ -1386,13 +1292,13 @@
"vspltw %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "*altivec_vspltsf"
(define_insn "altivec_vspltsf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(vec_duplicate:V4SF
(vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
(parallel
[(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vspltw %0,%1,%2"
[(set_attr "type" "vecperm")])
......@@ -1404,23 +1310,33 @@
"vspltis<VI_char> %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "ftruncv4sf2"
(define_insn "*altivec_ftruncv4sf2"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vrfiz %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vperm_<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(unspec:V [(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")
[(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
UNSPEC_VPERM))]
"TARGET_ALTIVEC"
"vperm %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vperm_<mode>_uns"
[(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
UNSPEC_VPERM_UNS))]
"TARGET_ALTIVEC"
"vperm %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vrfip"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
......@@ -1515,184 +1431,10 @@
"vrefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_expand "vcondv4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(if_then_else:V4SI
(match_operator 3 "comparison_operator"
[(match_operand:V4SI 4 "register_operand" "v")
(match_operand:V4SI 5 "register_operand" "v")])
(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vconduv4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(if_then_else:V4SI
(match_operator 3 "comparison_operator"
[(match_operand:V4SI 4 "register_operand" "v")
(match_operand:V4SI 5 "register_operand" "v")])
(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vcondv4sf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(if_then_else:V4SF
(match_operator 3 "comparison_operator"
[(match_operand:V4SF 4 "register_operand" "v")
(match_operand:V4SF 5 "register_operand" "v")])
(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vcondv8hi"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(if_then_else:V8HI
(match_operator 3 "comparison_operator"
[(match_operand:V8HI 4 "register_operand" "v")
(match_operand:V8HI 5 "register_operand" "v")])
(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vconduv8hi"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(if_then_else:V8HI
(match_operator 3 "comparison_operator"
[(match_operand:V8HI 4 "register_operand" "v")
(match_operand:V8HI 5 "register_operand" "v")])
(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vcondv16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(if_then_else:V16QI
(match_operator 3 "comparison_operator"
[(match_operand:V16QI 4 "register_operand" "v")
(match_operand:V16QI 5 "register_operand" "v")])
(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_expand "vconduv16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(if_then_else:V16QI
(match_operator 3 "comparison_operator"
[(match_operand:V16QI 4 "register_operand" "v")
(match_operand:V16QI 5 "register_operand" "v")])
(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")))]
"TARGET_ALTIVEC"
"
{
if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
operands[3], operands[4], operands[5]))
DONE;
else
FAIL;
}
")
(define_insn "altivec_vsel_v4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")]
UNSPEC_VSEL4SI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsel_v4sf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")]
UNSPEC_VSEL4SF))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsel_v8hi"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V8HI 3 "register_operand" "v")]
UNSPEC_VSEL8HI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsel_v16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
UNSPEC_VSEL16QI))]
"TARGET_ALTIVEC"
"vsel %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(unspec:V [(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")
[(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")]
UNSPEC_VLSDOI))]
"TARGET_ALTIVEC"
......@@ -1747,50 +1489,92 @@
"vupklsh %0,%1"
[(set_attr "type" "vecperm")])
;; AltiVec predicates.
;; Compare vectors producing a vector result and a predicate, setting CR6 to
;; indicate a combined status
(define_insn "*altivec_vcmpequ<VI_char>_p"
[(set (reg:CC 74)
(unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:VI 0 "register_operand" "=v")
(eq:VI (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vcmpequ<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
(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_insn "*altivec_vcmpgts<VI_char>_p"
[(set (reg:CC 74)
(unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:VI 0 "register_operand" "=v")
(gt:VI (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vcmpgts<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
(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_insn "*altivec_vcmpgtu<VI_char>_p"
[(set (reg:CC 74)
(unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
(match_operand:VI 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:VI 0 "register_operand" "=v")
(gtu:VI (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"vcmpgtu<VI_char>. %0,%1,%2"
[(set_attr "type" "veccmp")])
(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_insn "*altivec_vcmpeqfp_p"
[(set (reg:CC 74)
(unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:V4SF 0 "register_operand" "=v")
(eq:V4SF (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpeqfp. %0,%1,%2"
[(set_attr "type" "veccmp")])
(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"
"")
(define_insn "*altivec_vcmpgtfp_p"
[(set (reg:CC 74)
(unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:V4SF 0 "register_operand" "=v")
(gt:V4SF (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpgtfp. %0,%1,%2"
[(set_attr "type" "veccmp")])
;; We can get away with generating the opcode on the fly (%3 below)
;; because all the predicates have the same scheduling parameters.
(define_insn "*altivec_vcmpgefp_p"
[(set (reg:CC 74)
(unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))]
UNSPEC_PREDICATE))
(set (match_operand:V4SF 0 "register_operand" "=v")
(ge:V4SF (match_dup 1)
(match_dup 2)))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vcmpgefp. %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_predicate_<mode>"
(define_insn "altivec_vcmpbfp_p"
[(set (reg:CC 74)
(unspec:CC [(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")
(match_operand 3 "any_operand" "")] UNSPEC_PREDICATE))
(clobber (match_scratch:V 0 "=v"))]
"TARGET_ALTIVEC"
"%3 %0,%1,%2"
[(set_attr "type" "veccmp")])
(unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")]
UNSPEC_VCMPBFP))
(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_dup 1)
(match_dup 2)]
UNSPEC_VCMPBFP))]
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
"vcmpbfp. %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "altivec_mtvscr"
[(set (reg:SI 110)
......@@ -1959,95 +1743,6 @@
"stvewx %1,%y0"
[(set_attr "type" "vecstore")])
(define_expand "vec_init<mode>"
[(match_operand:V 0 "register_operand" "")
(match_operand 1 "" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_init (operands[0], operands[1]);
DONE;
})
(define_expand "vec_setv4si"
[(match_operand:V4SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_setv8hi"
[(match_operand:V8HI 0 "register_operand" "")
(match_operand:HI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_setv16qi"
[(match_operand:V16QI 0 "register_operand" "")
(match_operand:QI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_setv4sf"
[(match_operand:V4SF 0 "register_operand" "")
(match_operand:SF 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv4si"
[(match_operand:SI 0 "register_operand" "")
(match_operand:V4SI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv8hi"
[(match_operand:HI 0 "register_operand" "")
(match_operand:V8HI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv16qi"
[(match_operand:QI 0 "register_operand" "")
(match_operand:V16QI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv4sf"
[(match_operand:SF 0 "register_operand" "")
(match_operand:V4SF 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_ALTIVEC"
{
rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
DONE;
})
;; Generate
;; vspltis? SCRATCH0,0
;; vsubu?m SCRATCH2,SCRATCH1,%1
......@@ -2069,7 +1764,7 @@
;; vspltisw SCRATCH1,-1
;; vslw SCRATCH2,SCRATCH1,SCRATCH1
;; vandc %0,%1,SCRATCH2
(define_expand "absv4sf2"
(define_expand "altivec_absv4sf2"
[(set (match_dup 2)
(vec_duplicate:V4SI (const_int -1)))
(set (match_dup 3)
......@@ -2102,66 +1797,6 @@
operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
})
;; 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>"
[(set (match_operand:V 0 "register_operand" "=v")
(unspec:V [(match_operand:V 1 "register_operand" "v")
(match_operand:QI 2 "reg_or_short_operand" "")]
UNSPEC_VECSH))]
"TARGET_ALTIVEC"
"
{
rtx bitshift = operands[2];
rtx byteshift = gen_reg_rtx (QImode);
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;
byteshift = gen_rtx_CONST_INT (QImode, byteshift_val);
emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
byteshift));
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 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>"
[(set (match_operand:V 0 "register_operand" "=v")
(unspec:V [(match_operand:V 1 "register_operand" "v")
(match_operand:QI 2 "reg_or_short_operand" "")]
UNSPEC_VECSH))]
"TARGET_ALTIVEC"
"
{
rtx bitshift = operands[2];
rtx byteshift = gen_reg_rtx (QImode);
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);
byteshift = gen_rtx_CONST_INT (QImode, byteshift_val);
emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
byteshift));
DONE;
}")
(define_insn "altivec_vsumsws_nomode"
[(set (match_operand 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
......@@ -2204,16 +1839,6 @@
DONE;
}")
(define_insn "vec_realign_load_<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(unspec:V [(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
UNSPEC_REALIGN_LOAD))]
"TARGET_ALTIVEC"
"vperm %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_expand "neg<mode>2"
[(use (match_operand:VI 0 "register_operand" ""))
(use (match_operand:VI 1 "register_operand" ""))]
......@@ -2665,7 +2290,7 @@
DONE;
}")
(define_expand "negv4sf2"
(define_expand "altivec_negv4sf2"
[(use (match_operand:V4SF 0 "register_operand" ""))
(use (match_operand:V4SF 1 "register_operand" ""))]
"TARGET_ALTIVEC"
......@@ -2994,29 +2619,6 @@
emit_insn (gen_vpkuhum_nomode (operands[0], operands[1], operands[2]));
DONE;
}")
(define_expand "vec_interleave_highv4sf"
[(set (match_operand:V4SF 0 "register_operand" "")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
(match_operand:V4SF 2 "register_operand" "")]
UNSPEC_INTERHI_V4SF))]
"TARGET_ALTIVEC"
"
{
emit_insn (gen_altivec_vmrghsf (operands[0], operands[1], operands[2]));
DONE;
}")
(define_expand "vec_interleave_lowv4sf"
[(set (match_operand:V4SF 0 "register_operand" "")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
(match_operand:V4SF 2 "register_operand" "")]
UNSPEC_INTERLO_V4SF))]
"TARGET_ALTIVEC"
"
{
emit_insn (gen_altivec_vmrglsf (operands[0], operands[1], operands[2]));
DONE;
}")
(define_expand "vec_interleave_high<mode>"
[(set (match_operand:VI 0 "register_operand" "")
......
......@@ -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)
......
......@@ -671,6 +671,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ 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,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
......@@ -719,6 +725,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ 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,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
......@@ -1483,6 +1495,8 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ 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,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
......@@ -1507,6 +1521,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ 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,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
......@@ -2123,6 +2143,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ 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,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
......@@ -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,11 +2422,29 @@ 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,
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI },
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1280,12 +1280,24 @@ 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, \
/*VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_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 \
......
;; 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"
"")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment