Fix 41787
From-SVN: r153498
This commit is contained in:
parent
cb9c2485b2
commit
3fc841c85d
5 changed files with 123 additions and 9 deletions
|
@ -1,3 +1,23 @@
|
|||
2009-10-23 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/41787
|
||||
* config/rs6000/rs6000.c (struct machine_function): Add
|
||||
vsx_or_altivec_used_p to record if vector types are used.
|
||||
(rs6000_expand_to_rtl_hook): Rename from
|
||||
rs6000_alloc_sdmode_stack_slot. If VSX, check to see if there are
|
||||
any vector operations, so if there are, we can set VRSAVE to
|
||||
non-zero when only floating point vector registers are used.
|
||||
(TARGET_EXPAND_TO_RTL_HOOK): Use rs6000_expand_to_rtl_hook.
|
||||
(rs6000_check_vector_mode): Inner function to check if vector
|
||||
types are used in the code.
|
||||
(compute_vrsave_mask): If VSX, make sure VRSAVE is non-zero if
|
||||
vector instructions are used.
|
||||
|
||||
* config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED):
|
||||
Indicate that VSX registers which overlap floating point
|
||||
registers, can't be used across a call, since the ABI only states
|
||||
the scalar part of the register will be saved and restored.
|
||||
|
||||
2009-10-23 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/41673
|
||||
|
|
|
@ -130,6 +130,8 @@ typedef struct GTY(()) machine_function
|
|||
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 */
|
||||
|
@ -913,7 +915,7 @@ static void rs6000_elf_encode_section_info (tree, rtx, int)
|
|||
ATTRIBUTE_UNUSED;
|
||||
#endif
|
||||
static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
|
||||
static void rs6000_alloc_sdmode_stack_slot (void);
|
||||
static void rs6000_expand_to_rtl_hook (void);
|
||||
static void rs6000_instantiate_decls (void);
|
||||
#if TARGET_XCOFF
|
||||
static void rs6000_xcoff_asm_output_anchor (rtx);
|
||||
|
@ -1505,7 +1507,7 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
|||
#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
|
||||
|
||||
#undef TARGET_EXPAND_TO_RTL_HOOK
|
||||
#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
|
||||
#define TARGET_EXPAND_TO_RTL_HOOK rs6000_expand_to_rtl_hook
|
||||
|
||||
#undef TARGET_INSTANTIATE_DECLS
|
||||
#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
|
||||
|
@ -13190,6 +13192,38 @@ rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
|
|||
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,
|
||||
|
@ -13630,11 +13664,17 @@ rs6000_ira_cover_classes (void)
|
|||
return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
|
||||
}
|
||||
|
||||
/* Allocate a 64-bit stack slot to be used for copying SDmode
|
||||
values through if this function has any SDmode references. */
|
||||
/* 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. */
|
||||
|
||||
static void
|
||||
rs6000_alloc_sdmode_stack_slot (void)
|
||||
rs6000_expand_to_rtl_hook (void)
|
||||
{
|
||||
tree t;
|
||||
basic_block bb;
|
||||
|
@ -13642,6 +13682,24 @@ rs6000_alloc_sdmode_stack_slot (void)
|
|||
|
||||
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))
|
||||
{
|
||||
|
@ -16783,6 +16841,15 @@ compute_vrsave_mask (void)
|
|||
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;
|
||||
|
||||
|
|
|
@ -1033,10 +1033,12 @@ extern unsigned rs6000_pointer_size;
|
|||
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
|
||||
|
||||
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
|
||||
((TARGET_32BIT && TARGET_POWERPC64 \
|
||||
&& (GET_MODE_SIZE (MODE) > 4) \
|
||||
&& INT_REGNO_P (REGNO)) ? 1 : 0)
|
||||
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
|
||||
(((TARGET_32BIT && TARGET_POWERPC64 \
|
||||
&& (GET_MODE_SIZE (MODE) > 4) \
|
||||
&& INT_REGNO_P (REGNO)) ? 1 : 0) \
|
||||
|| (TARGET_VSX && FP_REGNO_P (REGNO) \
|
||||
&& GET_MODE_SIZE (MODE) > 8))
|
||||
|
||||
#define VSX_VECTOR_MODE(MODE) \
|
||||
((MODE) == V4SFmode \
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-10-22 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/41787
|
||||
* gcc.target/powerpc/vsx-vrsave.c: New file.
|
||||
|
||||
2009-10-23 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/41673
|
||||
|
|
20
gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c
Normal file
20
gcc/testsuite/gcc.target/powerpc/vsx-vrsave.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* { 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue