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. */
|| TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (STRUCT) != 0 \
&& DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
? MAX (MAX ((COMPUTED), (SPECIFIED)), BIGGEST_ALIGNMENT) \
? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
: MAX ((COMPUTED), (SPECIFIED)))
......
......@@ -96,6 +96,9 @@ int fixuplabelno = 0;
/* ABI enumeration available for subtarget to use. */
enum rs6000_abi rs6000_current_abi;
/* ABI string from -mabi= option. */
const char *rs6000_abi_string;
/* Debug flags */
const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
......@@ -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_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. */
char rs6000_reg_names[][8] =
......@@ -160,7 +170,13 @@ char rs6000_reg_names[][8] =
"24", "25", "26", "27", "28", "29", "30", "31",
"mq", "lr", "ctr","ap",
"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
......@@ -176,7 +192,13 @@ static const char alt_reg_names[][8] =
"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
"mq", "lr", "ctr", "ap",
"%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
......@@ -205,6 +227,12 @@ static const char alt_reg_names[][8] =
#undef TARGET_SCHED_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;
/* Override command line options. Mostly we process the processor
......@@ -438,6 +466,9 @@ rs6000_override_options (default_cpu)
error ("Unknown -mdebug-%s switch", rs6000_debug_name);
}
/* Handle -mabi= options. */
rs6000_parse_abi_options ();
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */
......@@ -463,6 +494,17 @@ rs6000_override_options (default_cpu)
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
optimization_options (level, size)
int level ATTRIBUTE_UNUSED;
......@@ -1570,6 +1612,18 @@ rs6000_legitimize_address (x, oldx, mode)
return gen_rtx_PLUS (Pmode, XEXP (x, 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
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
......@@ -1887,6 +1941,15 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]);
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 DImode:
/* Use default pattern for address of ELF small data */
......@@ -2087,6 +2150,7 @@ init_cumulative_args (cum, fntype, libname, incoming)
*cum = zero_cumulative;
cum->words = 0;
cum->fregno = FP_ARG_MIN_REG;
cum->vregno = ALTIVEC_ARG_MIN_REG;
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL;
cum->sysv_gregno = GP_ARG_MIN_REG;
......@@ -2167,6 +2231,8 @@ function_arg_boundary (mode, type)
if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
&& (mode == DImode || mode == DFmode))
return 64;
else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
return 128;
else
return PARM_BOUNDARY;
}
......@@ -2184,7 +2250,14 @@ function_arg_advance (cum, mode, type, named)
{
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
&& (mode == SFmode || mode == DFmode))
......@@ -2312,7 +2385,14 @@ function_arg (cum, mode, type, named)
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
&& (mode == SFmode || mode == DFmode))
......@@ -2407,7 +2487,8 @@ function_arg_partial_nregs (cum, mode, type, named)
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
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)
return 0;
......@@ -2864,6 +2945,476 @@ rs6000_va_arg (valist, type)
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,
and other bits from an original memory reference. */
......@@ -3966,6 +4517,11 @@ secondary_reload_class (class, mode, in)
&& (class == FLOAT_REGS || class == NON_SPECIAL_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. */
if ((class == CR_REGS || class == CR0_REGS)
&& regno >= 0 && CR_REGNO_P (regno))
......@@ -4740,6 +5296,32 @@ print_operand (file, x, code)
}
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:
if (GET_CODE (x) == REG)
fprintf (file, "%s", reg_names[REGNO (x)]);
......
......@@ -83,7 +83,8 @@ Boston, MA 02111-1307, USA. */
%{mcpu=801: -D_ARCH_PPC} \
%{mcpu=821: -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
for handling -mcpu=xxx switches. */
......@@ -209,6 +210,12 @@ extern int target_flags;
/* Nonzero if we need to schedule the prolog and epilog. */
#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_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC)
......@@ -227,6 +234,8 @@ extern int target_flags;
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
#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_HARD_FLOAT (! TARGET_SOFT_FLOAT)
......@@ -282,6 +291,10 @@ extern int target_flags;
N_("Use PowerPC-64 instruction set")}, \
{"no-powerpc64", - MASK_POWERPC64, \
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, \
N_("Use new mnemonics for PowerPC architecture")},\
{"old-mnemonics", -MASK_NEW_MNEMONICS, \
......@@ -409,6 +422,7 @@ extern enum processor_type rs6000_cpu;
{"tune=", &rs6000_select[2].string, \
N_("Schedule code for given CPU") }, \
{"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
{"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
SUBTARGET_OPTIONS \
}
......@@ -425,6 +439,7 @@ extern struct rs6000_cpu_select rs6000_select[];
/* Debug support */
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_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 MIN_UNITS_PER_WORD 4
#define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
......@@ -569,13 +585,20 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* 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. */
#define FUNCTION_BOUNDARY 32
/* 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. */
#define HANDLE_PRAGMA_PACK 1
......@@ -594,9 +617,11 @@ extern int rs6000_debug_arg; /* debug argument handling */
(TREE_CODE (EXP) == STRING_CST \
&& (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) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
(TREE_CODE (TYPE) == VECTOR_TYPE ? 128 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
......@@ -634,10 +659,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
a register, in order to work around problems in allocating stack storage
in inline functions. */
#define FIRST_PSEUDO_REGISTER 77
#define FIRST_PSEUDO_REGISTER 110
/* This must not decrease, for backwards compatibility. If
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
/* 1 for registers that have pervasive standard uses
......@@ -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, 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.
These must include the FIXED_REGISTERS and also any
......@@ -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, \
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, \
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 CR0_REGNO 68
......@@ -679,6 +717,9 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define CR4_REGNO 72
#define MAX_CR_REGNO 75
#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
listed once, even those in FIXED_REGISTERS.
......@@ -701,7 +742,16 @@ extern int rs6000_debug_arg; /* debug argument handling */
mq (not saved; best to use it if we can)
ctr (not saved; when we have the choice ctr is better)
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 \
{32, \
......@@ -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, \
18, 17, 16, 15, 14, 13, 12, \
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. */
#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
......@@ -733,6 +790,9 @@ extern int rs6000_debug_arg; /* debug argument handling */
/* True if register is the XER register. */
#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
to hold something 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 */
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \
? ((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))
#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.
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
......@@ -757,6 +832,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| (GET_MODE_CLASS (MODE) == MODE_INT \
&& 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 \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \
: ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \
......@@ -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 (MODE1) == MODE_CC \
: ALTIVEC_VECTOR_MODE (MODE1) \
? ALTIVEC_VECTOR_MODE (MODE2) \
: ALTIVEC_VECTOR_MODE (MODE2) \
? ALTIVEC_VECTOR_MODE (MODE1) \
: 1)
/* A C expression returning the cost of moving data from a register of class
......@@ -788,6 +868,8 @@ extern int rs6000_debug_arg; /* debug argument handling */
((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \
: (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) == LINK_REGS || (CLASS1) == CTR_REGS \
|| (CLASS1) == LINK_OR_CTR_REGS) \
......@@ -839,6 +921,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
global_regs[PIC_OFFSET_TABLE_REGNUM] \
= fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= 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.
......@@ -912,6 +1000,8 @@ enum reg_class
BASE_REGS,
GENERAL_REGS,
FLOAT_REGS,
ALTIVEC_REGS,
VRSAVE_REGS,
NON_SPECIAL_REGS,
MQ_REGS,
LINK_REGS,
......@@ -937,6 +1027,8 @@ enum reg_class
"BASE_REGS", \
"GENERAL_REGS", \
"FLOAT_REGS", \
"ALTIVEC_REGS", \
"VRSAVE_REGS", \
"NON_SPECIAL_REGS", \
"MQ_REGS", \
"LINK_REGS", \
......@@ -957,22 +1049,24 @@ enum reg_class
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
{ 0xfffffffe, 0x00000000, 0x00000008 }, /* BASE_REGS */ \
{ 0xffffffff, 0x00000000, 0x00000008 }, /* GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000 }, /* FLOAT_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000008 }, /* NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001 }, /* MQ_REGS */ \
{ 0x00000000, 0x00000000, 0x00000002 }, /* LINK_REGS */ \
{ 0x00000000, 0x00000000, 0x00000004 }, /* CTR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000006 }, /* LINK_OR_CTR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000007 }, /* SPECIAL_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000000f }, /* SPEC_OR_GEN_REGS */ \
{ 0x00000000, 0x00000000, 0x00000010 }, /* CR0_REGS */ \
{ 0x00000000, 0x00000000, 0x00000ff0 }, /* CR_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000ffff }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00010000 }, /* XER_REGS */ \
{ 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
{ 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */ \
{ 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0xffffe000, 0x0001ffff }, /* ALTIVEC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00020000 }, /* VRSAVE_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \
{ 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \
{ 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000007, 0x00000000 }, /* SPECIAL_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \
{ 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \
{ 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
{ 0xffffffff, 0x00000000, 0x0000ffff, 0x00000000 }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00010000, 0x00000000 }, /* XER_REGS */ \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff } /* ALL_REGS */ \
}
/* The same information, inverted:
......@@ -984,6 +1078,7 @@ enum reg_class
((REGNO) == 0 ? GENERAL_REGS \
: (REGNO) < 32 ? BASE_REGS \
: FP_REGNO_P (REGNO) ? FLOAT_REGS \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \
: (REGNO) == CR0_REGNO ? CR0_REGS \
: CR_REGNO_P (REGNO) ? CR_REGS \
: (REGNO) == MQ_REGNO ? MQ_REGS \
......@@ -991,6 +1086,7 @@ enum reg_class
: (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \
: (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \
: (REGNO) == XER_REGNO ? XER_REGS \
: (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \
: NO_REGS)
/* The class value for index registers, and the one for base regs. */
......@@ -1006,6 +1102,7 @@ enum reg_class
: (C) == 'q' ? MQ_REGS \
: (C) == 'c' ? CTR_REGS \
: (C) == 'l' ? LINK_REGS \
: (C) == 'v' ? ALTIVEC_REGS \
: (C) == 'x' ? CR0_REGS \
: (C) == 'y' ? CR_REGS \
: (C) == 'z' ? XER_REGS \
......@@ -1103,11 +1200,14 @@ enum reg_class
#define 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
location. */
/* If we are copying between FP or AltiVec registers and anything
else, we need a memory location. */
#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
needed to represent mode MODE in a register of class CLASS.
......@@ -1294,16 +1394,18 @@ typedef struct rs6000_stack {
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (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)
/* Define how to find the value returned by a library function
assuming the value has mode 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 \
: GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& TARGET_HARD_FLOAT \
? FP_ARG_RETURN : GP_ARG_RETURN))
? FP_ARG_RETURN : GP_ARG_RETURN)
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
......@@ -1338,9 +1440,15 @@ typedef struct rs6000_stack {
? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#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 */
#define GP_ARG_RETURN GP_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 */
#define CALL_NORMAL 0x00000000 /* no special processing */
......@@ -1352,13 +1460,19 @@ typedef struct rs6000_stack {
/* 1 if N is a possible register number for a function value
as seen by the caller.
On RS/6000, this is r3 and fp1. */
#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN || ((N) == FP_ARG_RETURN))
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) \
|| (TARGET_ALTIVEC && \
(N) == ALTIVEC_ARG_RETURN))
/* 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) \
((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)))
......@@ -1394,6 +1508,7 @@ typedef struct rs6000_args
{
int words; /* # words used for passing GP registers */
int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
......@@ -1436,6 +1551,12 @@ typedef struct rs6000_args
&& (CUM).fregno <= FP_ARG_MAX_REG \
&& 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.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
......@@ -1778,6 +1899,7 @@ typedef struct rs6000_args
&& GET_CODE (XEXP (X, 0)) == REG \
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
&& (! ALTIVEC_VECTOR_MODE (MODE) || INTVAL (X) == 0) \
&& (((MODE) != DFmode && (MODE) != DImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
......@@ -1805,6 +1927,7 @@ typedef struct rs6000_args
&& ! flag_pic && ! TARGET_TOC \
&& (MODE) != DImode \
&& (MODE) != TImode \
&& ! ALTIVEC_VECTOR_MODE (MODE) \
&& (TARGET_HARD_FLOAT || (MODE) != DFmode) \
&& GET_CODE (X) == LO_SUM \
&& GET_CODE (XEXP (X, 0)) == REG \
......@@ -2389,6 +2512,40 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[75][0], /* cr7 */ \
\
&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
......@@ -2407,7 +2564,12 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"mq", "lr", "ctr", "ap", \
"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. */
......@@ -2429,6 +2591,15 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \
{"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \
{"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 */ \
{"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \
{"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \
......@@ -2629,3 +2800,116 @@ extern int flag_pic;
extern int optimize;
extern int flag_expensive_optimizations;
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 @@
;; Define an insn type attribute. This is used in function unit delay
;; 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"))
;; Length (in bytes).
......@@ -13361,3 +13361,936 @@
emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
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 { \
one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
versions, just use 64 as the 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. */
#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. */
#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 ADJUST_FIELD_ALIGN
#undef ROUND_TYPE_ALIGN
/* Use ELF style section commands. */
......
......@@ -424,6 +424,7 @@ in the following sections.
-mtune=@var{cpu-type} @gol
-mpower -mno-power -mpower2 -mno-power2 @gol
-mpowerpc -mpowerpc64 -mno-powerpc @gol
-maltivec -mno-altivec @gol
-mpowerpc-gpopt -mno-powerpc-gpopt @gol
-mpowerpc-gfxopt -mno-powerpc-gfxopt @gol
-mnew-mnemonics -mold-mnemonics @gol
......@@ -436,6 +437,7 @@ in the following sections.
-mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol
-mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol
-mcall-aix -mcall-sysv -mcall-netbsd @gol
-mabi=altivec @gol
-mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -G @var{num}}
......@@ -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
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
@itemx -mno-fp-in-toc
@itemx -mno-sum-in-toc
......@@ -6912,6 +6923,12 @@ Linux-based GNU system.
On System V.4 and embedded PowerPC systems compile code for the
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
@itemx -mno-prototype
@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