From 2b2c2fe51ac9b27af695b04d7058a6154fb5a644 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 16 May 2007 08:30:10 +0000 Subject: [PATCH] rs6000.c (rs6000_emit_prologue): Move altivec register saving after stack push. 2007-05-16 Eric Christopher * 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 --- gcc/ChangeLog | 38 ++++--- gcc/config/rs6000/rs6000.c | 209 +++++++++++++++++++------------------ 2 files changed, 132 insertions(+), 115 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 847d10dd82f..dfa19ac6a6d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-05-16 Eric Christopher + + * 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 * 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 @@ -383,9 +389,9 @@ emit_call_insn. 2007-05-09 Bob Wilson - + * config/xtensa/xtensa.c (xtensa_output_literal): Don't use #if. - + 2007-05-09 Bob Wilson * 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 * 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 @@ -575,11 +581,11 @@ 2007-05-05 Aurelien Jarno * 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 @@ -651,10 +657,10 @@ ("fix_trunc2"): Expander added. 2007-05-04 Bob Wilson - + * config/xtensa/xtensa.md (adddi3, adddi_carry): Delete. (subdi3, subdi_carry): Delete. - + 2007-05-04 Jan Hubicka Richard Guenther @@ -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 @@ -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 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 61564a270b4..64471387738 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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) { -- 2.30.2