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]
Other format: [Raw text]

Fix for frame note handling under hppa-linux


This patch fixes a number of problems with the frame note code used only
under hppa-linux.  It is needed to bootstrap with the current main branch.

The first problem fixed is a temporary register was used for the floating
spills.  The insn setting the temporary register previously had a frame
note.  This insn would get scheduled before some of the general register
saves and this confused dwarf2out.  I solved this by not adding a note
to the temporary register copy and appending an expression list to each
floating point spill indicating what was being saved and where.

A different but related problem occured with large frames.  Here I found
that dwarf2out couldn't track the HIGH/LO_SUM insns needed for large frames.
So, again an expression list was needed to handle the situation.  This
required a rewrite to store_reg.

Finally, the stuff in hppa_expand_epilogue although disabled clearly
didn't work.  I removed notes from register restores.  The only remaining
note is the final stack adjust.

Tested under hppa-linux and hppa2.0w-hp-hpux11.11.  No regressions were
noted under hppa2.0w-hp-hpux11.11.  There is no previous benchmark for
hppa-linux test results as it didn't bootstrap before.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2002-02-04  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa.c (DO_FRAME_NOTES): Move forward.
	(store_reg): Revise handling of frame notes.
	(load_reg): Likewise.
	(set_reg_plus_d): Likewise.
	(hppa_expand_prologue): Likewise.
	(hppa_expand_epilogue): Likewise.
	
--- pa.c.orig	Tue Jan 22 01:23:17 2002
+++ pa.c	Sat Jan 26 02:52:49 2002
@@ -55,6 +55,18 @@
 #endif
 #endif
 
+#if DO_FRAME_NOTES
+#define FRP(INSN) \
+  do					\
+    {					\
+      rtx insn = INSN;			\
+      RTX_FRAME_RELATED_P (insn) = 1;	\
+    }					\
+  while (0)
+#else
+#define FRP(INSN) INSN
+#endif
+
 #ifndef FUNC_BEGIN_PROLOG_LABEL
 #define FUNC_BEGIN_PROLOG_LABEL        "LFBP"
 #endif
@@ -70,9 +82,9 @@
 static int compute_movstrsi_length PARAMS ((rtx));
 static bool pa_assemble_integer PARAMS ((rtx, unsigned int, int));
 static void remove_useless_addtr_insns PARAMS ((rtx, int));
-static rtx store_reg PARAMS ((int, int, int));
-static rtx load_reg PARAMS ((int, int, int));
-static rtx set_reg_plus_d PARAMS ((int, int, 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 void pa_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
 static int pa_adjust_priority PARAMS ((rtx, int));
@@ -2879,18 +2891,18 @@
    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 rtx
+static void
 store_reg (reg, disp, base)
      int reg, disp, base;
 {
-  rtx i, dest, src, basereg;
+  rtx insn, dest, src, basereg;
 
   src = gen_rtx_REG (word_mode, reg);
   basereg = gen_rtx_REG (Pmode, base);
   if (VAL_14_BITS_P (disp))
     {
       dest = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
-      i = emit_move_insn (dest, src);
+      insn = emit_move_insn (dest, src);
     }
   else
     {
@@ -2899,9 +2911,22 @@
       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);
+      insn = emit_move_insn (dest, src);
+      if (DO_FRAME_NOTES)
+	{
+	  REG_NOTES (insn)
+	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+		gen_rtx_SET (VOIDmode,
+			     gen_rtx_MEM (word_mode,
+					  gen_rtx_PLUS (word_mode, basereg,
+							delta)),
+                             src),
+                REG_NOTES (insn));
+	}
     }
-  return i;
+
+  if (DO_FRAME_NOTES)
+    RTX_FRAME_RELATED_P (insn) = 1;
 }
 
 /* Emit RTL to set REG to the value specified by BASE+DISP.
@@ -2910,28 +2935,32 @@
    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 rtx
+static void
 set_reg_plus_d (reg, base, disp)
      int reg, base, disp;
 {
-  rtx i;
+  rtx insn;
 
   if (VAL_14_BITS_P (disp))
     {
-      i = emit_move_insn (gen_rtx_REG (Pmode, reg),
-			  plus_constant (gen_rtx_REG (Pmode, base), disp));
+      insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
+			     plus_constant (gen_rtx_REG (Pmode, base), disp));
     }
   else
     {
+      rtx basereg = gen_rtx_REG (Pmode, base);
       rtx delta = GEN_INT (disp);
+
       emit_move_insn (gen_rtx_REG (Pmode, 1),
-		      gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
+		      gen_rtx_PLUS (Pmode, basereg,
 				    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));
+      insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
+			     gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 1),
+					     delta));
     }
-  return i;
+
+  if (DO_FRAME_NOTES && reg == STACK_POINTER_REGNUM)
+    RTX_FRAME_RELATED_P (insn) = 1;
 }
 
 int
@@ -3069,18 +3098,6 @@
   remove_useless_addtr_insns (get_insns (), 0);
 }
 
-#if DO_FRAME_NOTES
-#define FRP(INSN) \
-  do					\
-    {					\
-      rtx insn = INSN;			\
-      RTX_FRAME_RELATED_P (insn) = 1;	\
-    }					\
-  while (0)
-#else
-#define FRP(INSN) INSN
-#endif
-
 void
 hppa_expand_prologue ()
 {
@@ -3111,7 +3128,7 @@
      always be stored into the caller's frame at sp - 20 or sp - 16
      depending on which ABI is in use.  */
   if (regs_ever_live[2])
-    FRP (store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM));
+    store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
 
   /* Allocate the local frame and set up the frame pointer if needed.  */
   if (actual_fsize != 0)
@@ -3183,9 +3200,8 @@
 					 REG_NOTES (insn));
 		}
 
-	      FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
-				   STACK_POINTER_REGNUM,
-				   adjust2));
+	      set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
+			      adjust2);
 	    }
 	  /* Prevent register spills from being scheduled before the
 	     stack pointer is raised.  Necessary as we will be storing
@@ -3205,9 +3221,8 @@
 	  /* Can not optimize.  Adjust the stack frame by actual_fsize
 	     bytes.  */
 	  else
-	    FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
-				 STACK_POINTER_REGNUM,
-				 actual_fsize));
+	    set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
+			    actual_fsize);
 	}
     }
 
@@ -3220,7 +3235,7 @@
       for (i = 18, offset = local_fsize; i >= 4; i--)
 	if (regs_ever_live[i] && ! call_used_regs[i])
 	  {
-	    FRP (store_reg (i, offset, FRAME_POINTER_REGNUM));
+	    store_reg (i, offset, FRAME_POINTER_REGNUM);
 	    offset += UNITS_PER_WORD;
 	    gr_saved++;
 	  }
@@ -3244,7 +3259,7 @@
 						delta)));
 	      }
 	    else
-	      FRP (store_reg (i, offset, STACK_POINTER_REGNUM));
+	      store_reg (i, offset, STACK_POINTER_REGNUM);
 	    offset += UNITS_PER_WORD;
 	    gr_saved++;
 	  }
@@ -3252,9 +3267,8 @@
       /* 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)
-	FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
-			     STACK_POINTER_REGNUM,
-			     actual_fsize));
+	set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
+			actual_fsize);
     }
 
   /* The hppa calling conventions say that %r19, the pic offset
@@ -3275,9 +3289,9 @@
       /* First get the frame or stack pointer to the start of the FP register
 	 save area.  */
       if (frame_pointer_needed)
-	FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset));
+	set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
       else
-	FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset));
+	set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
 
       /* Now actually save the FP registers.  */
       for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
@@ -3285,37 +3299,44 @@
 	  if (regs_ever_live[i]
 	      || (! TARGET_64BIT && regs_ever_live[i + 1]))
 	    {
-	      rtx addr, reg;
+	      rtx addr, insn, reg;
 	      addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
 	      reg = gen_rtx_REG (DFmode, i);
-	      FRP (emit_move_insn (addr, reg));
+	      insn = emit_move_insn (addr, reg);
+	      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,
+			  gen_rtx_MEM (DFmode,
+				       plus_constant (stack_pointer_rtx,
+						      offset)),
+			  reg),
+			REG_NOTES (insn));
+		}
+	      offset += GET_MODE_SIZE (DFmode);
 	      fr_saved++;
 	    }
 	}
     }
 }
 
-/* ?!? Do we want frame notes in the epilogue yet?  */
-#undef DO_FRAME_NOTES
-#define DO_FRAME_NOTES 0
-#undef FRP
-#define FRP(INSN) INSN
-
 /* Emit RTL to load REG from the memory location specified by BASE+DISP.
    Handle case where DISP > 8k by using the add_high_const patterns.  */
 
-static rtx
+static void
 load_reg (reg, disp, base)
      int reg, disp, base;
 {
-  rtx i, src, dest, basereg;
+  rtx src, dest, basereg;
 
   dest = gen_rtx_REG (word_mode, reg);
   basereg = gen_rtx_REG (Pmode, base);
   if (VAL_14_BITS_P (disp))
     {
       src = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
-      i = emit_move_insn (dest, src);
+      emit_move_insn (dest, src);
     }
   else
     {
@@ -3324,9 +3345,8 @@
       rtx tmpreg = gen_rtx_REG (Pmode, 1);
       emit_move_insn (tmpreg, high);
       src = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
-      i = emit_move_insn (dest, src);
+      emit_move_insn (dest, src);
     }
-  return i;
 }
 
 /* This function generates the assembly code for function exit.
@@ -3388,7 +3408,7 @@
       ret_off = TARGET_64BIT ? -16 : -20;
       if (frame_pointer_needed)
 	{
-	  FRP (load_reg (2, ret_off, FRAME_POINTER_REGNUM));
+	  load_reg (2, ret_off, FRAME_POINTER_REGNUM);
 	  ret_off = 0;
 	}
       else
@@ -3396,7 +3416,7 @@
 	  /* No frame pointer, and stack is smaller than 8k.  */
 	  if (VAL_14_BITS_P (ret_off - actual_fsize))
 	    {
-	      FRP (load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM));
+	      load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM);
 	      ret_off = 0;
 	    }
 	}
@@ -3408,7 +3428,7 @@
       for (i = 18, offset = local_fsize; i >= 4; i--)
 	if (regs_ever_live[i] && ! call_used_regs[i])
 	  {
-	    FRP (load_reg (i, offset, FRAME_POINTER_REGNUM));
+	    load_reg (i, offset, FRAME_POINTER_REGNUM);
 	    offset += UNITS_PER_WORD;
 	  }
     }
@@ -3426,7 +3446,7 @@
 		  && VAL_14_BITS_P (-actual_fsize))
 	        merge_sp_adjust_with_load = i;
 	      else
-		FRP (load_reg (i, offset, STACK_POINTER_REGNUM));
+		load_reg (i, offset, STACK_POINTER_REGNUM);
 	      offset += UNITS_PER_WORD;
 	    }
 	}
@@ -3440,9 +3460,9 @@
     {
       /* Adjust the register to index off of.  */
       if (frame_pointer_needed)
-	FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset));
+	set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
       else
-	FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset));
+	set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
 
       /* Actually do the restores now.  */
       for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
@@ -3451,7 +3471,7 @@
 	  {
 	    rtx src = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
 	    rtx dest = gen_rtx_REG (DFmode, i);
-	    FRP (emit_move_insn (dest, src));
+	    emit_move_insn (dest, src);
 	  }
     }
 
@@ -3467,27 +3487,45 @@
   if (frame_pointer_needed)
     {
       rtx delta = GEN_INT (-64);
-      FRP (set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64));
-      FRP (emit_insn (gen_pre_load (frame_pointer_rtx,
-				    stack_pointer_rtx,
-				    delta)));
+      rtx insn;
+      set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
+      insn = emit_insn (gen_pre_load (frame_pointer_rtx, 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));
+	}
     }
   /* If we were deferring a callee register restore, do it now.  */
   else if (merge_sp_adjust_with_load)
     {
       rtx delta = GEN_INT (-actual_fsize);
       rtx dest = gen_rtx_REG (word_mode, merge_sp_adjust_with_load);
-      FRP (emit_insn (gen_pre_load (dest, stack_pointer_rtx, delta)));
+      rtx insn = emit_insn (gen_pre_load (dest, 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)
-    FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
-			 STACK_POINTER_REGNUM,
-			 - actual_fsize));
+    set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM, - actual_fsize);
 
   /* If we haven't restored %r2 yet (no frame pointer, and a stack
      frame greater than 8k), do so now.  */
   if (ret_off != 0)
-    FRP (load_reg (2, ret_off, STACK_POINTER_REGNUM));
+    load_reg (2, ret_off, STACK_POINTER_REGNUM);
 }
 
 rtx


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