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]

[PATCH]: Fix space register usage under hppa-unknown-linux-gnu


The hppa-unknown-linux-gnu port uses a flat address model (i.e., the same
space register values are used in space registers 4-7).  We have been
incorrectly treating the port the same as hpux which doesn't have a flat
address model.

This patch sets MASK_NO_SPACE_REGS in the target default causing
TARGET_NO_SPACE_REGS to be true.  The code generation has also been
improved for a number of situations where we do external branches
and don't need to load the new space register for the branch
destination.  This is fixing new code introduced for EH support
and during the call rewrite for 3.3.

Installed to 3.3 and trunk.  Tested on hppa-unknown-linux-gnu,
hppa64-hp-hpux11.11 and hppa2.0-hp-hpux11.11, 3.3 and main.
I also did some additional tests on hppa-linux using "-mlong-calls"
and "-mlong-calls -fPIC" to completely test the new code.

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

2003-02-06  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* config.gcc (hppa*-*-linux*): Set MASK_NO_SPACE_REGS in
	target_cpu_default.
	* pa.c (attr_length_call): Add 8 to call length (long indirect PA 1.X)
	if not MASK_NO_SPACE_REGS.
	(output_call): Adjust return pointer, don't load new space register
	into %sr0, and use %sr4 for call if TARGET_NO_SPACE_REGS is true.
	(pa_asm_output_mi_thunk): Don't load new space register into %sr0 if
	TARGET_NO_SPACE_REGS is true.
	* pa.md (return_external_pic): Add TARGET_NO_SPACE_REGS to insn
	conditions.
	(epilogue): Always use return_internal if TARGET_NO_SPACE_REGS is true.
	(interspace_jump): Add new pattern for when TARGET_NO_SPACE_REGS is
	true.  Use bve when TARGET_64BIT is true.

Index: config.gcc
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.280
diff -u -3 -p -r1.280 config.gcc
--- config.gcc	30 Jan 2003 14:22:50 -0000	1.280
+++ config.gcc	4 Feb 2003 16:07:07 -0000
@@ -780,7 +780,7 @@ hppa*64*-*-linux* | parisc*64*-*-linux*)
 	need_64bit_hwint=yes
 	;;
 hppa*-*-linux* | parisc*-*-linux*)
-	target_cpu_default="MASK_PA_11"
+	target_cpu_default="MASK_PA_11 | MASK_NO_SPACE_REGS"
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
 		 pa/pa32-regs.h pa/pa32-linux.h"
 	tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
Index: config/pa/pa.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.197
diff -u -3 -p -r1.197 pa.c
--- config/pa/pa.c	2 Feb 2003 06:04:58 -0000	1.197
+++ config/pa/pa.c	4 Feb 2003 16:07:07 -0000
@@ -6532,10 +6532,13 @@ attr_length_call (insn, sibcall)
 	  if (TARGET_PA_20)
 	    return (length + 32);
 
+	  if (!TARGET_NO_SPACE_REGS)
+	    length += 8;
+
 	  if (!sibcall)
 	    length += 8;
 
-	  return (length + 40);
+	  return (length + 32);
 	}
     }
 }
@@ -6730,7 +6733,10 @@ output_call (insn, call_dest, sibcall)
 		  if (!sibcall && !TARGET_PA_20)
 		    {
 		      output_asm_insn ("{bl|b,l} .+8,%%r2", xoperands);
-		      output_asm_insn ("addi 16,%%r2,%%r2", xoperands);
+		      if (TARGET_NO_SPACE_REGS)
+			output_asm_insn ("addi 8,%%r2,%%r2", xoperands);
+		      else
+			output_asm_insn ("addi 16,%%r2,%%r2", xoperands);
 		    }
 		}
 
@@ -6752,14 +6758,23 @@ output_call (insn, call_dest, sibcall)
 		}
 	      else
 		{
-	          output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
-				   xoperands);
+		  if (!TARGET_NO_SPACE_REGS)
+		    output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
+				     xoperands);
 
 		  if (sibcall)
-		    output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
+		    {
+		      if (TARGET_NO_SPACE_REGS)
+			output_asm_insn ("be 0(%%sr4,%%r1)", xoperands);
+		      else
+			output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
+		    }
 		  else
 		    {
-		      output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);
+		      if (TARGET_NO_SPACE_REGS)
+			output_asm_insn ("ble 0(%%sr4,%%r1)", xoperands);
+		      else
+			output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);
 
 		      if (indirect_call)
 			output_asm_insn ("stw %%r31,-24(%%sp)", xoperands);
@@ -7026,7 +7041,7 @@ pa_asm_output_mi_thunk (file, thunk_fnde
   pa_output_function_prologue (file, 0);
   if (VAL_14_BITS_P (delta))
     {
-      if (! TARGET_64BIT && ! TARGET_PORTABLE_RUNTIME && flag_pic)
+      if (!TARGET_64BIT && !TARGET_PORTABLE_RUNTIME && flag_pic)
 	{
 	  fprintf (file, "\taddil LT'%s,%%r19\n", lab);
 	  fprintf (file, "\tldw RT'%s(%%r1),%%r22\n", lab);
@@ -7035,8 +7050,14 @@ pa_asm_output_mi_thunk (file, thunk_fnde
 	  fprintf (file, "\tdepi 0,31,2,%%r22\n");
 	  fprintf (file, "\tldw 4(%%sr0,%%r22),%%r19\n");
 	  fprintf (file, "\tldw 0(%%sr0,%%r22),%%r22\n");
-	  fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n\tmtsp %%r1,%%sr0\n");
-	  fprintf (file, "\tbe 0(%%sr0,%%r22)\n\tldo ");
+	  if (TARGET_NO_SPACE_REGS)
+	    fprintf (file, "\tbe 0(%%sr4,%%r22)\n\tldo ");
+	  else
+	    {
+	      fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n");
+	      fprintf (file, "\tmtsp %%r1,%%sr0\n");
+	      fprintf (file, "\tbe 0(%%sr0,%%r22)\n\tldo ");
+	    }
 	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
 	  fprintf (file, "(%%r26),%%r26\n");
 	}
@@ -7049,7 +7070,7 @@ pa_asm_output_mi_thunk (file, thunk_fnde
     }
   else
     {
-      if (! TARGET_64BIT && ! TARGET_PORTABLE_RUNTIME && flag_pic)
+      if (!TARGET_64BIT && !TARGET_PORTABLE_RUNTIME && flag_pic)
 	{
 	  fprintf (file, "\taddil L'");
 	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
@@ -7063,8 +7084,14 @@ pa_asm_output_mi_thunk (file, thunk_fnde
 	  fprintf (file, "\tdepi 0,31,2,%%r22\n");
 	  fprintf (file, "\tldw 4(%%sr0,%%r22),%%r19\n");
 	  fprintf (file, "\tldw 0(%%sr0,%%r22),%%r22\n");
-	  fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n\tmtsp %%r1,%%sr0\n");
-	  fprintf (file, "\tbe,n 0(%%sr0,%%r22)\n");
+	  if (TARGET_NO_SPACE_REGS)
+	    fprintf (file, "\tbe 0(%%sr4,%%r22)");
+	  else
+	    {
+	      fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n");
+	      fprintf (file, "\tmtsp %%r1,%%sr0\n");
+	      fprintf (file, "\tbe,n 0(%%sr0,%%r22)\n");
+	    }
 	}
       else
 	{
Index: config/pa/pa.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.119
diff -u -3 -p -r1.119 pa.md
--- config/pa/pa.md	2 Feb 2003 06:04:58 -0000	1.119
+++ config/pa/pa.md	4 Feb 2003 16:07:08 -0000
@@ -5629,7 +5629,7 @@
   [(return)
    (clobber (reg:SI 1))
    (use (reg:SI 2))]
-  "flag_pic && current_function_calls_eh_return"
+  "!TARGET_NO_SPACE_REGS && flag_pic && current_function_calls_eh_return"
   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
   [(set_attr "type" "branch")
    (set_attr "length" "12")])
@@ -5665,8 +5665,10 @@
 
       /* EH returns bypass the normal return stub.  Thus, we must do an
 	 interspace branch to return from functions that call eh_return.
-	 This is only a problem for returns from shared code.  */
-      if (flag_pic && current_function_calls_eh_return)
+	 This is only a problem for returns from shared code on ports
+	 using space registers.  */
+      if (!TARGET_NO_SPACE_REGS
+	  && flag_pic && current_function_calls_eh_return)
 	x = gen_return_external_pic ();
       else
 	x = gen_return_internal ();
@@ -6997,7 +6999,8 @@
 
 ;;; EH does longjmp's from and within the data section.  Thus,
 ;;; an interspace branch is required for the longjmp implementation.
-;;; Registers r1 and r2 are used as scratch registers for the jump.
+;;; Registers r1 and r2 are used as scratch registers for the jump
+;;; when necessary.
 (define_expand "interspace_jump"
   [(parallel
      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
@@ -7011,6 +7014,22 @@
 (define_insn ""
   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
   (clobber (reg:SI 2))]
+  "TARGET_PA_20 && !TARGET_64BIT"
+  "bve%* (%0)"
+   [(set_attr "type" "branch")
+    (set_attr "length" "4")])
+
+(define_insn ""
+  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
+  (clobber (reg:SI 2))]
+  "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
+  "be%* 0(%%sr4,%0)"
+   [(set_attr "type" "branch")
+    (set_attr "length" "4")])
+
+(define_insn ""
+  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
+  (clobber (reg:SI 2))]
   "!TARGET_64BIT"
   "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
    [(set_attr "type" "branch")
@@ -7020,9 +7039,9 @@
   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
   (clobber (reg:DI 2))]
   "TARGET_64BIT"
-  "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
+  "bve%* (%0)"
    [(set_attr "type" "branch")
-    (set_attr "length" "12")])
+    (set_attr "length" "4")])
 
 (define_expand "builtin_longjmp"
   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]


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