64-bits wide and is allocated early enough so that the offset
does not overflow the 16-bit load/store offset field. */
rtx sdmode_stack_slot;
- /* True if any VSX or ALTIVEC vector type was used. */
- bool vsx_or_altivec_used_p;
} machine_function;
/* Target cpu type */
ATTRIBUTE_UNUSED;
#endif
static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
-static void rs6000_expand_to_rtl_hook (void);
+static void rs6000_alloc_sdmode_stack_slot (void);
static void rs6000_instantiate_decls (void);
#if TARGET_XCOFF
static void rs6000_xcoff_asm_output_anchor (rtx);
#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
#undef TARGET_EXPAND_TO_RTL_HOOK
-#define TARGET_EXPAND_TO_RTL_HOOK rs6000_expand_to_rtl_hook
+#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
#undef TARGET_INSTANTIATE_DECLS
#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
return NULL_TREE;
}
-static tree
-rs6000_check_vector_mode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
- /* Don't walk into types. */
- if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
- {
- *walk_subtrees = 0;
- return NULL_TREE;
- }
-
- switch (TREE_CODE (*tp))
- {
- case VAR_DECL:
- case PARM_DECL:
- case FIELD_DECL:
- case RESULT_DECL:
- case SSA_NAME:
- case REAL_CST:
- case INDIRECT_REF:
- case ALIGN_INDIRECT_REF:
- case MISALIGNED_INDIRECT_REF:
- case VIEW_CONVERT_EXPR:
- if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (*tp))))
- return *tp;
- break;
- default:
- break;
- }
-
- return NULL_TREE;
-}
-
enum reload_reg_type {
GPR_REGISTER_TYPE,
VECTOR_REGISTER_TYPE,
return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
}
-/* Scan the trees looking for certain types.
-
- Allocate a 64-bit stack slot to be used for copying SDmode values through if
- this function has any SDmode references.
-
- If VSX, note whether any vector operation was done so we can set VRSAVE to
- non-zero, even if we just use the floating point registers to tell the
- kernel to save the vector registers. */
+/* Allocate a 64-bit stack slot to be used for copying SDmode
+ values through if this function has any SDmode references. */
static void
-rs6000_expand_to_rtl_hook (void)
+rs6000_alloc_sdmode_stack_slot (void)
{
tree t;
basic_block bb;
gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
- /* Check for vectors. */
- if (TARGET_VSX)
- {
- FOR_EACH_BB (bb)
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- if (walk_gimple_op (gsi_stmt (gsi), rs6000_check_vector_mode,
- NULL))
- {
- cfun->machine->vsx_or_altivec_used_p = true;
- goto found_vector;
- }
- }
- found_vector:
- ;
- }
-
- /* Check for SDmode being used. */
FOR_EACH_BB (bb)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
if (df_regs_ever_live_p (i))
mask |= ALTIVEC_REG_BIT (i);
- /* If VSX is used, we might have used a traditional floating point register
- in a vector mode without using any altivec registers. However the VRSAVE
- register does not have room to indicate the floating point registers.
- Modern kernels only look to see if the value is non-zero to determine if
- they need to save the vector registers, so we just set an arbitrary
- value if any vector type was used. */
- if (mask == 0 && TARGET_VSX && cfun->machine->vsx_or_altivec_used_p)
- mask = 0xFFF;
-
if (mask == 0)
return mask;
+++ /dev/null
-/* { dg-do compile { target { powerpc*-*-* } } } */
-/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-/* { dg-require-effective-target powerpc_vsx_ok } */
-/* { dg-options "-O2 -mcpu=power7" } */
-/* { dg-final { scan-assembler-times "mtvrsave" 2 } } */
-
-/* Check whether VRSAVE is set to non-zero if VSX vector operations were
- used, but it should not be set if there are no vector operations. */
-
-void
-generates_vrsave (vector double *a, vector double *b, vector double *c)
-{
- *a = *b + *c;
-}
-
-void
-no_vrsave (double *a, double *b, double *c)
-{
- *a = *b + *c;
-}