aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-04-25 11:48:56 +0930
committerAlan Modra <amodra@gcc.gnu.org>2012-04-25 11:48:56 +0930
commitc344e2656abaa01b2afaebb6beef66b90433fbfa (patch)
tree6753bf434b23128855372851d3d46b8ac31b4f2e
parent544055ae6558c7f9d4c80cf31d0dfa8abd240809 (diff)
downloadgcc-c344e2656abaa01b2afaebb6beef66b90433fbfa.zip
gcc-c344e2656abaa01b2afaebb6beef66b90433fbfa.tar.gz
gcc-c344e2656abaa01b2afaebb6beef66b90433fbfa.tar.bz2
rs6000.c (START_USE, [...]): Define.
* config/rs6000/rs6000.c (START_USE, END_USE, NOT_INUSE): Define. (rs6000_emit_prologue): Use the above to catch register overlap. From-SVN: r186798
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c75
2 files changed, 72 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 12f0ac9..8f73814 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2012-04-25 Alan Modra <amodra@gmail.com>
+ * config/rs6000/rs6000.c (START_USE, END_USE, NOT_INUSE): Define.
+ (rs6000_emit_prologue): Use the above to catch register overlap.
+
+2012-04-25 Alan Modra <amodra@gmail.com>
+
* config/rs6000/rs6000.c (rs6000_emit_stack_reset): Delete forward
decl. Move logic selecting update reg to callers. Update all callers.
(rs6000_emit_allocate_stack): Add copy_off param.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 6718149..bb1a2b9 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -19302,6 +19302,29 @@ rs6000_emit_prologue (void)
HOST_WIDE_INT frame_off = 0;
HOST_WIDE_INT sp_off = 0;
+#ifdef ENABLE_CHECKING
+ /* Track and check usage of r0, r11, r12. */
+ int reg_inuse = using_static_chain_p ? 1 << 11 : 0;
+#define START_USE(R) do \
+ { \
+ gcc_assert ((reg_inuse & (1 << (R))) == 0); \
+ reg_inuse |= 1 << (R); \
+ } while (0)
+#define END_USE(R) do \
+ { \
+ gcc_assert ((reg_inuse & (1 << (R))) != 0); \
+ reg_inuse &= ~(1 << (R)); \
+ } while (0)
+#define NOT_INUSE(R) do \
+ { \
+ gcc_assert ((reg_inuse & (1 << (R))) == 0); \
+ } while (0)
+#else
+#define START_USE(R) do {} while (0)
+#define END_USE(R) do {} while (0)
+#define NOT_INUSE(R) do {} while (0)
+#endif
+
if (flag_stack_usage_info)
current_function_static_stack_size = info->total_size;
@@ -19466,6 +19489,7 @@ rs6000_emit_prologue (void)
if (need_r11)
{
ptr_reg = gen_rtx_REG (Pmode, 11);
+ START_USE (11);
}
else if (info->total_size < 32767)
frame_off = info->total_size;
@@ -19478,6 +19502,7 @@ rs6000_emit_prologue (void)
|| crtl->calls_eh_return)
{
ptr_reg = gen_rtx_REG (Pmode, 12);
+ START_USE (12);
}
else
{
@@ -19500,7 +19525,6 @@ rs6000_emit_prologue (void)
}
rs6000_emit_allocate_stack (info->total_size, ptr_reg, -frame_off);
sp_off = info->total_size;
- sp_off = info->total_size;
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie (frame_reg_rtx, false);
}
@@ -19511,6 +19535,7 @@ rs6000_emit_prologue (void)
rtx addr, reg, mem;
reg = gen_rtx_REG (Pmode, 0);
+ START_USE (0);
insn = emit_move_insn (reg, gen_rtx_REG (Pmode, LR_REGNO));
RTX_FRAME_RELATED_P (insn) = 1;
@@ -19526,6 +19551,7 @@ rs6000_emit_prologue (void)
insn = emit_move_insn (mem, reg);
rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
NULL_RTX, NULL_RTX);
+ END_USE (0);
}
}
@@ -19538,6 +19564,7 @@ rs6000_emit_prologue (void)
rtx set;
cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno);
+ START_USE (cr_save_regno);
insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
/* Now, there's no way that dwarf2out_frame_debug_expr is going
@@ -19581,6 +19608,8 @@ rs6000_emit_prologue (void)
/*savep=*/true, /*gpr=*/false, lr);
rs6000_frame_related (insn, frame_reg_rtx, sp_off,
NULL_RTX, NULL_RTX);
+ if (lr)
+ END_USE (0);
}
/* Save GPRs. This is done as a PARALLEL if we are using
@@ -19625,10 +19654,15 @@ rs6000_emit_prologue (void)
if (using_static_chain_p)
{
rtx r0 = gen_rtx_REG (Pmode, 0);
+
+ START_USE (0);
gcc_assert (info->first_gp_reg_save > 11);
emit_move_insn (r0, spe_save_area_ptr);
}
+ else if (REGNO (frame_reg_rtx) != 11)
+ START_USE (11);
+
emit_insn (gen_addsi3 (spe_save_area_ptr,
frame_reg_rtx, GEN_INT (offset)));
if (!using_static_chain_p && REGNO (frame_reg_rtx) == 11)
@@ -19659,8 +19693,16 @@ rs6000_emit_prologue (void)
}
/* Move the static chain pointer back. */
- if (using_static_chain_p && !spe_regs_addressable)
- emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0));
+ if (!spe_regs_addressable)
+ {
+ if (using_static_chain_p)
+ {
+ emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0));
+ END_USE (0);
+ }
+ else if (REGNO (frame_reg_rtx) != 11)
+ END_USE (11);
+ }
}
else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
{
@@ -19681,10 +19723,13 @@ rs6000_emit_prologue (void)
if (ptr_set_up)
frame_off = -end_save;
+ else
+ NOT_INUSE (ptr_regno);
emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, offset));
}
else if (!ptr_set_up)
{
+ NOT_INUSE (ptr_regno);
emit_move_insn (ptr_reg, frame_reg_rtx);
}
ptr_off = -end_save;
@@ -19695,6 +19740,8 @@ rs6000_emit_prologue (void)
/*savep=*/true, /*gpr=*/true, lr);
rs6000_frame_related (insn, ptr_reg, sp_off - ptr_off,
NULL_RTX, NULL_RTX);
+ if (lr)
+ END_USE (0);
}
else if (!WORLD_SAVE_P (info) && using_store_multiple)
{
@@ -19753,12 +19800,15 @@ rs6000_emit_prologue (void)
rtx save_insn, join_insn, note;
long toc_restore_insn;
- gcc_assert (REGNO (frame_reg_rtx) != 11);
tmp_reg = gen_rtx_REG (Pmode, 11);
tmp_reg_si = gen_rtx_REG (SImode, 11);
if (using_static_chain_p)
- emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
- gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
+ {
+ START_USE (0);
+ emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
+ }
+ else
+ START_USE (11);
emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
/* Peek at instruction to which this function returns. If it's
restoring r2, then we know we've already saved r2. We can't
@@ -19811,7 +19861,12 @@ rs6000_emit_prologue (void)
RTX_FRAME_RELATED_P (join_insn) = 1;
if (using_static_chain_p)
- emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
+ {
+ emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
+ END_USE (0);
+ }
+ else
+ END_USE (11);
}
/* Save CR if we use any that must be preserved. */
@@ -19828,6 +19883,7 @@ rs6000_emit_prologue (void)
{
rtx set;
+ START_USE (0);
cr_save_rtx = gen_rtx_REG (SImode, 0);
insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
@@ -19835,6 +19891,7 @@ rs6000_emit_prologue (void)
add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
}
insn = emit_move_insn (mem, cr_save_rtx);
+ END_USE (REGNO (cr_save_rtx));
rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
NULL_RTX, NULL_RTX);
@@ -19856,6 +19913,7 @@ rs6000_emit_prologue (void)
&& (info->vrsave_save_offset
+ info->total_size - frame_off) > 32767))
{
+ START_USE (12);
ptr_reg = gen_rtx_REG (Pmode, 12);
frame_reg_rtx = ptr_reg;
frame_off = -(info->altivec_save_offset + info->altivec_size);
@@ -19864,7 +19922,6 @@ rs6000_emit_prologue (void)
frame_off = info->total_size;
rs6000_emit_allocate_stack (info->total_size, ptr_reg, -frame_off);
sp_off = info->total_size;
- sp_off = info->total_size;
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie (frame_reg_rtx, false);
}
@@ -19896,6 +19953,7 @@ rs6000_emit_prologue (void)
savereg = gen_rtx_REG (V4SImode, i);
+ NOT_INUSE (0);
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn (areg, GEN_INT (offset));
@@ -19928,6 +19986,7 @@ rs6000_emit_prologue (void)
/* 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. */
+ NOT_INUSE (0);
reg = gen_rtx_REG (SImode, 0);
vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
if (TARGET_MACHO)