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]

pa TARGET_NO_SPACE_REGS


Hi Jeff,
  This is the result of digging around to see if I could make
TARGET_NO_SPACE_REGS a useful option on hppa-linux.  There seems to
be quite some overlap, confusion even, in what TARGET_NO_SPACE_REGS
and TARGET_FAST_INDIRECT_CALLS do.  What I've done is remove the
effect on call sequences that TARGET_NO_SPACE_REGS used to have.  This
allows TARGET_NO_SPACE_REGS to be used with -fPIC and shared libraries
under hppa-linux, giving less restrictive index reg constraints and
faster builtin_return.

Additionally, I've simplified the logic in output_millicode_call so that
-fPIC takes precedence, then TARGET_PORTABLE_RUNTIME, then the ble
type call when the destination is out of range.

	* config/pa/pa.h: Revise comments for TARGET_NO_SPACE_REGS and
	TARGET_FAST_INDIRECT_CALLS.
	* config/pa/pa.c (override_options): TARGET_NO_SPACE_REGS is
	now OK with -fPIC.  Don't warn.
	(return_addr_rtx): Short circuit export stub matching when
	TARGET_NO_SPACE_REGS.
	(output_millicode_call): For out of range calls, make -fPIC
	take precedence, then TARGET_PORTABLE_RUNTIME, then ble.  Don't
	return before delay slot checks when TARGET_PORTABLE_RUNTIME.
	* config/pa/pa.md: Modify length attr calculation of all
	millicode insns to match above.

Alan Modra
-- 
Linuxcare

Offsets and fuzz likely in this patch...

diff -urpN -xCVS -x*~ gcc-current/gcc/config/pa/pa.h parisc/gcc/gcc/config/pa/pa.h
--- gcc-current/gcc/config/pa/pa.h	Sat Mar 24 19:57:08 2001
+++ parisc/gcc/gcc/config/pa/pa.h	Fri Mar 30 14:07:54 2001
@@ -106,13 +106,9 @@ extern int target_flags;
 #define MASK_DISABLE_FPREGS 2
 #define TARGET_DISABLE_FPREGS (target_flags & MASK_DISABLE_FPREGS)
 
-/* Generate code which assumes that calls through function pointers will
-   never cross a space boundary.  Such assumptions are generally safe for
-   building kernels and statically linked executables.  Code compiled with
-   this option will fail miserably if the executable is dynamically linked
-   or uses nested functions!
-
-   This is also used to trigger aggressive unscaled index addressing.  */
+/* Generate code which assumes that all space register are equivalent.
+   Triggers aggressive unscaled index addressing and faster
+   builtin_return_address.  */
 #define MASK_NO_SPACE_REGS 4
 #define TARGET_NO_SPACE_REGS (target_flags & MASK_NO_SPACE_REGS)
 
@@ -148,7 +144,12 @@ extern int target_flags;
 #define MASK_LONG_LOAD_STORE 512
 #define TARGET_LONG_LOAD_STORE (target_flags & MASK_LONG_LOAD_STORE)
 
-/* Use a faster sequence for indirect calls.  */
+/* Use a faster sequence for indirect calls.  This assumes that calls
+   through function pointers will never cross a space boundary, and
+   that the executable is not dynamically linked.  Such assumptions
+   are generally safe for building kernels and statically linked
+   executables.  Code compiled with this option will fail miserably if
+   the executable is dynamically linked or uses nested functions!  */
 #define MASK_FAST_INDIRECT_CALLS 1024
 #define TARGET_FAST_INDIRECT_CALLS (target_flags & MASK_FAST_INDIRECT_CALLS)
 
diff -urpN -xCVS -x*~ gcc-current/gcc/config/pa/pa.c parisc/gcc/gcc/config/pa/pa.c
--- gcc-current/gcc/config/pa/pa.c	Fri Mar 30 18:07:49 2001
+++ parisc/gcc/gcc/config/pa/pa.c	Fri Mar 30 14:07:54 2001
@@ -170,7 +172,7 @@ override_options ()
       warning ("PIC code generation is not supported in the portable runtime model\n");
     }
 
-  if (flag_pic && (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS))
+  if (flag_pic && TARGET_FAST_INDIRECT_CALLS)
    {
       warning ("PIC code generation is not compatible with fast indirect calls\n");
    }
@@ -3602,15 +3627,17 @@ return_addr_rtx (count, frameaddr)
   rtx saved_rp;
   rtx ins;
 
-  saved_rp = gen_reg_rtx (Pmode);
+  if (TARGET_64BIT)
+    return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -16));
+
+  if (TARGET_NO_SPACE_REGS)
+    return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -20));
 
   /* First, we start off with the normal return address pointer from
      -20[frameaddr].  */
 
-  if (TARGET_64BIT)
-    return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -16));
-  else
-    emit_move_insn (saved_rp, plus_constant (frameaddr, -5 * UNITS_PER_WORD));
+  saved_rp = gen_reg_rtx (Pmode);
+  emit_move_insn (saved_rp, plus_constant (frameaddr, -20));
 
   /* Get pointer to the instruction stream.  We have to mask out the
      privilege level from the two low order bits of the return address
@@ -5759,9 +5787,7 @@ output_millicode_call (insn, call_dest)
   rtx xoperands[4];
   rtx seq_insn;
 
-  xoperands[3] = gen_rtx_REG (SImode, 31);
-  if (TARGET_64BIT)
-    xoperands[3] = gen_rtx_REG (SImode, 2);
+  xoperands[3] = gen_rtx_REG (Pmode, TARGET_64BIT ? 2 : 31);
 
   /* Handle common case -- empty delay slot or no jump in the delay slot,
      and we're sure that the branch will reach the beginning of the $CODE$
@@ -5797,18 +5823,32 @@ output_millicode_call (insn, call_dest)
 	  delay_insn_deleted = 1;
 	}
 
-      /* If we're allowed to use be/ble instructions, then this is the
-	 best sequence to use for a long millicode call.  */
-      if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS
-	  || ! (flag_pic  || TARGET_PORTABLE_RUNTIME))
+      /* PIC long millicode call sequence.  */
+      if (flag_pic)
 	{
 	  xoperands[0] = call_dest;
-	  output_asm_insn ("ldil L%%%0,%3", xoperands);
-	  output_asm_insn ("{ble|be,l} R%%%0(%%sr4,%3)", xoperands);
+	  xoperands[1] = gen_label_rtx ();
+	  /* Get our address + 8 into %r1.  */
+	  output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
+
+	  /* Add %r1 to the offset of our target from the next insn.  */
+	  output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
+	  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+				     CODE_LABEL_NUMBER (xoperands[1]));
+	  output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
+
+	  /* Get the return address into %r31.  */
+	  output_asm_insn ("blr 0,%3", xoperands);
+
+	  /* Branch to our target which is in %r1.  */
+	  output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
+
+	  /* Empty delay slot.  Note this insn gets fetched twice and
+	     executed once.  To be safe we use a nop.  */
 	  output_asm_insn ("nop", xoperands);
 	}
       /* Pure portable runtime doesn't allow be/ble; we also don't have
-	 PIC support int he assembler/linker, so this sequence is needed.  */
+	 PIC support in the assembler/linker, so this sequence is needed.  */
       else if (TARGET_PORTABLE_RUNTIME)
 	{
 	  xoperands[0] = call_dest;
@@ -5825,30 +5865,14 @@ output_millicode_call (insn, call_dest)
 	  /* Empty delay slot.  Note this insn gets fetched twice and
 	     executed once.  To be safe we use a nop.  */
 	  output_asm_insn ("nop", xoperands);
-	  return "";
 	}
-      /* PIC long millicode call sequence.  */
+      /* If we're allowed to use be/ble instructions, then this is the
+	 best sequence to use for a long millicode call.  */
       else
 	{
 	  xoperands[0] = call_dest;
-	  xoperands[1] = gen_label_rtx ();
-	  /* Get our address + 8 into %r1.  */
-	  output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
-
-	  /* Add %r1 to the offset of our target from the next insn.  */
-	  output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
-	  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
-				     CODE_LABEL_NUMBER (xoperands[1]));
-	  output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
-
-	  /* Get the return address into %r31.  */
-	  output_asm_insn ("blr 0,%3", xoperands);
-
-	  /* Branch to our target which is in %r1.  */
-	  output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
-
-	  /* Empty delay slot.  Note this insn gets fetched twice and
-	     executed once.  To be safe we use a nop.  */
+	  output_asm_insn ("ldil L%%%0,%3", xoperands);
+	  output_asm_insn ("{ble|be,l} R%%%0(%%sr4,%3)", xoperands);
 	  output_asm_insn ("nop", xoperands);
 	}
 
diff -urpN -xCVS -x*~ gcc-current/gcc/config/pa/pa.md parisc/gcc/gcc/config/pa/pa.md
--- gcc-current/gcc/config/pa/pa.md	Sat Mar 24 19:58:19 2001
+++ parisc/gcc/gcc/config/pa/pa.md	Fri Mar 30 14:07:54 2001
@@ -3942,21 +3942,18 @@
                      (const_int 0)))
             (const_int 4)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+            (ne (symbol_ref "flag_pic")
                 (const_int 0))
-            (const_int 8)
+            (const_int 24)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+            (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+                (const_int 0))
+            (const_int 20)]
 
-;; Out of range and either PIC or PORTABLE_RUNTIME
-	  (const_int 24)))])
+;; Out of reach, can use ble
+          (const_int 12)))])
 
 (define_expand "muldi3"
   [(set (match_operand:DI 0 "register_operand" "")
@@ -4049,21 +4046,18 @@
                      (const_int 0)))
             (const_int 4)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+            (ne (symbol_ref "flag_pic")
                 (const_int 0))
-            (const_int 8)
+            (const_int 24)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+            (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+                (const_int 0))
+            (const_int 20)]
 
-;; Out of range and either PIC or PORTABLE_RUNTIME
-	  (const_int 24)))])
+;; Out of reach, can use ble
+          (const_int 12)))])
 
 (define_expand "udivsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@@ -4107,21 +4101,18 @@
                      (const_int 0)))
             (const_int 4)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+            (ne (symbol_ref "flag_pic")
                 (const_int 0))
-            (const_int 8)
+            (const_int 24)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+            (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+                (const_int 0))
+            (const_int 20)]
 
-;; Out of range and either PIC or PORTABLE_RUNTIME
-	  (const_int 24)))])
+;; Out of reach, can use ble
+          (const_int 12)))])
 
 (define_expand "modsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@@ -4162,21 +4153,18 @@
                      (const_int 0)))
             (const_int 4)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+            (ne (symbol_ref "flag_pic")
                 (const_int 0))
-            (const_int 8)
+            (const_int 24)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+            (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+                (const_int 0))
+            (const_int 20)]
 
-;; Out of range and either PIC or PORTABLE_RUNTIME
-	  (const_int 24)))])
+;; Out of reach, can use ble
+          (const_int 12)))])
 
 (define_expand "umodsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
@@ -4217,21 +4205,18 @@
                      (const_int 0)))
             (const_int 4)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+            (ne (symbol_ref "flag_pic")
                 (const_int 0))
-            (const_int 8)
+            (const_int 24)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+            (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+                (const_int 0))
+            (const_int 20)]
 
-;; Out of range and either PIC or PORTABLE_RUNTIME
-	  (const_int 24)))])
+;; Out of reach, can use ble
+          (const_int 12)))])
 
 ;;- and instructions
 ;; We define DImode `and` so with DImode `not` we can get
@@ -5803,7 +5788,7 @@
   rtx xoperands[2];
 
   /* First the special case for kernels, level 0 systems, etc.  */
-  if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
+  if (TARGET_FAST_INDIRECT_CALLS)
     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
 
   /* Now the normal case -- we can reach $$dyncall directly or
@@ -5838,8 +5823,8 @@
   [(set_attr "type" "dyncall")
    (set (attr "length")
      (cond [
-;; First NO_SPACE_REGS
-	    (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; First FAST_INDIRECT_CALLS
+	    (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
 		(const_int 0))
 	    (const_int 8)
 
@@ -5850,19 +5835,18 @@
 		     (const_int 0)))
 	    (const_int 8)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-	    (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-		     (const_int 0))
-		 (eq (symbol_ref "flag_pic")
-		     (const_int 0)))
-	    (const_int 12)
+;; Out of reach PIC
+	    (ne (symbol_ref "flag_pic")
+		(const_int 0))
+	    (const_int 24)
 
+;; Out of reach PORTABLE_RUNTIME
 	    (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
 		(const_int 0))
 	    (const_int 20)]
 
-;; Out of range PIC case
-	  (const_int 24)))])
+;; Out of reach, can use ble
+	  (const_int 12)))])
 
 (define_expand "call_value"
   [(parallel [(set (match_operand 0 "" "")
@@ -5982,7 +5966,7 @@
   rtx xoperands[2];
 
   /* First the special case for kernels, level 0 systems, etc.  */
-  if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
+  if (TARGET_FAST_INDIRECT_CALLS)
     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
 
   /* Now the normal case -- we can reach $$dyncall directly or
@@ -6017,8 +6001,8 @@
   [(set_attr "type" "dyncall")
    (set (attr "length")
      (cond [
-;; First NO_SPACE_REGS
-	    (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; First FAST_INDIRECT_CALLS
+	    (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
 		(const_int 0))
 	    (const_int 8)
 
@@ -6029,19 +6013,18 @@
 		     (const_int 0)))
 	    (const_int 8)
 
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-	    (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-		     (const_int 0))
-		 (eq (symbol_ref "flag_pic")
-		     (const_int 0)))
-	    (const_int 12)
+;; Out of reach PIC
+	    (ne (symbol_ref "flag_pic")
+		(const_int 0))
+	    (const_int 24)
 
+;; Out of reach PORTABLE_RUNTIME
 	    (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
 		(const_int 0))
 	    (const_int 20)]
 
-;; Out of range PIC case
-	  (const_int 24)))])
+;; Out of reach, can use ble
+	  (const_int 12)))])
 
 ;; Call subroutine returning any type.
 
@@ -7109,26 +7092,18 @@
                      (const_int 0)))
             (const_int 28)
 
-;; NO_SPACE_REGS
-            (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
-                (const_int 0))
-            (const_int 32)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
-            (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
-                     (const_int 0))
-                 (eq (symbol_ref "flag_pic")
-                     (const_int 0)))
-            (const_int 32)
+;; Out of reach PIC
+	    (ne (symbol_ref "flag_pic")
+		(const_int 0))
+	    (const_int 44)
 
-;; PORTABLE_RUNTIME
+;; Out of reach PORTABLE_RUNTIME
 	    (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
 		(const_int 0))
 	    (const_int 40)]
 
-;; Out of range and PIC 
-	  (const_int 44)))])
+;; Out of reach, can use ble
+          (const_int 32)))])
 
 ;; On the PA, the PIC register is call clobbered, so it must
 ;; be saved & restored around calls by the caller.  If the call



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