Re: PowerPC prologue and epilogue 4

2012-04-24 Thread David Edelsohn
On Tue, Apr 17, 2012 at 11:13 AM, Alan Modra  wrote:
> This provides some protection against misuse of r0, r11 and r12.  I
> found it useful when enabling out-of-line saves for large frames.  ;-)
>
>        * config/rs6000/rs6000.c (START_USE, END_USE, NOT_INUSE): Define.
>        (rs6000_emit_prologue): Use the above to catch register overlap.

This patch is okay.

Thanks, David


PowerPC prologue and epilogue 4

2012-04-17 Thread Alan Modra
This provides some protection against misuse of r0, r11 and r12.  I
found it useful when enabling out-of-line saves for large frames.  ;-)

* config/rs6000/rs6000.c (START_USE, END_USE, NOT_INUSE): Define.
(rs6000_emit_prologue): Use the above to catch register overlap.

diff -urp gcc-alan3/gcc/config/rs6000/rs6000.c 
gcc-alan4/gcc/config/rs6000/rs6000.c
--- gcc-alan3/gcc/config/rs6000/rs6000.c2012-04-17 07:19:42.927931887 
+0930
+++ gcc-alan4/gcc/config/rs6000/rs6000.c2012-04-17 09:11:31.760669589 
+0930
@@ -19301,6 +19301,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;
 
@@ -19465,6 +19488,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;
@@ -19477,6 +19501,7 @@ rs6000_emit_prologue (void)
   || crtl->calls_eh_return)
{
  ptr_reg = gen_rtx_REG (Pmode, 12);
+ START_USE (12);
}
   else
{
@@ -19509,6 +19534,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;
 
@@ -19524,6 +19550,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);
}
 }
 
@@ -19536,6 +19563,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
@@ -19579,6 +19607,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
@@ -19623,10 +19653,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)
@@ -19657,8 +19692,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)
 {
@@ -19679,10 +19722,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;
@@ -19693,6 +19739,8 @@ rs6000_emit_prologue (void)
 /*savep=*/true, /*gpr=*/true, lr);
   rs6000_frame_related (insn, ptr_reg, sp_off - ptr_off,
NULL_RTX,