Commit 0ac081f6 by Aldy Hernandez

invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec for rs6000.


	* doc/invoke.texi: Add -maltivec, -mno-altivec, and -mabi=altivec
	for rs6000.

	* config/rs6000/rs6000.h (MASK_ALTIVEC): New.
	(TARGET_ALTIVEC): New.
	(TARGET_SWITCHES): Add altivec.
	(FIRST_PSEUDO_REGISTER): Change to 109.
	(CALL_USED_REGISTERS): Same.
	(FIRST_ALTIVEC_REGNO): New.
	(LAST_ALTIVEC_REGNO): New.
	(ALTIVEC_REGNO_P): New.
	(UNITS_PER_ALTIVEC_WORD): New.
	(ALTIVEC_VECTOR_MODE): New.
	(FIXED_REGISTERS): Add altivec registers.
	(REG_ALLOC_ORDER): Same.
	(HARD_REGNO_NREGS): Adjust for altivec registers.
	(HARD_REGNO_MODE_OK): Same.
	(MODES_TIEABLE_P): Same.
	(REGISTER_MOVE_COST): Same.
	(REGNO_REG_CLASS): Same.
	(reg_class): Add ALTIVEC_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v' constraint for ALTIVEC_REGS.
	(ALTIVEC_ARG_RETURN): New.
	(FUNCTION_VALUE): Handle VECTOR_TYPE.
	(LIBCALL_VALUE): Handle altivec vector modes.
	(VECTOR_MODE_SUPPORTED_P): New.
	(ALTIVEC_ARG_MIN_REG): New.
	(ALTIVEC_ARG_MAX_REG): New.
	(ALTIVEC_ARG_NUM_REG): New.
	(FUNCTION_VALUE_REGNO_P): Return true for altivec return register.
	(FUNCTION_ARG_REGNO_P): Support passing args in altivec registers.
	(REGISTER_NAMES): Add altivec regs.
	(DEBUG_REGISTER_NAMES): Same.
	(ADDITIONAL_REGISTER_NAMES): Same.
	(rs6000_builtins): New.
	(MD_EXPAND_BUILTIN): New.
	(MD_INIT_BUILTINS): New.
	(LEGITIMATE_OFFSET_ADDRESS_P): This addressing mode is not valid
	for AltiVec instructions.
	(LEGITIMATE_LO_SUM_ADDRESS_P): Same.
	(HARD_REGNO_MODE_OK): Altivec modes can only go in altivec
	registers.
	(SECONDARY_MEMORY_NEEDED): We need memory to copy vector modes.
	(TARGET_SWITCHES): Add no-altivec.
	(DATA_ALIGNMENT): Align vectors to 128 bits.
	(TARGET_OPTIONS): Add abi= option.
	Add rs6000_abi_string extern.
	(LOCAL_ALIGNMENT): New.
	(CPP_CPU_SPEC): Define __ALTIVEC__ when -maltivec.
	(MASK_ALTIVEC_ABI): New.
	(TARGET_ALTIVEC_ABI): New.
	(CONDITIONAL_REGISTER_USAGE): Set first 20 AltiVec registers to
	call-saved.
	(STACK_BOUNDARY): Adjust for altivec.
	(BIGGEST_ALIGNMENT): Same.
	(rs6000_args): Add vregno.
	(USE_ALTIVEC_FOR_ARG_P): New.
	(FIXED_REGISTERS): Add vrsave register.
	(CALL_USED_REGISTERS): Same.
	(CONDITIONAL_REGISTER_USAGE): Set VRSAVE info.
	(VRSAVE_REGNO): New.
	(reg_class): Add VRSAVE_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REGNO_REG_CLASS): Same.

	* config/rs6000/sysv4.h (STACK_BOUNDARY): Adjust for altivec.
	(ABI_STACK_BOUNDARY): Same.
	(BIGGEST_ALIGNMENT): Same.
	(ADJUST_FIELD_ALIGN): Remove undef.  Define anew.
	(ROUND_TYPE_ALIGN): Same.

	* config/rs6000/aix.h (ROUND_TYPE_ALIGN): Change BIGGEST_ALIGNMENT
	to 64.

	* config/rs6000/rs6000.c (rs6000_expand_builtin): New.
	(altivec_expand_builtin): New.
	(altivec_init_builtins): New.
	(TARGET_EXPAND_BUILTIN): New.
	(TARGET_INIT_BUILTINS): New.
	(rs6000_init_builtins): New.
	(struct builtin_description): New.
	(bdesc_2arg): New.
	(rs6000_reg_names): Add altivec registers.
	(alt_reg_names): Same.
	(secondary_reload_class): Altivec regs can hold altivec regs and
	memory.
	(rs6000_emit_move): Force constants into memory for AltiVec moves.
	(print_operand): Add 'y' case for printing altivec memory
	operands.
	(rs6000_legitimize_address): Legitimize vector addresses into
	[REG+REG] or [REG].
	(altivec_expand_binop_builtin): New.
	New string rs6000_current_abi.
	(rs6000_override_options): Call rs6000_parse_abi_options.
	(rs6000_parse_abi_options): New.
	(function_arg_boundary): Vector arguments must be 16
	byte aligned.
	(function_arg_advance): Handle vector arguments.
	(function_arg_partial_nregs): Same.
	(init_cumulative_args): Same.
	(function_arg): Same.

	* config/rs6000/rs6000.md (altivec_lvx): New.
	(type): Add altivec attribute.
	(movv4si): New.
	(*movv4si_internal): New.
	(movv16qi): New.
	(*movv16qi_internal): New.
	(movv8hi): New.
	(*movv8hi_internal1): New.
	(movv4sf): New.
	(*movv4sf_internal1): New.
	(altivec_stvx): New.
	(vaddubm): New.
	(vadduhm): New.
	(vadduwm): New.
	(vaddfp): New.
	(vaddcuw): New.
	(vaddubs): New.
	(vaddsbs): New.
	(vadduhs): New.
	(vaddshs): New.
	(vadduws): New.
	(vaddsws): New.
	(vand): New.
	(vandc): New.
	(vavgub): New.
	(vavgsb): New.
	(vavguh): New.
	(vavgsh): New.
	(vavguw): New.
	(vavgsw): New.
	(vcmpbfp): New.
	(vcmpequb): New.
	(vcmpequh): New.
	(vcmpequw): New.
	(vcmpeqfp): New.
	(vcmpgefp): New.
	(vcmpgtub): New.
	(vcmpgtsb): New.
	(vcmpgtuh): New.
	(vcmpgtsh): New.
	(vcmpgtuw): New.
	(vcmpgtsw): New.
	(vcmpgtfp): New.
	(vcmpgefp): New.
	(vcmpgtub): New.
	(vcmpgtsb): New.
	(vcmpgtuh): New.
	(vcmpgtsh): New.
	(vcmpgtuw): New.
	(vcmpgtsw): New.
	(vcmpgtfp): New.
	(vmaxub): New.
	(vmaxsb): New.
	(vmaxuh): New.
	(vmaxsh): New.
	(vmaxuw): New.
	(vmaxsw): New.
	(vmaxfp): New.
	(vmrghb): New.
	(vmrghh): New.
	(vmrghw): New.
	(vmrglb): New.
	(vmrglh): New.
	(vmrglw): New.
	(vminub): New.
	(vminsb): New.
	(vminuh): New.
	(vminsh): New.
	(vminuw): New.
	(vminsw): New.
	(vminfp): New.
	(vmuleub): New.
	(vmulesb): New.
	(vmuleuh): New.
	(vmulesh): New.
	(vmuloub): New.
	(vmulosb): New.
	(vmulouh): New.
	(vmulosh): New.
	(vnor): New.
	(vor): New.
	(vpkuhum): New.
	(vpkuwum): New.
	(vpkpx): New.
	(vpkuhss): New.
	(vpkshss): New.
	(vpkuwss): New.
	(vpkswss): New.
	(vpkuhus): New.
	(vpkshus): New.
	(vpkuwus): New.
	(vpkswus): New.
	(vrlb): New.
	(vrlh): New.
	(vrlw): New.
	(vslb): New.
	(vslh): New.
	(vslw): New.
	(vsl): New.
	(vslo): New.
	(vsrb): New.
	(vrsh): New.
	(vrsw): New.
	(vsrab): New.
	(vsrah): New.
	(vsraw): New.
	(vsr): New.
	(vsro): New.
	(vsububm): New.
	(vsubuhm): New.
	(vsubuwm): New.
	(vsubfp): New.
	(vsubcuw): New.
	(vsububs): New.
	(vsubsbs): New.
	(vsubuhs): New.
	(vsubshs): New.
	(vsubuws): New.
	(vsubsws): New.
	(vsum4ubs): New.
	(vsum4sbs): New.
	(vsum4shs): New.
	(vsum2sws): New.
	(vsumsws): New.
	(vxor): New.

From-SVN: r46833
parent 178612c9
...@@ -115,7 +115,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -115,7 +115,7 @@ Boston, MA 02111-1307, USA. */
|| TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (STRUCT) != 0 \ && TYPE_FIELDS (STRUCT) != 0 \
&& DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \ && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
: MAX ((COMPUTED), (SPECIFIED))) : MAX ((COMPUTED), (SPECIFIED)))
......
...@@ -96,6 +96,9 @@ int fixuplabelno = 0; ...@@ -96,6 +96,9 @@ int fixuplabelno = 0;
/* ABI enumeration available for subtarget to use. */ /* ABI enumeration available for subtarget to use. */
enum rs6000_abi rs6000_current_abi; enum rs6000_abi rs6000_current_abi;
/* ABI string from -mabi= option. */
const char *rs6000_abi_string;
/* Debug flags */ /* Debug flags */
const char *rs6000_debug_name; const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */ int rs6000_debug_stack; /* debug stack applications */
...@@ -146,6 +149,13 @@ static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int)); ...@@ -146,6 +149,13 @@ static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int rs6000_adjust_priority PARAMS ((rtx, int)); static int rs6000_adjust_priority PARAMS ((rtx, int));
static int rs6000_issue_rate PARAMS ((void)); static int rs6000_issue_rate PARAMS ((void));
static void rs6000_init_builtins PARAMS ((tree));
static void altivec_init_builtins PARAMS ((void));
static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static rtx altivec_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
static void rs6000_parse_abi_options PARAMS ((void));
/* Default register names. */ /* Default register names. */
char rs6000_reg_names[][8] = char rs6000_reg_names[][8] =
...@@ -160,7 +170,13 @@ char rs6000_reg_names[][8] = ...@@ -160,7 +170,13 @@ char rs6000_reg_names[][8] =
"24", "25", "26", "27", "28", "29", "30", "31", "24", "25", "26", "27", "28", "29", "30", "31",
"mq", "lr", "ctr","ap", "mq", "lr", "ctr","ap",
"0", "1", "2", "3", "4", "5", "6", "7", "0", "1", "2", "3", "4", "5", "6", "7",
"xer" "xer",
/* AltiVec registers. */
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
"vrsave"
}; };
#ifdef TARGET_REGNAMES #ifdef TARGET_REGNAMES
...@@ -176,7 +192,13 @@ static const char alt_reg_names[][8] = ...@@ -176,7 +192,13 @@ static const char alt_reg_names[][8] =
"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31", "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
"mq", "lr", "ctr", "ap", "mq", "lr", "ctr", "ap",
"%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
"xer" "xer",
/* AltiVec registers. */
"%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
"%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
"%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
"%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
"%vrsave"
}; };
#endif #endif
...@@ -205,6 +227,12 @@ static const char alt_reg_names[][8] = ...@@ -205,6 +227,12 @@ static const char alt_reg_names[][8] =
#undef TARGET_SCHED_ADJUST_PRIORITY #undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS rs6000_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
/* Override command line options. Mostly we process the processor /* Override command line options. Mostly we process the processor
...@@ -438,6 +466,9 @@ rs6000_override_options (default_cpu) ...@@ -438,6 +466,9 @@ rs6000_override_options (default_cpu)
error ("Unknown -mdebug-%s switch", rs6000_debug_name); error ("Unknown -mdebug-%s switch", rs6000_debug_name);
} }
/* Handle -mabi= options. */
rs6000_parse_abi_options ();
#ifdef TARGET_REGNAMES #ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the /* If the user desires alternate register names, copy in the
alternate names now. */ alternate names now. */
...@@ -463,6 +494,17 @@ rs6000_override_options (default_cpu) ...@@ -463,6 +494,17 @@ rs6000_override_options (default_cpu)
free_machine_status = rs6000_free_machine_status; free_machine_status = rs6000_free_machine_status;
} }
/* Handle -mabi= options. */
void rs6000_parse_abi_options ()
{
if (rs6000_abi_string == 0)
return;
else if (! strcmp (rs6000_abi_string, "altivec"))
target_flags |= MASK_ALTIVEC_ABI;
else
error ("Unknown ABI specified: '%s'", rs6000_abi_string);
}
void void
optimization_options (level, size) optimization_options (level, size)
int level ATTRIBUTE_UNUSED; int level ATTRIBUTE_UNUSED;
...@@ -1544,7 +1586,7 @@ rs6000_legitimize_address (x, oldx, mode) ...@@ -1544,7 +1586,7 @@ rs6000_legitimize_address (x, oldx, mode)
rtx x; rtx x;
rtx oldx ATTRIBUTE_UNUSED; rtx oldx ATTRIBUTE_UNUSED;
enum machine_mode mode; enum machine_mode mode;
{ {
if (GET_CODE (x) == PLUS if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT && GET_CODE (XEXP (x, 1)) == CONST_INT
...@@ -1570,6 +1612,18 @@ rs6000_legitimize_address (x, oldx, mode) ...@@ -1570,6 +1612,18 @@ rs6000_legitimize_address (x, oldx, mode)
return gen_rtx_PLUS (Pmode, XEXP (x, 0), return gen_rtx_PLUS (Pmode, XEXP (x, 0),
force_reg (Pmode, force_operand (XEXP (x, 1), 0))); force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
} }
else if (ALTIVEC_VECTOR_MODE (mode))
{
rtx reg;
/* Make sure both operands are registers. */
if (GET_CODE (x) == PLUS)
return gen_rtx_PLUS (Pmode, XEXP (x, 0),
force_reg (Pmode, XEXP (x, 1)));
reg = force_reg (Pmode, x);
return reg;
}
else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
&& GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_DOUBLE
...@@ -1887,6 +1941,15 @@ rs6000_emit_move (dest, source, mode) ...@@ -1887,6 +1941,15 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]); operands[1] = force_const_mem (mode, operands[1]);
break; break;
case V16QImode:
case V8HImode:
case V4SFmode:
case V4SImode:
/* fixme: aldyh -- allow vector constants when they are implemented. */
if (CONSTANT_P (operands[1]))
operands[1] = force_const_mem (mode, operands[1]);
break;
case SImode: case SImode:
case DImode: case DImode:
/* Use default pattern for address of ELF small data */ /* Use default pattern for address of ELF small data */
...@@ -2087,6 +2150,7 @@ init_cumulative_args (cum, fntype, libname, incoming) ...@@ -2087,6 +2150,7 @@ init_cumulative_args (cum, fntype, libname, incoming)
*cum = zero_cumulative; *cum = zero_cumulative;
cum->words = 0; cum->words = 0;
cum->fregno = FP_ARG_MIN_REG; cum->fregno = FP_ARG_MIN_REG;
cum->vregno = ALTIVEC_ARG_MIN_REG;
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL; cum->call_cookie = CALL_NORMAL;
cum->sysv_gregno = GP_ARG_MIN_REG; cum->sysv_gregno = GP_ARG_MIN_REG;
...@@ -2167,6 +2231,8 @@ function_arg_boundary (mode, type) ...@@ -2167,6 +2231,8 @@ function_arg_boundary (mode, type)
if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& (mode == DImode || mode == DFmode)) && (mode == DImode || mode == DFmode))
return 64; return 64;
else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
return 128;
else else
return PARM_BOUNDARY; return PARM_BOUNDARY;
} }
...@@ -2184,7 +2250,14 @@ function_arg_advance (cum, mode, type, named) ...@@ -2184,7 +2250,14 @@ function_arg_advance (cum, mode, type, named)
{ {
cum->nargs_prototype--; cum->nargs_prototype--;
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
cum->vregno++;
else
cum->words += RS6000_ARG_SIZE (mode, type);
}
else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
{ {
if (TARGET_HARD_FLOAT if (TARGET_HARD_FLOAT
&& (mode == SFmode || mode == DFmode)) && (mode == SFmode || mode == DFmode))
...@@ -2312,7 +2385,14 @@ function_arg (cum, mode, type, named) ...@@ -2312,7 +2385,14 @@ function_arg (cum, mode, type, named)
return GEN_INT (cum->call_cookie); return GEN_INT (cum->call_cookie);
} }
if (abi == ABI_V4 || abi == ABI_SOLARIS) if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
if (cum->vregno <= ALTIVEC_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->vregno);
else
return NULL;
}
else if (abi == ABI_V4 || abi == ABI_SOLARIS)
{ {
if (TARGET_HARD_FLOAT if (TARGET_HARD_FLOAT
&& (mode == SFmode || mode == DFmode)) && (mode == SFmode || mode == DFmode))
...@@ -2407,7 +2487,8 @@ function_arg_partial_nregs (cum, mode, type, named) ...@@ -2407,7 +2487,8 @@ function_arg_partial_nregs (cum, mode, type, named)
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
return 0; return 0;
if (USE_FP_FOR_ARG_P (*cum, mode, type)) if (USE_FP_FOR_ARG_P (*cum, mode, type)
|| USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
{ {
if (cum->nargs_prototype >= 0) if (cum->nargs_prototype >= 0)
return 0; return 0;
...@@ -2863,6 +2944,476 @@ rs6000_va_arg (valist, type) ...@@ -2863,6 +2944,476 @@ rs6000_va_arg (valist, type)
return addr_rtx; return addr_rtx;
} }
/* Builtins. */
#define def_builtin(MASK, NAME, TYPE, CODE) \
do { \
if ((MASK) & target_flags) \
builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL); \
} while (0)
struct builtin_description
{
const unsigned int mask;
const enum insn_code icode;
const char *const name;
const enum rs6000_builtins code;
};
/* Simple binary operatiors: VECc = foo (VECa, VECb). */
static const struct builtin_description bdesc_2arg[] =
{
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddubm, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vadduhm, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vadduwm, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddfp, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vand, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
{ MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxub, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxsb, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxuh, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxsh, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxuw, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxsw, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmaxfp, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminub, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminsb, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminuh, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminsh, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminuw, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminsw, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vminfp, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
{ MASK_ALTIVEC, CODE_FOR_altivec_vor, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
{ MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrsh, "__builtin_altivec_vrsh", ALTIVEC_BUILTIN_VRSH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vrsw, "__builtin_altivec_vrsw", ALTIVEC_BUILTIN_VRSW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsububm, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubuhm, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubuwm, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubfp, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
{ MASK_ALTIVEC, CODE_FOR_altivec_vxor, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
};
static rtx
altivec_expand_binop_builtin (icode, arglist, target)
enum insn_code icode;
tree arglist;
rtx target;
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
enum machine_mode mode1 = insn_data[icode].operand[2].mode;
if (! target
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
pat = GEN_FCN (icode) (target, op0, op1);
if (! pat)
return 0;
emit_insn (pat);
return target;
}
static rtx
altivec_expand_builtin (exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget;
enum machine_mode mode;
int ignore;
{
struct builtin_description *d;
size_t i;
enum insn_code icode;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
tree arg0, arg1, arg2, arg3;
rtx op0, op1, op2, pat;
enum machine_mode tmode, mode0, mode1, mode2;
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
switch (fcode)
{
case ALTIVEC_BUILTIN_LD_INTERNAL:
icode = CODE_FOR_altivec_lvx;
arg0 = TREE_VALUE (arglist);
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
if (! target
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
pat = GEN_FCN (icode) (target, op0);
if (! pat)
return 0;
emit_insn (pat);
return target;
case ALTIVEC_BUILTIN_ST_INTERNAL:
icode = CODE_FOR_altivec_stvx;
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
mode0 = insn_data[icode].operand[0].mode;
mode1 = insn_data[icode].operand[1].mode;
if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
pat = GEN_FCN (icode) (op0, op1);
if (! pat)
return 0;
emit_insn (pat);
return NULL_RTX;
}
/* Handle simple binary operations. */
for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
if (d->code == fcode)
return altivec_expand_binop_builtin (d->icode, arglist, target);
abort ();
return NULL_RTX;
}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
SUBTARGET may be used as the target for computing one of EXP's operands.
IGNORE is nonzero if the value is to be ignored. */
static rtx
rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget;
enum machine_mode mode;
int ignore;
{
if (TARGET_ALTIVEC)
return altivec_expand_builtin (exp, target, subtarget, mode, ignore);
abort ();
}
static void
rs6000_init_builtins (list_node)
tree list_node ATTRIBUTE_UNUSED;
{
if (TARGET_ALTIVEC)
altivec_init_builtins ();
}
static void
altivec_init_builtins (void)
{
struct builtin_description * d;
size_t i;
tree endlink = void_list_node;
tree pint_type_node = build_pointer_type (integer_type_node);
/* V4SI foo (int *). */
tree v4si_ftype_pint
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, pint_type_node, endlink));
/* void foo (int *, V4SI). */
tree void_ftype_pint_v4si
= build_function_type (void_type_node,
tree_cons (NULL_TREE, pint_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree v4si_ftype_v4si_v4si
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree v4sf_ftype_v4sf_v4sf
= build_function_type (V4SF_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
endlink)));
tree v8hi_ftype_v8hi_v8hi
= build_function_type (V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
endlink)));
tree v16qi_ftype_v16qi_v16qi
= build_function_type (V16QI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
endlink)));
tree v4si_ftype_v4sf_v4sf
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
endlink)));
tree v8hi_ftype_v16qi_v16qi
= build_function_type (V8HI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
endlink)));
tree v4si_ftype_v8hi_v8hi
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
endlink)));
tree v8hi_ftype_v4si_v4si
= build_function_type (V8HI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree v16qi_ftype_v8hi_v8hi
= build_function_type (V16QI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
endlink)));
tree v4si_ftype_v16qi_v4si
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree v4si_ftype_v8hi_v4si
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree int_ftype_v4si_v4si
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
tree int_ftype_v4sf_v4sf
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
endlink)));
tree int_ftype_v16qi_v16qi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
endlink)));
tree int_ftype_v8hi_v8hi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node,
endlink)));
def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL);
def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL);
/* Add the simple binary operators. */
for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
{
enum machine_mode mode0, mode1, mode2;
tree type;
if (d->name == 0)
continue;
mode0 = insn_data[d->icode].operand[0].mode;
mode1 = insn_data[d->icode].operand[1].mode;
mode2 = insn_data[d->icode].operand[2].mode;
/* When all three operands are of the same mode. */
if (mode0 == mode1 && mode1 == mode2)
{
switch (mode0)
{
case V4SFmode:
type = v4sf_ftype_v4sf_v4sf;
break;
case V4SImode:
type = v4si_ftype_v4si_v4si;
break;
case V16QImode:
type = v16qi_ftype_v16qi_v16qi;
break;
case V8HImode:
type = v8hi_ftype_v8hi_v8hi;
break;
default:
abort ();
}
}
/* A few other combos we really don't want to do manually. */
/* vint, vfloat, vfloat. */
else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
type = v4si_ftype_v4sf_v4sf;
/* vshort, vchar, vchar. */
else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
type = v8hi_ftype_v16qi_v16qi;
/* vint, vshort, vshort. */
else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
type = v4si_ftype_v8hi_v8hi;
/* vshort, vint, vint. */
else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
type = v8hi_ftype_v4si_v4si;
/* vchar, vshort, vshort. */
else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
type = v16qi_ftype_v8hi_v8hi;
/* vint, vchar, vint. */
else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
type = v4si_ftype_v16qi_v4si;
/* vint, vshort, vint. */
else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
type = v4si_ftype_v8hi_v4si;
/* fixme: aldyh */
/* int, x, x. */
else if (mode0 == SImode)
{
switch (mode1)
{
case V4SImode:
type = int_ftype_v4si_v4si;
break;
case V4SFmode:
type = int_ftype_v4sf_v4sf;
break;
case V16QImode:
type = int_ftype_v16qi_v16qi;
break;
case V8HImode:
type = int_ftype_v8hi_v8hi;
break;
default:
abort ();
}
}
else
abort ();
def_builtin (d->mask, d->name, type, d->code);
}
}
/* Generate a memory reference for expand_block_move, copying volatile, /* Generate a memory reference for expand_block_move, copying volatile,
and other bits from an original memory reference. */ and other bits from an original memory reference. */
...@@ -3966,6 +4517,11 @@ secondary_reload_class (class, mode, in) ...@@ -3966,6 +4517,11 @@ secondary_reload_class (class, mode, in)
&& (class == FLOAT_REGS || class == NON_SPECIAL_REGS)) && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
return NO_REGS; return NO_REGS;
/* Memory, and AltiVec registers can go into AltiVec registers. */
if ((regno == -1 || ALTIVEC_REGNO_P (regno))
&& class == ALTIVEC_REGS)
return NO_REGS;
/* We can copy among the CR registers. */ /* We can copy among the CR registers. */
if ((class == CR_REGS || class == CR0_REGS) if ((class == CR_REGS || class == CR0_REGS)
&& regno >= 0 && CR_REGNO_P (regno)) && regno >= 0 && CR_REGNO_P (regno))
...@@ -4739,6 +5295,32 @@ print_operand (file, x, code) ...@@ -4739,6 +5295,32 @@ print_operand (file, x, code)
reg_names[SMALL_DATA_REG]); reg_names[SMALL_DATA_REG]);
} }
return; return;
/* Print AltiVec memory operand. */
case 'y':
{
rtx tmp;
if (GET_CODE (x) != MEM)
abort ();
tmp = XEXP (x, 0);
if (GET_CODE (tmp) == REG)
fprintf (file, "0, %s", reg_names[REGNO (tmp)]);
else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
{
if (REGNO (XEXP (tmp, 0)) == 0)
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
reg_names[ REGNO (XEXP (tmp, 0)) ]);
else
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
reg_names[ REGNO (XEXP (tmp, 1)) ]);
}
else
abort ();
break;
}
case 0: case 0:
if (GET_CODE (x) == REG) if (GET_CODE (x) == REG)
......
...@@ -83,7 +83,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -83,7 +83,8 @@ Boston, MA 02111-1307, USA. */
%{mcpu=801: -D_ARCH_PPC} \ %{mcpu=801: -D_ARCH_PPC} \
%{mcpu=821: -D_ARCH_PPC} \ %{mcpu=821: -D_ARCH_PPC} \
%{mcpu=823: -D_ARCH_PPC} \ %{mcpu=823: -D_ARCH_PPC} \
%{mcpu=860: -D_ARCH_PPC}" %{mcpu=860: -D_ARCH_PPC} \
%{maltivec: -D__ALTIVEC__}"
/* Common ASM definitions used by ASM_SPEC among the various targets /* Common ASM definitions used by ASM_SPEC among the various targets
for handling -mcpu=xxx switches. */ for handling -mcpu=xxx switches. */
...@@ -209,6 +210,12 @@ extern int target_flags; ...@@ -209,6 +210,12 @@ extern int target_flags;
/* Nonzero if we need to schedule the prolog and epilog. */ /* Nonzero if we need to schedule the prolog and epilog. */
#define MASK_SCHED_PROLOG 0x00040000 #define MASK_SCHED_PROLOG 0x00040000
/* Use AltiVec instructions. */
#define MASK_ALTIVEC 0x00080000
/* Enhance the current ABI with AltiVec extensions. */
#define MASK_ALTIVEC_ABI 0x00100000
#define TARGET_POWER (target_flags & MASK_POWER) #define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2) #define TARGET_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC) #define TARGET_POWERPC (target_flags & MASK_POWERPC)
...@@ -227,6 +234,8 @@ extern int target_flags; ...@@ -227,6 +234,8 @@ extern int target_flags;
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE) #define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD) #define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG) #define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
#define TARGET_ALTIVEC_ABI (target_flags & MASK_ALTIVEC_ABI)
#define TARGET_32BIT (! TARGET_64BIT) #define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT) #define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
...@@ -282,6 +291,10 @@ extern int target_flags; ...@@ -282,6 +291,10 @@ extern int target_flags;
N_("Use PowerPC-64 instruction set")}, \ N_("Use PowerPC-64 instruction set")}, \
{"no-powerpc64", - MASK_POWERPC64, \ {"no-powerpc64", - MASK_POWERPC64, \
N_("Don't use PowerPC-64 instruction set")}, \ N_("Don't use PowerPC-64 instruction set")}, \
{"altivec", MASK_ALTIVEC, \
N_("Use AltiVec instructions.")}, \
{"no-altivec", - MASK_ALTIVEC, \
N_("Don't use AltiVec instructions.")}, \
{"new-mnemonics", MASK_NEW_MNEMONICS, \ {"new-mnemonics", MASK_NEW_MNEMONICS, \
N_("Use new mnemonics for PowerPC architecture")},\ N_("Use new mnemonics for PowerPC architecture")},\
{"old-mnemonics", -MASK_NEW_MNEMONICS, \ {"old-mnemonics", -MASK_NEW_MNEMONICS, \
...@@ -409,6 +422,7 @@ extern enum processor_type rs6000_cpu; ...@@ -409,6 +422,7 @@ extern enum processor_type rs6000_cpu;
{"tune=", &rs6000_select[2].string, \ {"tune=", &rs6000_select[2].string, \
N_("Schedule code for given CPU") }, \ N_("Schedule code for given CPU") }, \
{"debug=", &rs6000_debug_name, N_("Enable debug output") }, \ {"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
{"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
SUBTARGET_OPTIONS \ SUBTARGET_OPTIONS \
} }
...@@ -424,7 +438,8 @@ struct rs6000_cpu_select ...@@ -424,7 +438,8 @@ struct rs6000_cpu_select
extern struct rs6000_cpu_select rs6000_select[]; extern struct rs6000_cpu_select rs6000_select[];
/* Debug support */ /* Debug support */
extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */ extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
extern const char *rs6000_abi_string; /* for -mabi={sysv,darwin,solaris,eabi,aix,altivec} */
extern int rs6000_debug_stack; /* debug stack applications */ extern int rs6000_debug_stack; /* debug stack applications */
extern int rs6000_debug_arg; /* debug argument handling */ extern int rs6000_debug_arg; /* debug argument handling */
...@@ -505,6 +520,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -505,6 +520,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8) #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
#define MIN_UNITS_PER_WORD 4 #define MIN_UNITS_PER_WORD 4
#define UNITS_PER_FP_WORD 8 #define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
/* Type used for ptrdiff_t, as a string used in a declaration. */ /* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int" #define PTRDIFF_TYPE "int"
...@@ -569,13 +585,20 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -569,13 +585,20 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64) #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */ /* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY (TARGET_32BIT ? 64 : 128) #define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */ /* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32 #define FUNCTION_BOUNDARY 32
/* No data type wants to be aligned rounder than this. */ /* No data type wants to be aligned rounder than this. */
#define BIGGEST_ALIGNMENT 64 #define BIGGEST_ALIGNMENT 128
/* A C expression to compute the alignment for a variables in the
local store. TYPE is the data type, and ALIGN is the alignment
that the object would ordinarily have. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
((TARGET_ALTIVEC \
&& TREE_CODE (TYPE)) == VECTOR_TYPE ? 128 : ALIGN)
/* Handle #pragma pack. */ /* Handle #pragma pack. */
#define HANDLE_PRAGMA_PACK 1 #define HANDLE_PRAGMA_PACK 1
...@@ -594,9 +617,11 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -594,9 +617,11 @@ extern int rs6000_debug_arg; /* debug argument handling */
(TREE_CODE (EXP) == STRING_CST \ (TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */ /* Make arrays of chars word-aligned for the same reasons.
Align vectors to 128 bits. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \ #define DATA_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \ (TREE_CODE (TYPE) == VECTOR_TYPE ? 128 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
...@@ -634,10 +659,12 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -634,10 +659,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
a register, in order to work around problems in allocating stack storage a register, in order to work around problems in allocating stack storage
in inline functions. */ in inline functions. */
#define FIRST_PSEUDO_REGISTER 77 #define FIRST_PSEUDO_REGISTER 110
/* This must not decrease, for backwards compatibility. If /* This must not decrease, for backwards compatibility. If
FIRST_PSEUDO_REGISTER increases, this should as well. */ FIRST_PSEUDO_REGISTER increases, this should as well. */
/* fixme: this needs to be defined to "TARGET_ALTIVEC_ABI ? 110 : 77"
and then fix usages of DWARF_FRAME_REGISTERS to work. */
#define DWARF_FRAME_REGISTERS 77 #define DWARF_FRAME_REGISTERS 77
/* 1 for registers that have pervasive standard uses /* 1 for registers that have pervasive standard uses
...@@ -655,7 +682,12 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -655,7 +682,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1} 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, \
/* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0 \
}
/* 1 for registers not available across function calls. /* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any These must include the FIXED_REGISTERS and also any
...@@ -669,7 +701,13 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -669,7 +701,13 @@ extern int rs6000_debug_arg; /* debug argument handling */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1} 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \
/* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0 \
}
#define MQ_REGNO 64 #define MQ_REGNO 64
#define CR0_REGNO 68 #define CR0_REGNO 68
...@@ -679,6 +717,9 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -679,6 +717,9 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define CR4_REGNO 72 #define CR4_REGNO 72
#define MAX_CR_REGNO 75 #define MAX_CR_REGNO 75
#define XER_REGNO 76 #define XER_REGNO 76
#define FIRST_ALTIVEC_REGNO 77
#define LAST_ALTIVEC_REGNO 108
#define VRSAVE_REGNO 109
/* List the order in which to allocate registers. Each register must be /* List the order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS. listed once, even those in FIXED_REGISTERS.
...@@ -701,7 +742,16 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -701,7 +742,16 @@ extern int rs6000_debug_arg; /* debug argument handling */
mq (not saved; best to use it if we can) mq (not saved; best to use it if we can)
ctr (not saved; when we have the choice ctr is better) ctr (not saved; when we have the choice ctr is better)
lr (saved) lr (saved)
cr5, r1, r2, ap, xer (fixed) */ cr5, r1, r2, ap, xer, vrsave (fixed)
AltiVec registers:
v0 - v1 (not saved or used for anything)
v13 - v3 (not saved; incoming vector arg registers)
v2 (not saved; incoming vector arg reg; return value)
v19 - v14 (not saved or used for anything)
v31 - v20 (saved; order given to save least number)
*/
#define REG_ALLOC_ORDER \ #define REG_ALLOC_ORDER \
{32, \ {32, \
...@@ -716,7 +766,14 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -716,7 +766,14 @@ extern int rs6000_debug_arg; /* debug argument handling */
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \ 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, 12, \ 18, 17, 16, 15, 14, 13, 12, \
64, 66, 65, \ 64, 66, 65, \
73, 1, 2, 67, 76} 73, 1, 2, 67, 76, \
/* AltiVec registers. */ \
77, 78, \
90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
79, \
96, 95, 94, 93, 92, 91, \
108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97 \
}
/* True if register is floating-point. */ /* True if register is floating-point. */
#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63) #define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
...@@ -733,6 +790,9 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -733,6 +790,9 @@ extern int rs6000_debug_arg; /* debug argument handling */
/* True if register is the XER register. */ /* True if register is the XER register. */
#define XER_REGNO_P(N) ((N) == XER_REGNO) #define XER_REGNO_P(N) ((N) == XER_REGNO)
/* True if register is an AltiVec register. */
#define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE This is ordinarily the length in words of a value of mode MODE
...@@ -744,8 +804,23 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -744,8 +804,23 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define HARD_REGNO_NREGS(REGNO, MODE) \ #define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \ (FP_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ALTIVEC_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
|| (MODE) == V8HImode \
|| (MODE) == V4SFmode \
|| (MODE) == V4SImode)
/* Define this macro to be nonzero if the port is prepared to handle
insns involving vector mode MODE. At the very least, it must have
move patterns for this mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \
(TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
For POWER and PowerPC, the GPRs can hold any mode, but the float For POWER and PowerPC, the GPRs can hold any mode, but the float
registers only can hold floating modes and DImode, and CR register only registers only can hold floating modes and DImode, and CR register only
...@@ -757,6 +832,7 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -757,6 +832,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
(GET_MODE_CLASS (MODE) == MODE_FLOAT \ (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| (GET_MODE_CLASS (MODE) == MODE_INT \ || (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \ && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \ : XER_REGNO_P (REGNO) ? (MODE) == PSImode \
: ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \ : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \
...@@ -776,6 +852,10 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -776,6 +852,10 @@ extern int rs6000_debug_arg; /* debug argument handling */
? GET_MODE_CLASS (MODE2) == MODE_CC \ ? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \ : GET_MODE_CLASS (MODE2) == MODE_CC \
? GET_MODE_CLASS (MODE1) == MODE_CC \ ? GET_MODE_CLASS (MODE1) == MODE_CC \
: ALTIVEC_VECTOR_MODE (MODE1) \
? ALTIVEC_VECTOR_MODE (MODE2) \
: ALTIVEC_VECTOR_MODE (MODE2) \
? ALTIVEC_VECTOR_MODE (MODE1) \
: 1) : 1)
/* A C expression returning the cost of moving data from a register of class /* A C expression returning the cost of moving data from a register of class
...@@ -785,9 +865,11 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -785,9 +865,11 @@ extern int rs6000_debug_arg; /* debug argument handling */
registers is expensive. */ registers is expensive. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \ #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \ ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \
: (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10 \ : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10 \
: (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10 \ : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10 \
: (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20 \
: (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20 \
: (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS \ : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS \
|| (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS \ || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS \
|| (CLASS1) == LINK_OR_CTR_REGS) \ || (CLASS1) == LINK_OR_CTR_REGS) \
...@@ -839,6 +921,12 @@ extern int rs6000_debug_arg; /* debug argument handling */ ...@@ -839,6 +921,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
global_regs[PIC_OFFSET_TABLE_REGNUM] \ global_regs[PIC_OFFSET_TABLE_REGNUM] \
= fixed_regs[PIC_OFFSET_TABLE_REGNUM] \ = fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
if (TARGET_ALTIVEC_ABI) \
{ \
fixed_regs[VRSAVE_REGNO] = call_used_regs[VRSAVE_REGNO] = 1; \
for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) \
call_used_regs[i] = 1; \
} \
} }
/* Specify the registers used for certain standard purposes. /* Specify the registers used for certain standard purposes.
...@@ -912,6 +1000,8 @@ enum reg_class ...@@ -912,6 +1000,8 @@ enum reg_class
BASE_REGS, BASE_REGS,
GENERAL_REGS, GENERAL_REGS,
FLOAT_REGS, FLOAT_REGS,
ALTIVEC_REGS,
VRSAVE_REGS,
NON_SPECIAL_REGS, NON_SPECIAL_REGS,
MQ_REGS, MQ_REGS,
LINK_REGS, LINK_REGS,
...@@ -937,6 +1027,8 @@ enum reg_class ...@@ -937,6 +1027,8 @@ enum reg_class
"BASE_REGS", \ "BASE_REGS", \
"GENERAL_REGS", \ "GENERAL_REGS", \
"FLOAT_REGS", \ "FLOAT_REGS", \
"ALTIVEC_REGS", \
"VRSAVE_REGS", \
"NON_SPECIAL_REGS", \ "NON_SPECIAL_REGS", \
"MQ_REGS", \ "MQ_REGS", \
"LINK_REGS", \ "LINK_REGS", \
...@@ -955,24 +1047,26 @@ enum reg_class ...@@ -955,24 +1047,26 @@ enum reg_class
This is an initializer for a vector of HARD_REG_SET This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */ of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ \ { \
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
{ 0xfffffffe, 0x00000000, 0x00000008 }, /* BASE_REGS */ \ { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */ \
{ 0xffffffff, 0x00000000, 0x00000008 }, /* GENERAL_REGS */ \ { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000 }, /* FLOAT_REGS */ \ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000008 }, /* NON_SPECIAL_REGS */ \ { 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001 }, /* MQ_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */ \
{ 0x00000000, 0x00000000, 0x00000002 }, /* LINK_REGS */ \ { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000004 }, /* CTR_REGS */ \ { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \
{ 0x00000000, 0x00000000, 0x00000006 }, /* LINK_OR_CTR_REGS */ \ { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \
{ 0x00000000, 0x00000000, 0x00000007 }, /* SPECIAL_REGS */ \ { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000000f }, /* SPEC_OR_GEN_REGS */ \ { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000010 }, /* CR0_REGS */ \ { 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000ff0 }, /* CR_REGS */ \ { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000ffff }, /* NON_FLOAT_REGS */ \ { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \
{ 0x00000000, 0x00000000, 0x00010000 }, /* XER_REGS */ \ { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
{ 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \ { 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */ \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \
} }
/* The same information, inverted: /* The same information, inverted:
...@@ -984,6 +1078,7 @@ enum reg_class ...@@ -984,6 +1078,7 @@ enum reg_class
((REGNO) == 0 ? GENERAL_REGS \ ((REGNO) == 0 ? GENERAL_REGS \
: (REGNO) < 32 ? BASE_REGS \ : (REGNO) < 32 ? BASE_REGS \
: FP_REGNO_P (REGNO) ? FLOAT_REGS \ : FP_REGNO_P (REGNO) ? FLOAT_REGS \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \
: (REGNO) == CR0_REGNO ? CR0_REGS \ : (REGNO) == CR0_REGNO ? CR0_REGS \
: CR_REGNO_P (REGNO) ? CR_REGS \ : CR_REGNO_P (REGNO) ? CR_REGS \
: (REGNO) == MQ_REGNO ? MQ_REGS \ : (REGNO) == MQ_REGNO ? MQ_REGS \
...@@ -991,6 +1086,7 @@ enum reg_class ...@@ -991,6 +1086,7 @@ enum reg_class
: (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \ : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \
: (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \ : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \
: (REGNO) == XER_REGNO ? XER_REGS \ : (REGNO) == XER_REGNO ? XER_REGS \
: (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \
: NO_REGS) : NO_REGS)
/* The class value for index registers, and the one for base regs. */ /* The class value for index registers, and the one for base regs. */
...@@ -1006,6 +1102,7 @@ enum reg_class ...@@ -1006,6 +1102,7 @@ enum reg_class
: (C) == 'q' ? MQ_REGS \ : (C) == 'q' ? MQ_REGS \
: (C) == 'c' ? CTR_REGS \ : (C) == 'c' ? CTR_REGS \
: (C) == 'l' ? LINK_REGS \ : (C) == 'l' ? LINK_REGS \
: (C) == 'v' ? ALTIVEC_REGS \
: (C) == 'x' ? CR0_REGS \ : (C) == 'x' ? CR0_REGS \
: (C) == 'y' ? CR_REGS \ : (C) == 'y' ? CR_REGS \
: (C) == 'z' ? XER_REGS \ : (C) == 'z' ? XER_REGS \
...@@ -1103,11 +1200,14 @@ enum reg_class ...@@ -1103,11 +1200,14 @@ enum reg_class
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class (CLASS, MODE, IN) secondary_reload_class (CLASS, MODE, IN)
/* If we are copying between FP registers and anything else, we need a memory /* If we are copying between FP or AltiVec registers and anything
location. */ else, we need a memory location. */
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS)) ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS \
|| (CLASS2) == FLOAT_REGS \
|| (CLASS1) == ALTIVEC_REGS \
|| (CLASS2) == ALTIVEC_REGS))
/* Return the maximum number of consecutive registers /* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. needed to represent mode MODE in a register of class CLASS.
...@@ -1294,16 +1394,18 @@ typedef struct rs6000_stack { ...@@ -1294,16 +1394,18 @@ typedef struct rs6000_stack {
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE) \ || POINTER_TYPE_P (VALTYPE) \
? word_mode : TYPE_MODE (VALTYPE), \ ? word_mode : TYPE_MODE (VALTYPE), \
TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \ TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
: TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
? FP_ARG_RETURN : GP_ARG_RETURN) ? FP_ARG_RETURN : GP_ARG_RETURN)
/* Define how to find the value returned by a library function /* Define how to find the value returned by a library function
assuming the value has mode MODE. */ assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \ #define LIBCALL_VALUE(MODE) \
gen_rtx_REG (MODE, (GET_MODE_CLASS (MODE) == MODE_FLOAT \ gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN \
&& TARGET_HARD_FLOAT \ : GET_MODE_CLASS (MODE) == MODE_FLOAT \
? FP_ARG_RETURN : GP_ARG_RETURN)) && TARGET_HARD_FLOAT \
? FP_ARG_RETURN : GP_ARG_RETURN)
/* The definition of this macro implies that there are cases where /* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers. a scalar value cannot be returned in registers.
...@@ -1338,9 +1440,15 @@ typedef struct rs6000_stack { ...@@ -1338,9 +1440,15 @@ typedef struct rs6000_stack {
? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1) #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
/* Minimum and maximum AltiVec registers used to hold arguments. */
#define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2)
#define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
#define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
/* Return registers */ /* Return registers */
#define GP_ARG_RETURN GP_ARG_MIN_REG #define GP_ARG_RETURN GP_ARG_MIN_REG
#define FP_ARG_RETURN FP_ARG_MIN_REG #define FP_ARG_RETURN FP_ARG_MIN_REG
#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
/* Flags for the call/call_value rtl operations set up by function_arg */ /* Flags for the call/call_value rtl operations set up by function_arg */
#define CALL_NORMAL 0x00000000 /* no special processing */ #define CALL_NORMAL 0x00000000 /* no special processing */
...@@ -1352,13 +1460,19 @@ typedef struct rs6000_stack { ...@@ -1352,13 +1460,19 @@ typedef struct rs6000_stack {
/* 1 if N is a possible register number for a function value /* 1 if N is a possible register number for a function value
as seen by the caller. as seen by the caller.
On RS/6000, this is r3 and fp1. */ On RS/6000, this is r3, fp1, and v2 (for AltiVec). */
#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN)) #define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN \
|| ((N) == FP_ARG_RETURN) \
|| (TARGET_ALTIVEC && \
(N) == ALTIVEC_ARG_RETURN))
/* 1 if N is a possible register number for function argument passing. /* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13. */ On RS/6000, these are r3-r10 and fp1-fp13.
On AltiVec, v2 - v13 are used for passing vectors. */
#define FUNCTION_ARG_REGNO_P(N) \ #define FUNCTION_ARG_REGNO_P(N) \
((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \ ((unsigned)(((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
|| (TARGET_ALTIVEC && \
(unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_MAX_REG)) \
|| ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG))) || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
...@@ -1394,6 +1508,7 @@ typedef struct rs6000_args ...@@ -1394,6 +1508,7 @@ typedef struct rs6000_args
{ {
int words; /* # words used for passing GP registers */ int words; /* # words used for passing GP registers */
int fregno; /* next available FP register */ int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */ int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */ int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */ int prototype; /* Whether a prototype was defined */
...@@ -1436,6 +1551,12 @@ typedef struct rs6000_args ...@@ -1436,6 +1551,12 @@ typedef struct rs6000_args
&& (CUM).fregno <= FP_ARG_MAX_REG \ && (CUM).fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT) && TARGET_HARD_FLOAT)
/* Non-zero if we can use an AltiVec register to pass this arg. */
#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
(ALTIVEC_VECTOR_MODE (MODE) \
&& (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
&& TARGET_ALTIVEC_ABI)
/* Determine where to put an argument to a function. /* Determine where to put an argument to a function.
Value is zero to push the argument on the stack, Value is zero to push the argument on the stack,
or a hard register in which to store the argument. or a hard register in which to store the argument.
...@@ -1778,6 +1899,7 @@ typedef struct rs6000_args ...@@ -1778,6 +1899,7 @@ typedef struct rs6000_args
&& GET_CODE (XEXP (X, 0)) == REG \ && GET_CODE (XEXP (X, 0)) == REG \
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \ && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \ && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
&& (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0) \
&& (((MODE) != DFmode && (MODE) != DImode) \ && (((MODE) != DFmode && (MODE) != DImode) \
|| (TARGET_32BIT \ || (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \ ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
...@@ -1805,6 +1927,7 @@ typedef struct rs6000_args ...@@ -1805,6 +1927,7 @@ typedef struct rs6000_args
&& ! flag_pic && ! TARGET_TOC \ && ! flag_pic && ! TARGET_TOC \
&& (MODE) != DImode \ && (MODE) != DImode \
&& (MODE) != TImode \ && (MODE) != TImode \
&& ! ALTIVEC_VECTOR_MODE (MODE) \
&& (TARGET_HARD_FLOAT || (MODE) != DFmode) \ && (TARGET_HARD_FLOAT || (MODE) != DFmode) \
&& GET_CODE (X) == LO_SUM \ && GET_CODE (X) == LO_SUM \
&& GET_CODE (XEXP (X, 0)) == REG \ && GET_CODE (XEXP (X, 0)) == REG \
...@@ -2389,6 +2512,40 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ ...@@ -2389,6 +2512,40 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[75][0], /* cr7 */ \ &rs6000_reg_names[75][0], /* cr7 */ \
\ \
&rs6000_reg_names[76][0], /* xer */ \ &rs6000_reg_names[76][0], /* xer */ \
\
&rs6000_reg_names[77][0], /* v0 */ \
&rs6000_reg_names[78][0], /* v1 */ \
&rs6000_reg_names[79][0], /* v2 */ \
&rs6000_reg_names[80][0], /* v3 */ \
&rs6000_reg_names[81][0], /* v4 */ \
&rs6000_reg_names[82][0], /* v5 */ \
&rs6000_reg_names[83][0], /* v6 */ \
&rs6000_reg_names[84][0], /* v7 */ \
&rs6000_reg_names[85][0], /* v8 */ \
&rs6000_reg_names[86][0], /* v9 */ \
&rs6000_reg_names[87][0], /* v10 */ \
&rs6000_reg_names[88][0], /* v11 */ \
&rs6000_reg_names[89][0], /* v12 */ \
&rs6000_reg_names[90][0], /* v13 */ \
&rs6000_reg_names[91][0], /* v14 */ \
&rs6000_reg_names[92][0], /* v15 */ \
&rs6000_reg_names[93][0], /* v16 */ \
&rs6000_reg_names[94][0], /* v17 */ \
&rs6000_reg_names[95][0], /* v18 */ \
&rs6000_reg_names[96][0], /* v19 */ \
&rs6000_reg_names[97][0], /* v20 */ \
&rs6000_reg_names[98][0], /* v21 */ \
&rs6000_reg_names[99][0], /* v22 */ \
&rs6000_reg_names[100][0], /* v23 */ \
&rs6000_reg_names[101][0], /* v24 */ \
&rs6000_reg_names[102][0], /* v25 */ \
&rs6000_reg_names[103][0], /* v26 */ \
&rs6000_reg_names[104][0], /* v27 */ \
&rs6000_reg_names[105][0], /* v28 */ \
&rs6000_reg_names[106][0], /* v29 */ \
&rs6000_reg_names[107][0], /* v30 */ \
&rs6000_reg_names[108][0], /* v31 */ \
&rs6000_reg_names[109][0], /* vrsave */ \
} }
/* print-rtl can't handle the above REGISTER_NAMES, so define the /* print-rtl can't handle the above REGISTER_NAMES, so define the
...@@ -2407,7 +2564,12 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ ...@@ -2407,7 +2564,12 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"mq", "lr", "ctr", "ap", \ "mq", "lr", "ctr", "ap", \
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
"xer" \ "xer", \
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
"vrsave" \
} }
/* Table of additional register names to use in user input. */ /* Table of additional register names to use in user input. */
...@@ -2429,6 +2591,15 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ ...@@ -2429,6 +2591,15 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \ {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \
{"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \ {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \
{"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63}, \ {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63}, \
{"v0", 77}, {"v1", 78}, {"v2", 79}, {"v3", 80}, \
{"v4", 81}, {"v5", 82}, {"v6", 83}, {"v7", 84}, \
{"v8", 85}, {"v9", 86}, {"v10", 87}, {"v11", 88}, \
{"v12", 89}, {"v13", 90}, {"v14", 91}, {"v15", 92}, \
{"v16", 93}, {"v17", 94}, {"v18", 95}, {"v19", 96}, \
{"v20", 97}, {"v21", 98}, {"v22", 99}, {"v23", 100}, \
{"v24", 101},{"v25", 102},{"v26", 103},{"v27", 104}, \
{"v28", 105},{"v29", 106},{"v30", 107},{"v31", 108}, \
{"vrsave", 109}, \
/* no additional names for: mq, lr, ctr, ap */ \ /* no additional names for: mq, lr, ctr, ap */ \
{"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \ {"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \
{"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \ {"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \
...@@ -2629,3 +2800,116 @@ extern int flag_pic; ...@@ -2629,3 +2800,116 @@ extern int flag_pic;
extern int optimize; extern int optimize;
extern int flag_expensive_optimizations; extern int flag_expensive_optimizations;
extern int frame_pointer_needed; extern int frame_pointer_needed;
enum rs6000_builtins
{
/* AltiVec builtins. */
ALTIVEC_BUILTIN_ST_INTERNAL,
ALTIVEC_BUILTIN_LD_INTERNAL,
ALTIVEC_BUILTIN_VADDUBM,
ALTIVEC_BUILTIN_VADDUHM,
ALTIVEC_BUILTIN_VADDUWM,
ALTIVEC_BUILTIN_VADDFP,
ALTIVEC_BUILTIN_VADDCUW,
ALTIVEC_BUILTIN_VADDUBS,
ALTIVEC_BUILTIN_VADDSBS,
ALTIVEC_BUILTIN_VADDUHS,
ALTIVEC_BUILTIN_VADDSHS,
ALTIVEC_BUILTIN_VADDUWS,
ALTIVEC_BUILTIN_VADDSWS,
ALTIVEC_BUILTIN_VAND,
ALTIVEC_BUILTIN_VANDC,
ALTIVEC_BUILTIN_VAVGUB,
ALTIVEC_BUILTIN_VAVGSB,
ALTIVEC_BUILTIN_VAVGUH,
ALTIVEC_BUILTIN_VAVGSH,
ALTIVEC_BUILTIN_VAVGUW,
ALTIVEC_BUILTIN_VAVGSW,
ALTIVEC_BUILTIN_VCMPBFP,
ALTIVEC_BUILTIN_VCMPEQUB,
ALTIVEC_BUILTIN_VCMPEQUH,
ALTIVEC_BUILTIN_VCMPEQUW,
ALTIVEC_BUILTIN_VCMPEQFP,
ALTIVEC_BUILTIN_VCMPGEFP,
ALTIVEC_BUILTIN_VCMPGTUB,
ALTIVEC_BUILTIN_VCMPGTSB,
ALTIVEC_BUILTIN_VCMPGTUH,
ALTIVEC_BUILTIN_VCMPGTSH,
ALTIVEC_BUILTIN_VCMPGTUW,
ALTIVEC_BUILTIN_VCMPGTSW,
ALTIVEC_BUILTIN_VCMPGTFP,
ALTIVEC_BUILTIN_VMAXUB,
ALTIVEC_BUILTIN_VMAXSB,
ALTIVEC_BUILTIN_VMAXUH,
ALTIVEC_BUILTIN_VMAXSH,
ALTIVEC_BUILTIN_VMAXUW,
ALTIVEC_BUILTIN_VMAXSW,
ALTIVEC_BUILTIN_VMAXFP,
ALTIVEC_BUILTIN_VMRGHB,
ALTIVEC_BUILTIN_VMRGHH,
ALTIVEC_BUILTIN_VMRGHW,
ALTIVEC_BUILTIN_VMRGLB,
ALTIVEC_BUILTIN_VMRGLH,
ALTIVEC_BUILTIN_VMRGLW,
ALTIVEC_BUILTIN_VMINUB,
ALTIVEC_BUILTIN_VMINSB,
ALTIVEC_BUILTIN_VMINUH,
ALTIVEC_BUILTIN_VMINSH,
ALTIVEC_BUILTIN_VMINUW,
ALTIVEC_BUILTIN_VMINSW,
ALTIVEC_BUILTIN_VMINFP,
ALTIVEC_BUILTIN_VMULEUB,
ALTIVEC_BUILTIN_VMULESB,
ALTIVEC_BUILTIN_VMULEUH,
ALTIVEC_BUILTIN_VMULESH,
ALTIVEC_BUILTIN_VMULOUB,
ALTIVEC_BUILTIN_VMULOSB,
ALTIVEC_BUILTIN_VMULOUH,
ALTIVEC_BUILTIN_VMULOSH,
ALTIVEC_BUILTIN_VNOR,
ALTIVEC_BUILTIN_VOR,
ALTIVEC_BUILTIN_VPKUHUM,
ALTIVEC_BUILTIN_VPKUWUM,
ALTIVEC_BUILTIN_VPKPX,
ALTIVEC_BUILTIN_VPKUHSS,
ALTIVEC_BUILTIN_VPKSHSS,
ALTIVEC_BUILTIN_VPKUWSS,
ALTIVEC_BUILTIN_VPKSWSS,
ALTIVEC_BUILTIN_VPKUHUS,
ALTIVEC_BUILTIN_VPKSHUS,
ALTIVEC_BUILTIN_VPKUWUS,
ALTIVEC_BUILTIN_VPKSWUS,
ALTIVEC_BUILTIN_VRLB,
ALTIVEC_BUILTIN_VRLH,
ALTIVEC_BUILTIN_VRLW,
ALTIVEC_BUILTIN_VSLB,
ALTIVEC_BUILTIN_VSLH,
ALTIVEC_BUILTIN_VSLW,
ALTIVEC_BUILTIN_VSL,
ALTIVEC_BUILTIN_VSLO,
ALTIVEC_BUILTIN_VSRB,
ALTIVEC_BUILTIN_VRSH,
ALTIVEC_BUILTIN_VRSW,
ALTIVEC_BUILTIN_VSRAB,
ALTIVEC_BUILTIN_VSRAH,
ALTIVEC_BUILTIN_VSRAW,
ALTIVEC_BUILTIN_VSR,
ALTIVEC_BUILTIN_VSRO,
ALTIVEC_BUILTIN_VSUBUBM,
ALTIVEC_BUILTIN_VSUBUHM,
ALTIVEC_BUILTIN_VSUBUWM,
ALTIVEC_BUILTIN_VSUBFP,
ALTIVEC_BUILTIN_VSUBCUW,
ALTIVEC_BUILTIN_VSUBUBS,
ALTIVEC_BUILTIN_VSUBSBS,
ALTIVEC_BUILTIN_VSUBUHS,
ALTIVEC_BUILTIN_VSUBSHS,
ALTIVEC_BUILTIN_VSUBUWS,
ALTIVEC_BUILTIN_VSUBSWS,
ALTIVEC_BUILTIN_VSUM4UBS,
ALTIVEC_BUILTIN_VSUM4SBS,
ALTIVEC_BUILTIN_VSUM4SHS,
ALTIVEC_BUILTIN_VSUM2SWS,
ALTIVEC_BUILTIN_VSUMSWS,
ALTIVEC_BUILTIN_VXOR
};
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
;; Define an insn type attribute. This is used in function unit delay ;; Define an insn type attribute. This is used in function unit delay
;; computations. ;; computations.
(define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg" (define_attr "type" "integer,load,store,fpload,fpstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,altivec"
(const_string "integer")) (const_string "integer"))
;; Length (in bytes). ;; Length (in bytes).
...@@ -13361,3 +13361,936 @@ ...@@ -13361,3 +13361,936 @@
emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]); emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
DONE; DONE;
}") }")
;; AltiVec patterns
;; Generic LVX load instruction.
(define_insn "altivec_lvx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(match_operand:V4SI 1 "memory_operand" "m"))]
"TARGET_ALTIVEC"
"lvx\t%0,%y1"
[(set_attr "type" "altivec")])
;; Generic STVX store instruction.
(define_insn "altivec_stvx"
[(set (match_operand:V4SI 0 "memory_operand" "=m")
(match_operand:V4SI 1 "register_operand" "v"))]
"TARGET_ALTIVEC"
"stvx\t%1,%y0"
[(set_attr "type" "altivec")])
;; Vector move instructions.
(define_expand "movv4si"
[(set (match_operand:V4SI 0 "nonimmediate_operand" "")
(match_operand:V4SI 1 "any_operand" ""))]
"TARGET_ALTIVEC"
"{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
(define_insn "*movv4si_internal"
[(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v")
(match_operand:V4SI 1 "input_operand" "v,m,v"))]
"TARGET_ALTIVEC"
"@
stvx\t%1,%y0
ldvx\t%0,%y1
vor\t%0,%1,%1"
[(set_attr "type" "altivec")])
(define_expand "movv8hi"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
(match_operand:V8HI 1 "any_operand" ""))]
"TARGET_ALTIVEC"
"{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
(define_insn "*movv8hi_internal1"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v")
(match_operand:V8HI 1 "input_operand" "v,m,v"))]
"TARGET_ALTIVEC"
"@
stvx\t%1,%y0
ldvx\t%0,%y1
vor\t%0,%1,%1"
[(set_attr "type" "altivec")])
(define_expand "movv16qi"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
(match_operand:V16QI 1 "any_operand" ""))]
"TARGET_ALTIVEC"
"{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
(define_insn "*movv16qi_internal1"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v")
(match_operand:V16QI 1 "input_operand" "v,m,v"))]
"TARGET_ALTIVEC"
"@
stvx\t%1,%y0
ldvx\t%0,%y1
vor\t%0,%1,%1"
[(set_attr "type" "altivec")])
(define_expand "movv4sf"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
(match_operand:V4SF 1 "any_operand" ""))]
"TARGET_ALTIVEC"
"{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
(define_insn "*movv4sf_internal1"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v")
(match_operand:V4SF 1 "input_operand" "v,m,v"))]
"TARGET_ALTIVEC"
"@
stvx\t%1,%y0
ldvx\t%0,%y1
vor\t%0,%1,%1"
[(set_attr "type" "altivec")])
;; Simple binary operations.
(define_insn "altivec_vaddubm"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 31))]
"TARGET_ALTIVEC"
"vaddubm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vadduhm"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 32))]
"TARGET_ALTIVEC"
"vadduhm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vadduwm"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 33))]
"TARGET_ALTIVEC"
"vadduwm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddfp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")] 34))]
"TARGET_ALTIVEC"
"vaddfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddcuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 35))]
"TARGET_ALTIVEC"
"vaddcuw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddubs"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 36))]
"TARGET_ALTIVEC"
"vaddubs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddsbs"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 37))]
"TARGET_ALTIVEC"
"vaddsbs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vadduhs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 38))]
"TARGET_ALTIVEC"
"vadduhs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddshs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 39))]
"TARGET_ALTIVEC"
"vaddshs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vadduws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 40))]
"TARGET_ALTIVEC"
"vadduws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vaddsws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 41))]
"TARGET_ALTIVEC"
"vaddsws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vand"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 42))]
"TARGET_ALTIVEC"
"vand\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vandc"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 43))]
"TARGET_ALTIVEC"
"vandc\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavgub"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 44))]
"TARGET_ALTIVEC"
"vavgub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavgsb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 45))]
"TARGET_ALTIVEC"
"vavgsb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavguh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 46))]
"TARGET_ALTIVEC"
"vavguh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavgsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 47))]
"TARGET_ALTIVEC"
"vavgsh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavguw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 48))]
"TARGET_ALTIVEC"
"vavguw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vavgsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 49))]
"TARGET_ALTIVEC"
"vavgsw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vcmpbfp"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")] 50))]
"TARGET_ALTIVEC"
"vcmpbfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 51))]
"TARGET_ALTIVEC"
"vcmpequb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 52))]
"TARGET_ALTIVEC"
"vcmpequh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 53))]
"TARGET_ALTIVEC"
"vcmpequw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 54))]
"TARGET_ALTIVEC"
"vcmpeqfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 55))]
"TARGET_ALTIVEC"
"vcmpgefp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 56))]
"TARGET_ALTIVEC"
"vcmpgtub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 57))]
"TARGET_ALTIVEC"
"vcmpgtsb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 58))]
"TARGET_ALTIVEC"
"vcmpgtuh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 59))]
"TARGET_ALTIVEC"
"vcmpgtsh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 60))]
"TARGET_ALTIVEC"
"vcmpgtuw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 61))]
"TARGET_ALTIVEC"
"vcmpgtsw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(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")] 62))]
"TARGET_ALTIVEC"
"vcmpgtfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxub"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 63))]
"TARGET_ALTIVEC"
"vmaxub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxsb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 64))]
"TARGET_ALTIVEC"
"vmaxsb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxuh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 65))]
"TARGET_ALTIVEC"
"vmaxuh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 66))]
"TARGET_ALTIVEC"
"vmaxsh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 67))]
"TARGET_ALTIVEC"
"vmaxuw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 68))]
"TARGET_ALTIVEC"
"vmaxsw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmaxfp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")] 69))]
"TARGET_ALTIVEC"
"vmaxfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrghb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 70))]
"TARGET_ALTIVEC"
"vmrghb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrghh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 71))]
"TARGET_ALTIVEC"
"vmrghh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrghw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 72))]
"TARGET_ALTIVEC"
"vmrghw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrglb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 73))]
"TARGET_ALTIVEC"
"vmrglb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrglh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 74))]
"TARGET_ALTIVEC"
"vmrglh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmrglw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 75))]
"TARGET_ALTIVEC"
"vmrglw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminub"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 76))]
"TARGET_ALTIVEC"
"vminub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminsb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 77))]
"TARGET_ALTIVEC"
"vminsb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminuh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 78))]
"TARGET_ALTIVEC"
"vminuh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 79))]
"TARGET_ALTIVEC"
"vminsh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 80))]
"TARGET_ALTIVEC"
"vminuw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 81))]
"TARGET_ALTIVEC"
"vminsw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vminfp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")] 82))]
"TARGET_ALTIVEC"
"vminfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmuleub"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 83))]
"TARGET_ALTIVEC"
"vmuleub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmulesb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 84))]
"TARGET_ALTIVEC"
"vmulesb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmuleuh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 85))]
"TARGET_ALTIVEC"
"vmuleuh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmulesh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 86))]
"TARGET_ALTIVEC"
"vmulesh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmuloub"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 87))]
"TARGET_ALTIVEC"
"vmuloub\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmulosb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 88))]
"TARGET_ALTIVEC"
"vmulosb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmulouh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 89))]
"TARGET_ALTIVEC"
"vmulouh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vmulosh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 90))]
"TARGET_ALTIVEC"
"vmulosh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vnor"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 91))]
"TARGET_ALTIVEC"
"vnor\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vor"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 92))]
"TARGET_ALTIVEC"
"vor\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuhum"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 93))]
"TARGET_ALTIVEC"
"vpkuhum\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuwum"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 94))]
"TARGET_ALTIVEC"
"vpkuwum\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkpx"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 95))]
"TARGET_ALTIVEC"
"vpkpx\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuhss"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 96))]
"TARGET_ALTIVEC"
"vpkuhss\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkshss"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 97))]
"TARGET_ALTIVEC"
"vpkshss\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuwss"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 98))]
"TARGET_ALTIVEC"
"vpkuwss\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkswss"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 99))]
"TARGET_ALTIVEC"
"vpkswss\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuhus"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 100))]
"TARGET_ALTIVEC"
"vpkuhus\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkshus"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 101))]
"TARGET_ALTIVEC"
"vpkshus\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkuwus"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 102))]
"TARGET_ALTIVEC"
"vpkuwus\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vpkswus"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 103))]
"TARGET_ALTIVEC"
"vpkswus\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vrlb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 104))]
"TARGET_ALTIVEC"
"vrlb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vrlh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 105))]
"TARGET_ALTIVEC"
"vrlh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vrlw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 106))]
"TARGET_ALTIVEC"
"vrlw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vslb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 107))]
"TARGET_ALTIVEC"
"vslb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vslh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 108))]
"TARGET_ALTIVEC"
"vslh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vslw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 109))]
"TARGET_ALTIVEC"
"vslw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsl"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 110))]
"TARGET_ALTIVEC"
"vsl\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vslo"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 111))]
"TARGET_ALTIVEC"
"vslo\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsrb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 112))]
"TARGET_ALTIVEC"
"vsrb\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vrsh"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 113))]
"TARGET_ALTIVEC"
"vrsh\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vrsw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 114))]
"TARGET_ALTIVEC"
"vrsw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsrab"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 115))]
"TARGET_ALTIVEC"
"vsrab\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsrah"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 116))]
"TARGET_ALTIVEC"
"vsrah\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsraw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 117))]
"TARGET_ALTIVEC"
"vsraw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsr"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 118))]
"TARGET_ALTIVEC"
"vsr\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsro"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 119))]
"TARGET_ALTIVEC"
"vsro\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsububm"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 120))]
"TARGET_ALTIVEC"
"vsububm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubuhm"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 121))]
"TARGET_ALTIVEC"
"vsubuhm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubuwm"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 122))]
"TARGET_ALTIVEC"
"vsubuwm\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubfp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v")] 123))]
"TARGET_ALTIVEC"
"vsubfp\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubcuw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 124))]
"TARGET_ALTIVEC"
"vsubcuw\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsububs"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 125))]
"TARGET_ALTIVEC"
"vsububs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubsbs"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V16QI 2 "register_operand" "v")] 126))]
"TARGET_ALTIVEC"
"vsubsbs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubuhs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 127))]
"TARGET_ALTIVEC"
"vsubuhs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubshs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V8HI 2 "register_operand" "v")] 128))]
"TARGET_ALTIVEC"
"vsubshs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubuws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 129))]
"TARGET_ALTIVEC"
"vsubuws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsubsws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 130))]
"TARGET_ALTIVEC"
"vsubsws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsum4ubs"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 131))]
"TARGET_ALTIVEC"
"vsum4ubs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsum4sbs"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 132))]
"TARGET_ALTIVEC"
"vsum4sbs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsum4shs"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 133))]
"TARGET_ALTIVEC"
"vsum4shs\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsum2sws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 134))]
"TARGET_ALTIVEC"
"vsum2sws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vsumsws"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 135))]
"TARGET_ALTIVEC"
"vsumsws\t%0,%1,%2"
[(set_attr "type" "altivec")])
(define_insn "altivec_vxor"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:V4SI 2 "register_operand" "v")] 136))]
"TARGET_ALTIVEC"
"vxor\t%0,%1,%2"
[(set_attr "type" "altivec")])
...@@ -400,18 +400,31 @@ do { \ ...@@ -400,18 +400,31 @@ do { \
one set of libraries with -mno-eabi instead of eabi libraries and non-eabi one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
versions, just use 64 as the stack boundary. */ versions, just use 64 as the stack boundary. */
#undef STACK_BOUNDARY #undef STACK_BOUNDARY
#define STACK_BOUNDARY 64 #define STACK_BOUNDARY (TARGET_ALTIVEC_ABI ? 128 : 64)
/* Real stack boundary as mandated by the appropriate ABI. */ /* Real stack boundary as mandated by the appropriate ABI. */
#define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128) #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* No data type wants to be aligned rounder than this. */ /* No data type wants to be aligned rounder than this. */
#undef BIGGEST_ALIGNMENT #undef BIGGEST_ALIGNMENT
#define BIGGEST_ALIGNMENT ((TARGET_EABI) ? 64 : 128) #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
? 128 : COMPUTED)
/* Define this macro as an expression for the alignment of a type
(given by TYPE as a tree node) if the alignment computed in the
usual way is COMPUTED and the alignment explicitly specified was
SPECIFIED. */
#define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED) \
((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) \
? 128 : MAX (COMPUTED, SPECIFIED))
#undef BIGGEST_FIELD_ALIGNMENT #undef BIGGEST_FIELD_ALIGNMENT
#undef ADJUST_FIELD_ALIGN #undef ADJUST_FIELD_ALIGN
#undef ROUND_TYPE_ALIGN
/* Use ELF style section commands. */ /* Use ELF style section commands. */
......
...@@ -424,6 +424,7 @@ in the following sections. ...@@ -424,6 +424,7 @@ in the following sections.
-mtune=@var{cpu-type} @gol -mtune=@var{cpu-type} @gol
-mpower -mno-power -mpower2 -mno-power2 @gol -mpower -mno-power -mpower2 -mno-power2 @gol
-mpowerpc -mpowerpc64 -mno-powerpc @gol -mpowerpc -mpowerpc64 -mno-powerpc @gol
-maltivec -mno-altivec @gol
-mpowerpc-gpopt -mno-powerpc-gpopt @gol -mpowerpc-gpopt -mno-powerpc-gpopt @gol
-mpowerpc-gfxopt -mno-powerpc-gfxopt @gol -mpowerpc-gfxopt -mno-powerpc-gfxopt @gol
-mnew-mnemonics -mold-mnemonics @gol -mnew-mnemonics -mold-mnemonics @gol
...@@ -436,6 +437,7 @@ in the following sections. ...@@ -436,6 +437,7 @@ in the following sections.
-mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol -mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol
-mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol -mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol
-mcall-aix -mcall-sysv -mcall-netbsd @gol -mcall-aix -mcall-sysv -mcall-netbsd @gol
-mabi=altivec @gol
-mprototype -mno-prototype @gol -mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol -msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -G @var{num}} -msdata=@var{opt} -mvxworks -G @var{num}}
...@@ -6684,6 +6686,15 @@ values for @var{cpu_type} are used for @option{-mtune} as for ...@@ -6684,6 +6686,15 @@ values for @var{cpu_type} are used for @option{-mtune} as for
architecture, registers, and mnemonics set by @option{-mcpu}, but the architecture, registers, and mnemonics set by @option{-mcpu}, but the
scheduling parameters set by @option{-mtune}. scheduling parameters set by @option{-mtune}.
@item -maltivec
@itemx -mno-altivec
@opindex maltivec
@opindex mno-altivec
These switches enable or disable the use of built-in functions that
allow access to the AltiVec instruction set. You may also need to set
@option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
enhancements.
@item -mfull-toc @item -mfull-toc
@itemx -mno-fp-in-toc @itemx -mno-fp-in-toc
@itemx -mno-sum-in-toc @itemx -mno-sum-in-toc
...@@ -6912,6 +6923,12 @@ Linux-based GNU system. ...@@ -6912,6 +6923,12 @@ Linux-based GNU system.
On System V.4 and embedded PowerPC systems compile code for the On System V.4 and embedded PowerPC systems compile code for the
NetBSD operating system. NetBSD operating system.
@item -mabi=altivec
@opindex mabi=altivec
Extend the current ABI with AltiVec ABI extensions. This does not
change the default ABI, instead it adds the AltiVec ABI extensions to
the current ABI@.
@item -mprototype @item -mprototype
@itemx -mno-prototype @itemx -mno-prototype
@opindex mprototype @opindex mprototype
......
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