rs6000.c (rs6000_emit_prologue): Move altivec register saving after stack push.

2007-05-16  Eric Christopher  <echristo@apple.com>

	* config/rs6000/rs6000.c (rs6000_emit_prologue): Move altivec register
        saving after stack push. Set sp_offset whenever we push.
        (rs6000_emit_epilogue): Move altivec register restore before stack push.

From-SVN: r124763
This commit is contained in:
Eric Christopher 2007-05-16 08:30:10 +00:00
parent 748670c25b
commit 2b2c2fe51a
2 changed files with 132 additions and 115 deletions

View file

@ -1,3 +1,9 @@
2007-05-16 Eric Christopher <echristo@apple.com>
* config/rs6000/rs6000.c (rs6000_emit_prologue): Move altivec register
saving after stack push. Set sp_offset whenever we push.
(rs6000_emit_epilogue): Move altivec register restore before stack push.
2007-05-16 Richard Sandiford <richard@codesourcery.com>
* configure.ac: Allow sysroots to be relocated under $prefix as
@ -274,7 +280,7 @@
* tree-flow.h (strict_aliasing_warning_backend): Declare.
* tree-ssa-alias-warnings.c: New file.
* tree-ssa-alias.c (compute_may_aliases): Add call to
strict_aliasing_warning_backend.
strict_aliasing_warning_backend.
2007-05-11 Zdenek Dvorak <dvorakz@suse.cz>
@ -383,9 +389,9 @@
emit_call_insn.
2007-05-09 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.c (xtensa_output_literal): Don't use #if.
2007-05-09 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.c (xtensa_output_literal): Mask out high bits
@ -468,7 +474,7 @@
bfin_expand_epilogue accordingly.
(sibcall_epilogue): Likewise.
(eh_return_internal): Likewise.
* config/bfin/bfin-protos.h (enum bfin_cpu): Add
BFIN_CPU_BF534, BFIN_CPU_BF536 and BFIN_CPU_BF561.
* config/bfin/bfin.c (bfin_handle_option): Handle
@ -482,7 +488,7 @@
PR target/31854
* config/i386/i386.c (ix86_function_regparm): Process local
functions only when TREE_CODE (decl) equals FUNCTION_DECL.
2007-05-07 Mike Stump <mrs@apple.com>
* doc/invoke.texi (Warning Options): Document that -Wempty-body
@ -522,11 +528,11 @@
(function_vector_handler): New
(current_function_special_page_vector): New
(m32c_special_page_vector_p): New.
* config/m32c/m32c-protos.h (m32c_special_page_vector_p):
* config/m32c/m32c-protos.h (m32c_special_page_vector_p):
Prototype.
* config/m32c/jump.md: Added instruction JSRS for functions
* config/m32c/jump.md: Added instruction JSRS for functions
with attribute "function_vector".
* doc/extend.texi (function_vector): Added description
* doc/extend.texi (function_vector): Added description
for M16C, M32C targets.
2007-05-07 DJ Delorie <dj@redhat.com>
@ -575,11 +581,11 @@
2007-05-05 Aurelien Jarno <aurelien@aurel32.net>
* config/pa/pa.md: Split tgd_load, tld_load and tie_load
into pic and non-pic versions. Mark r19 as used for
tgd_load_pic, tld_load_pic and tie_load_pic. Mark r27 as used
into pic and non-pic versions. Mark r19 as used for
tgd_load_pic, tld_load_pic and tie_load_pic. Mark r27 as used
for tgd_load, tld_load and tie_load .
* config/pa/pa.c (legitimize_tls_address): Emit pic or non-pic
version of tgd_load, tld_load and tie_load depending on the
version of tgd_load, tld_load and tie_load depending on the
value of flag_pic.
2007-05-04 Ulrich Drepper <drepper@redhat.com>
@ -651,10 +657,10 @@
("fix_trunc<DSF:mode><GPR:mode>2"): Expander added.
2007-05-04 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.md (adddi3, adddi_carry): Delete.
(subdi3, subdi_carry): Delete.
2007-05-04 Jan Hubicka <jh@suse.cz>
Richard Guenther <rguenther@suse.de>
@ -712,7 +718,7 @@
with changed signature and 'debug_rgn_dependencies ()'.
(debug_rgn_dependencies): New static function.
(init_ready_list): Use it.
* sched-int.h (debug_dependencies): Declare.
2007-05-04 Andreas Krebbel <krebbel1@de.ibm.com>
@ -788,8 +794,8 @@
PR tree-optimization/31699
* tree-vect-analyze.c (vect_update_misalignment_for_peel): Remove wrong
code.
(vect_enhance_data_refs_alignment): Compute peel amount using
TYPE_VECTOR_SUBPARTS instead of vf.
(vect_enhance_data_refs_alignment): Compute peel amount using
TYPE_VECTOR_SUBPARTS instead of vf.
* tree-vect-transform.c (vect_gen_niters_for_prolog_loop): Likewise.
2007-05-02 Brooks Moses <brooks.moses@codesourcery.com>

View file

@ -14812,77 +14812,6 @@ rs6000_emit_prologue (void)
sp_offset = info->total_size;
}
/* Save AltiVec registers if needed. */
if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
{
int i;
/* There should be a non inline version of this, for when we
are saving lots of vector registers. */
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
rtx areg, savereg, mem;
int offset;
offset = info->altivec_save_offset + sp_offset
+ 16 * (i - info->first_altivec_reg_save);
savereg = gen_rtx_REG (V4SImode, i);
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn (areg, GEN_INT (offset));
/* AltiVec addressing mode is [reg+reg]. */
mem = gen_frame_mem (V4SImode,
gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
insn = emit_move_insn (mem, savereg);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
areg, GEN_INT (offset));
}
}
/* VRSAVE is a bit vector representing which AltiVec registers
are used. The OS uses this to determine which vector
registers to save on a context switch. We need to save
VRSAVE on the stack frame, add whatever AltiVec registers we
used in this function, and do the corresponding magic in the
epilogue. */
if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
&& info->vrsave_mask != 0)
{
rtx reg, mem, vrsave;
int offset;
/* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
as frame_reg_rtx and r11 as the static chain pointer for
nested functions. */
reg = gen_rtx_REG (SImode, 0);
vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
if (TARGET_MACHO)
emit_insn (gen_get_vrsave_internal (reg));
else
emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
if (!WORLD_SAVE_P (info))
{
/* Save VRSAVE. */
offset = info->vrsave_save_offset + sp_offset;
mem = gen_frame_mem (SImode,
gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (offset)));
insn = emit_move_insn (mem, reg);
}
/* Include the registers in the mask. */
emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
insn = emit_insn (generate_set_vrsave (reg, info, 0));
}
/* If we use the link register, get it into r0. */
if (!WORLD_SAVE_P (info) && info->lr_save_p)
{
@ -15120,7 +15049,10 @@ rs6000_emit_prologue (void)
for which it was done previously. */
if (!WORLD_SAVE_P (info) && info->push_p
&& !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
rs6000_emit_allocate_stack (info->total_size, FALSE);
{
rs6000_emit_allocate_stack (info->total_size, FALSE);
sp_offset = info->total_size;
}
/* Set frame pointer, if needed. */
if (frame_pointer_needed)
@ -15130,6 +15062,78 @@ rs6000_emit_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
}
/* Save AltiVec registers if needed. Save here because the red zone does
not include AltiVec registers. */
if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
{
int i;
/* There should be a non inline version of this, for when we
are saving lots of vector registers. */
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
rtx areg, savereg, mem;
int offset;
offset = info->altivec_save_offset + sp_offset
+ 16 * (i - info->first_altivec_reg_save);
savereg = gen_rtx_REG (V4SImode, i);
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn (areg, GEN_INT (offset));
/* AltiVec addressing mode is [reg+reg]. */
mem = gen_frame_mem (V4SImode,
gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
insn = emit_move_insn (mem, savereg);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
areg, GEN_INT (offset));
}
}
/* VRSAVE is a bit vector representing which AltiVec registers
are used. The OS uses this to determine which vector
registers to save on a context switch. We need to save
VRSAVE on the stack frame, add whatever AltiVec registers we
used in this function, and do the corresponding magic in the
epilogue. */
if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
&& info->vrsave_mask != 0)
{
rtx reg, mem, vrsave;
int offset;
/* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
as frame_reg_rtx and r11 as the static chain pointer for
nested functions. */
reg = gen_rtx_REG (SImode, 0);
vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
if (TARGET_MACHO)
emit_insn (gen_get_vrsave_internal (reg));
else
emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
if (!WORLD_SAVE_P (info))
{
/* Save VRSAVE. */
offset = info->vrsave_save_offset + sp_offset;
mem = gen_frame_mem (SImode,
gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (offset)));
insn = emit_move_insn (mem, reg);
}
/* Include the registers in the mask. */
emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
insn = emit_insn (generate_set_vrsave (reg, info, 0));
}
/* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
|| (DEFAULT_ABI == ABI_V4
@ -15387,33 +15391,10 @@ rs6000_emit_epilogue (int sibcall)
return;
}
/* If we have a frame pointer, a call to alloca, or a large stack
frame, restore the old stack pointer using the backchain. Otherwise,
we know what size to update it with. */
if (use_backchain_to_restore_sp)
{
/* Under V.4, don't reset the stack pointer until after we're done
loading the saved registers. */
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
emit_move_insn (frame_reg_rtx,
gen_rtx_MEM (Pmode, sp_reg_rtx));
}
else if (info->push_p)
{
if (DEFAULT_ABI == ABI_V4
|| current_function_calls_eh_return)
sp_offset = info->total_size;
else
{
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size)));
}
}
/* Set sp_offset based on the stack push from the prologue. */
if ((DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return)
&& info->total_size < 32767)
sp_offset = info->total_size;
/* Restore AltiVec registers if needed. */
if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
@ -15454,6 +15435,36 @@ rs6000_emit_epilogue (int sibcall)
emit_insn (generate_set_vrsave (reg, info, 1));
}
sp_offset = 0;
/* If we have a frame pointer, a call to alloca, or a large stack
frame, restore the old stack pointer using the backchain. Otherwise,
we know what size to update it with. */
if (use_backchain_to_restore_sp)
{
/* Under V.4, don't reset the stack pointer until after we're done
loading the saved registers. */
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
emit_move_insn (frame_reg_rtx,
gen_rtx_MEM (Pmode, sp_reg_rtx));
}
else if (info->push_p)
{
if (DEFAULT_ABI == ABI_V4
|| current_function_calls_eh_return)
sp_offset = info->total_size;
else
{
emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size)));
}
}
/* Get the old lr if we saved it. */
if (info->lr_save_p)
{