This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Frame notes for pa.c


First step towards having dwarf2 debugging on hppa.  This won't do
anything yet, as INCOMING_RETURN_ADDR_RTX insn't yet defined in pa.h.
Patch is othogonal to my last patch for profiling, but may not apply
cleanly as that one hasn't yet gone in.

	* config/pa/pa.c: (set_reg_plus_d): Return last insn.
	(actual_fsize, local_fsize, save_fregs): Move for store_reg to see.
	(DO_FRAME_NOTES): Define to control the following..
	(store_reg): Set RTX_FRAME_RELATED_P on insns, and
	REG_FRAME_RELATED_EXPR notes as necessary.
	(hppa_expand_prologue): Likewise.
	(hppa_expand_epilogue): Likewise.

Alan Modra
-- 
Linuxcare

--- gcc-current/gcc/config/pa/pa.c	Mon Mar 26 17:21:56 2001
+++ gcc-new/gcc/config/pa/pa.c	Fri Mar 30 18:07:49 2001
@@ -42,6 +42,14 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "tm_p.h"
 
+#ifndef DO_FRAME_NOTES
+#ifdef INCOMING_RETURN_ADDR_RTX
+#define DO_FRAME_NOTES 1
+#else
+#define DO_FRAME_NOTES 0
+#endif
+#endif
+
 static void pa_init_machine_status PARAMS ((struct function *));
 static void pa_mark_machine_status PARAMS ((struct function *));
 static void pa_free_machine_status PARAMS ((struct function *));
@@ -56,7 +64,7 @@ static int compute_movstrsi_length			PAR
 static void remove_useless_addtr_insns			PARAMS ((rtx, int));
 static void store_reg					PARAMS ((int, int, int));
 static void load_reg					PARAMS ((int, int, int));
-static void set_reg_plus_d				PARAMS ((int, int, int));
+static rtx set_reg_plus_d				PARAMS ((int, int, int));
 
 /* Save the operands last given to a compare for use when we
    generate a scc or bcc insn.  */
@@ -2743,6 +2751,12 @@ remove_useless_addtr_insns (insns, check
 
 */
 
+/* Global variables set by FUNCTION_PROLOGUE.  */
+/* Size of frame.  Need to know this to emit return insns from
+   leaf procedures.  */
+static int actual_fsize;
+static int local_fsize, save_fregs;
+
 /* Emit RTL to store REG at the memory location specified by BASE+DISP.
    Handle case where DISP > 8k by using the add_high_const patterns.
 
@@ -2753,21 +2767,36 @@ static void
 store_reg (reg, disp, base)
      int reg, disp, base;
 {
+  rtx i, dest, src, basereg;
+
+  src = gen_rtx_REG (word_mode, reg);
+  basereg = gen_rtx_REG (Pmode, base);
   if (VAL_14_BITS_P (disp))
-    emit_move_insn (gen_rtx_MEM (word_mode,
-				 plus_constant (gen_rtx_REG (Pmode, base),
-						disp)),
-		    gen_rtx_REG (word_mode, reg));
+    {
+      dest = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
+      i = emit_move_insn (dest, src);
+    }
   else
     {
-      emit_move_insn (gen_rtx_REG (Pmode, 1),
-		      gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
-				    gen_rtx_HIGH (Pmode, GEN_INT (disp))));
-      emit_move_insn (gen_rtx_MEM (word_mode,
-				   gen_rtx_LO_SUM (Pmode,
-						   gen_rtx_REG (Pmode, 1),
-						   GEN_INT (disp))),
-		      gen_rtx_REG (word_mode, reg));
+      rtx delta = GEN_INT (disp);
+      rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta));
+      rtx tmpreg = gen_rtx_REG (Pmode, 1);
+      emit_move_insn (tmpreg, high);
+      dest = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
+      i = emit_move_insn (dest, src);
+    }
+  if (DO_FRAME_NOTES)
+    {
+      RTX_FRAME_RELATED_P (i) = 1;
+      if (base != STACK_POINTER_REGNUM)
+	{
+	  rtx addr = plus_constant (stack_pointer_rtx, disp - actual_fsize);
+	  dest = gen_rtx_MEM (word_mode, addr);
+	  REG_NOTES (i)
+	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+				 gen_rtx_SET (VOIDmode, dest, src),
+				 REG_NOTES (i));
+	}
     }
 }
 
@@ -2805,31 +2834,30 @@ load_reg (reg, disp, base)
    Note in DISP > 8k case, we will leave the high part of the address
    in %r1.  There is code in expand_hppa_{prologue,epilogue} that knows this.*/
 
-static void
+static rtx
 set_reg_plus_d (reg, base, disp)
      int reg, base, disp;
 {
+  rtx i;
+
   if (VAL_14_BITS_P (disp))
-    emit_move_insn (gen_rtx_REG (Pmode, reg),
-		    plus_constant (gen_rtx_REG (Pmode, base), disp));
+    {
+      i = emit_move_insn (gen_rtx_REG (Pmode, reg),
+			  plus_constant (gen_rtx_REG (Pmode, base), disp));
+    }
   else
     {
+      rtx delta = GEN_INT (disp);
       emit_move_insn (gen_rtx_REG (Pmode, 1),
 		      gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
-				    gen_rtx_HIGH (Pmode, GEN_INT (disp))));
-      emit_move_insn (gen_rtx_REG (Pmode, reg),
-		      gen_rtx_LO_SUM (Pmode,
-				      gen_rtx_REG (Pmode, 1),
-				       GEN_INT (disp)));
+				    gen_rtx_HIGH (Pmode, delta)));
+      i = emit_move_insn (gen_rtx_REG (Pmode, reg),
+			  gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 1),
+					  delta));
     }
+  return i;
 }
 
-/* Global variables set by FUNCTION_PROLOGUE.  */
-/* Size of frame.  Need to know this to emit return insns from
-   leaf procedures.  */
-static int actual_fsize;
-static int local_fsize, save_fregs;
-
 int
 compute_frame_size (size, fregs_live)
      int size;
@@ -2945,6 +2973,7 @@ hppa_expand_prologue()
   int merge_sp_adjust_with_store = 0;
   int i, offset;
   rtx tmpreg, size_rtx;
+  rtx insn;
 
   gr_saved = 0;
   fr_saved = 0;
@@ -2982,9 +3011,31 @@ hppa_expand_prologue()
 	     handles small (<8k) frames.  The second handles large (>=8k)
 	     frames.  */
 	  emit_move_insn (tmpreg, frame_pointer_rtx);
-	  emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+	  insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
 	  if (VAL_14_BITS_P (actual_fsize))
-	    emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, size_rtx));
+	    {
+	      insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg,
+						size_rtx));
+	      if (DO_FRAME_NOTES)
+		{
+		  rtvec vec;
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  vec = gen_rtvec (2,
+				   gen_rtx_SET (VOIDmode,
+						gen_rtx_MEM (word_mode,
+							     stack_pointer_rtx),
+						frame_pointer_rtx),
+				   gen_rtx_SET (VOIDmode,
+						stack_pointer_rtx,
+						gen_rtx_PLUS (word_mode,
+							      stack_pointer_rtx,
+							      size_rtx)));
+		  REG_NOTES (insn)
+		    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					 gen_rtx_SEQUENCE (VOIDmode, vec),
+					 REG_NOTES (insn));
+		}
+	    }
 	  else
 	    {
 	      /* It is incorrect to store the saved frame pointer at *sp,
@@ -2996,10 +3047,46 @@ hppa_expand_prologue()
 	      int adjust1 = 8192 - 64;
 	      int adjust2 = actual_fsize - adjust1;
 	      rtx delta = GEN_INT (adjust1);
-	      emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, delta));
-	      set_reg_plus_d (STACK_POINTER_REGNUM,
-			      STACK_POINTER_REGNUM,
-			      adjust2);
+	      insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg,
+						delta));
+	      if (DO_FRAME_NOTES)
+		{
+		  rtvec vec;
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  vec = gen_rtvec (2,
+				   gen_rtx_SET (VOIDmode,
+						gen_rtx_MEM (word_mode,
+							     stack_pointer_rtx),
+						frame_pointer_rtx),
+				   gen_rtx_SET (VOIDmode,
+						stack_pointer_rtx,
+						gen_rtx_PLUS (word_mode,
+							      stack_pointer_rtx,
+							      delta)));
+		  REG_NOTES (insn)
+		    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					 gen_rtx_SEQUENCE (VOIDmode, vec),
+					 REG_NOTES (insn));
+		}
+
+	      insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+				     STACK_POINTER_REGNUM,
+				     adjust2);
+	      if (DO_FRAME_NOTES)
+		{
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  if (! VAL_14_BITS_P (adjust2))
+		    {
+		      rtx addr = plus_constant (stack_pointer_rtx, adjust2);
+
+		      REG_NOTES (insn)
+			= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					     gen_rtx_SET (VOIDmode,
+							  stack_pointer_rtx,
+							  addr),
+					     REG_NOTES (insn));
+		    }
+		}
 	    }
 	  /* Prevent register spills from being scheduled before the
 	     stack pointer is raised.  Necessary as we will be storing
@@ -3019,9 +3106,26 @@ hppa_expand_prologue()
 	  /* Can not optimize.  Adjust the stack frame by actual_fsize
 	     bytes.  */
 	  else
-	    set_reg_plus_d (STACK_POINTER_REGNUM,
-			    STACK_POINTER_REGNUM,
-			    actual_fsize);
+	    {
+	      insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+				     STACK_POINTER_REGNUM,
+				     actual_fsize);
+	      if (DO_FRAME_NOTES)
+		{
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  if (! VAL_14_BITS_P (actual_fsize))
+		    {
+		      rtx addr;
+		      addr = plus_constant (stack_pointer_rtx, actual_fsize);
+		      REG_NOTES (insn)
+			= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					     gen_rtx_SET (VOIDmode,
+							  stack_pointer_rtx,
+							  addr),
+					     REG_NOTES (insn));
+		    }
+		}
+	    }
 	}
     }
 
@@ -3051,10 +3155,25 @@ hppa_expand_prologue()
 	       optimize the first GR save.  */
 	    if (merge_sp_adjust_with_store)
 	      {
+		rtx delta = GEN_INT (-offset);
 		merge_sp_adjust_with_store = 0;
-	        emit_insn (gen_post_store (stack_pointer_rtx,
-					   gen_rtx_REG (word_mode, i),
-					   GEN_INT (-offset)));
+	        insn = emit_insn (gen_post_store (stack_pointer_rtx,
+						  gen_rtx_REG (word_mode, i),
+						  delta));
+		if (DO_FRAME_NOTES)
+		  {
+		    rtx set;
+		    RTX_FRAME_RELATED_P (insn) = 1;
+		    set = gen_rtx_SET (VOIDmode,
+				       stack_pointer_rtx,
+				       gen_rtx_PLUS (word_mode,
+						     stack_pointer_rtx,
+						     delta));
+		    REG_NOTES (insn)
+		      = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					   set,
+					   REG_NOTES (insn));
+		  }
 	      }
 	    else
 	      store_reg (i, offset, STACK_POINTER_REGNUM);
@@ -3065,9 +3184,13 @@ hppa_expand_prologue()
       /* If we wanted to merge the SP adjustment with a GR save, but we never
 	 did any GR saves, then just emit the adjustment here.  */
       if (merge_sp_adjust_with_store)
-	set_reg_plus_d (STACK_POINTER_REGNUM,
-			STACK_POINTER_REGNUM,
-			actual_fsize);
+	{
+	  insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+				 STACK_POINTER_REGNUM,
+				 actual_fsize);
+	  if (DO_FRAME_NOTES)
+	    RTX_FRAME_RELATED_P (insn) = 1;
+	}
     }
 
   /* The hppa calling conventions say that %r19, the pic offset
@@ -3098,9 +3221,26 @@ hppa_expand_prologue()
 	  if (regs_ever_live[i]
 	      || (! TARGET_64BIT && regs_ever_live[i + 1]))
 	    {
-	      emit_move_insn (gen_rtx_MEM (DFmode,
-				           gen_rtx_POST_INC (DFmode, tmpreg)),
-			      gen_rtx_REG (DFmode, i));
+	      rtx addr, reg;
+	      addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
+	      reg = gen_rtx_REG (DFmode, i);
+	      insn = emit_move_insn (addr, reg);
+	      if (DO_FRAME_NOTES)
+		{
+		  rtx stackoff;
+		  RTX_FRAME_RELATED_P (insn) = 1;
+		  stackoff = GEN_INT (offset + (frame_pointer_needed
+						? -actual_fsize : 0));
+		  addr = gen_rtx_MEM (DFmode,
+				      gen_rtx_PLUS (DFmode,
+						    stack_pointer_rtx,
+						    stackoff));
+		  REG_NOTES (insn)
+		    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+					 gen_rtx_SET (VOIDmode, addr, reg),
+					 REG_NOTES (insn));
+		  offset += 8;
+		}
 	      fr_saved++;
 	    }
 	}
@@ -3147,6 +3287,7 @@ hppa_expand_epilogue ()
   int offset, i;
   int merge_sp_adjust_with_load = 0;
   int ret_off = 0;
+  rtx insn;
 
   /* We will use this often.  */
   tmpreg = gen_rtx_REG (word_mode, 1);
@@ -3239,25 +3380,83 @@ hppa_expand_epilogue ()
      pointer is initially set to fp + 64 to avoid a race condition.  */
   if (frame_pointer_needed)
     {
-      set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
-      emit_insn (gen_pre_load (frame_pointer_rtx, 
-			       stack_pointer_rtx,
-			       GEN_INT (-64)));
+      rtx delta = GEN_INT (-64);
+      insn = set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
+      if (DO_FRAME_NOTES)
+	{
+	  RTX_FRAME_RELATED_P (insn) = 1;
+	  REG_NOTES (insn)
+	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+				 gen_rtx_SET (VOIDmode,
+					      stack_pointer_rtx,
+					      plus_constant (stack_pointer_rtx,
+							     64 - actual_fsize)),
+				 REG_NOTES (insn));
+	}
+      insn = emit_insn (gen_pre_load (frame_pointer_rtx, 
+				      stack_pointer_rtx,
+				      delta));
+      if (DO_FRAME_NOTES)
+	{
+	  rtvec vec;
+	  RTX_FRAME_RELATED_P (insn) = 1;
+	  vec = gen_rtvec (2,
+			   gen_rtx_SET (VOIDmode,
+					stack_pointer_rtx,
+					gen_rtx_PLUS (word_mode,
+						      stack_pointer_rtx,
+						      delta)),
+			   gen_rtx_SET (VOIDmode,
+					frame_pointer_rtx,
+					gen_rtx_MEM (word_mode,
+						     stack_pointer_rtx)));
+	  REG_NOTES (insn)
+	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+				 gen_rtx_SEQUENCE (VOIDmode, vec),
+				 REG_NOTES (insn));
+	}
     }
   /* If we were deferring a callee register restore, do it now.  */
   else if (merge_sp_adjust_with_load)
     {
       rtx delta = GEN_INT (-actual_fsize);
-      emit_insn (gen_pre_load (gen_rtx_REG (word_mode,
-					    merge_sp_adjust_with_load),
-			       stack_pointer_rtx,
-			       delta));
+      insn = emit_insn (gen_pre_load (gen_rtx_REG (word_mode,
+						   merge_sp_adjust_with_load),
+				      stack_pointer_rtx,
+				      delta));
+      if (DO_FRAME_NOTES)
+	{
+	  RTX_FRAME_RELATED_P (insn) = 1;
+	  REG_NOTES (insn)
+	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+				 gen_rtx_SET (VOIDmode,
+					      stack_pointer_rtx,
+					      gen_rtx_PLUS (word_mode,
+							    stack_pointer_rtx,
+							    delta)),
+				 REG_NOTES (insn));
+	}
     }
   else if (actual_fsize != 0)
     {
-      set_reg_plus_d (STACK_POINTER_REGNUM,
-		      STACK_POINTER_REGNUM,
-		      - actual_fsize);
+      insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+			     STACK_POINTER_REGNUM,
+			     - actual_fsize);
+      if (DO_FRAME_NOTES)
+	{
+	  RTX_FRAME_RELATED_P (insn) = 1;
+	  if (! VAL_14_BITS_P (- actual_fsize))
+	    {
+	      rtx addr = plus_constant (stack_pointer_rtx, - actual_fsize);
+
+	      REG_NOTES (insn)
+		= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+				     gen_rtx_SET (VOIDmode,
+						  stack_pointer_rtx,
+						  addr),
+				     REG_NOTES (insn));
+	    }
+	}
     }
 
   /* If we haven't restored %r2 yet (no frame pointer, and a stack


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]