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]

Use UNSPECs for Darwin PIC references


I'm trying to move rs6000 and darwin targets away from using
(const (minus ...)) to represent offsets.  See:

    http://gcc.gnu.org/ml/gcc/2008-09/msg00174.html

for details.

Most of the changes are straight-forward.  gen_pic_offset used
to create expressions of the form:

    (const (minus (symbol_ref "X") (symbol_ref "<pic base>")))

It now needs to create:

    (const (unspec [(symbol_ref "X")] UNSPEC_MACHOPIC_OFFSET))

It used to take the (symbol_ref "<pic base>") as a pic_base
parameter, using the direct form if this parameter was null.
The new function doesn't need pic_base, so it simply uses
MACHO_DYNAMIC_NO_PIC_P to choose between the direct and
indirect forms.

Some CPU-specific code used to create the (const (minus ...)) too.
I instead made gen_pic_offset public (renaming it to machopic_gen_offset)
and made the CPU code use that.

The main hitch is that we used to set crtl->uses_pic_offset_table
when creating the "<pic base>" symbol.  This was only actually
necessary in two places:

  - in cases where gen_pic_offset would be called
  - in rs6000.md:builtin_setjmp_receiver

Other callers are for when we have already decided to use
a PIC register.

The main quirk is that gen_pic_offset/machopic_gen_offset should
not set crtl->uses_pic_offset_table when called from cost-estimation
routines.  I've borrowed the ARM idiom for this.  Note that this
didn't used to be a problem because the cost-estimation routines
use (symbol_ref "") as a "typical" symbol.  In the rs6000 backend,
toc_label_name is "" for darwin, so toc_relative_expr_p returned
true for it.  toc_relative_expr_p wasn't conditional on TARGET_TOC
before my GNU/Linux and AIX patch, so:

      else if (mode == Pmode
	       && CONSTANT_P (operands[1])
	       && ((GET_CODE (operands[1]) != CONST_INT
		    && ! easy_fp_constant (operands[1], mode))
		   || (GET_CODE (operands[1]) == CONST_INT
		       && num_insns_constant (operands[1], mode) > 2)
		   || (GET_CODE (operands[0]) == REG
		       && FP_REGNO_P (REGNO (operands[0]))))
	       && GET_CODE (operands[1]) != HIGH
	       && ! legitimate_constant_pool_address_p (operands[1])
	       && ! toc_relative_expr_p (operands[1]))

was false for darwin when operands[1] == (symbol_ref "").

We can replace all remaining calls to machopic_function_base_name
with a symbolic constant (MACHOPIC_FUNCTION_BASE_NAME).  There's
also no need for machopic_function_base_sym; we can just use
gen_rtx_SYMBOL_REF.  (One place did this already.)

Bootstrapped & regression-tested on x86_64-linux-gnu.
Also tested by comparing the assembly output of gcc.c-torture,
gcc.dg and g++.dg on these targets:

    i386-darwin
    x86_64-darwin
    powerpc-darwin
    powerpc64-darwin 

For each target I used the options:

    -O2 -fno-pic
    -O2 -fpic
    -O2 -fPIC

The "before" run included the 3 x86 delegitimize_address patches,
the 'E' combine patch, and the alias.c:find_base_value patch.
The "after" run included the 3 (const (minus ...)) patches too.

The assembly output for powerpc-darwin, powerpc64-darwin and
x86_64-darwin was identical.  It looks like we're not going to
get identical code for i386-darwin though.  I've attached the
differences below.  They fall into two camps:

  - gcc.c-torture/compile/pr34029-2.s
  - g++.dg/opt/delay-slot-1.s

      These two are better under the new scheme.  The testcases
      have code like this:

          load address of X
          reference X - 1

      Under the old scheme, the load will be represented as:

          (const (minus (symbol_ref "X") (symbol_ref "<pic base>")))

      Subtracting 1 from this expression and simplifying gives:

          (const (plus (not (symbol_ref "<pic base>")) (symbol_ref "X")))

      which of course doesn't match an .md insn.  Under the new scheme
      we get:

          (const (plus (unspec [(symbol_ref "X")] ...) (const_int -1)))

      which does match.

  - gcc.c-torture/execute/ieee/fp-cmp-8f.s
  - gcc.c-torture/execute/pr20601-1.s
  - gcc.c-torture/unsorted/gen_tst.s
  - gcc.dg/gomp/for-16.s
  - gcc.dg/trampoline-1.s
  - gcc.dg/tree-prof/stringop-1.s
  - gcc.dg/tree-ssa/predcom-5.s
  - gcc.dg/tree-ssa/ssa-lim-6.s
  - gcc.dg/vect/pr36228.s
  - g++.dg/eh/registers1.s

      These testcases are directly equivalent up until register allocation,
      at which point different decisions cause us to make different
      assignments.

Note that PowerPC currently rejects constant offsets in a machopic
expression.  I've preserved that behaviour here.  

Richard


gcc/
	* config/darwin-protos.h (machopic_function_base_name): Delete.
	(machopic_function_base_sym): Likewise.
	(machopic_gen_offset): Declare.
	* config/darwin.h (MACHOPIC_FUNCTION_BASE_NAME): New macro.
	(ASM_OUTPUT_LABELREF): Use it instead of a hard-coded string constant.
	* config/darwin.c (machopic_function_base_name): Delete.
	(machopic_function_base_sym): Likewise.
	(gen_pic_offset): Rename to...
	(machopic_gen_offset): ...this and remove the pic_base argument.
	Instead use MACHO_DYNAMIC_NO_PIC_P to decide whether a PIC offset
	is needed.  Create an UNSPEC_MACHOPIC_OFFSET if so, and set
	crtl->uses_pic_offset_table.
	(machopic_indirect_data_reference): Use new machopic_gen_offset
	interface.
	(machopic_legitimize_pic_address): Likewise.
	(machopic_operand_p): Check for UNSPEC_MACHOPIC_OFFSET.

	* config/i386/darwin.h (GOT_SYMBOL_NAME): Use
	MACHOPIC_FUNCTION_BASE_NAME instead of machopic_function_base_name.
	* config/i386/i386.c (output_set_got): Likewise.
	(darwin_local_data_pic): Check for an UNSPEC_MACHOPIC_OFFSET
	instead of a MINUS.
	(legitimate_pic_operand_p): Handle UNSPEC_MACHOPIC_OFFSET.
	(legitimate_address_p): Likewise.
	(output_pic_addr_const): Likewise.
	(output_addr_const_extra): Likewise.
	(ix86_delegitimize_address): Expect darwin_local_data_pic to
	match an UNSPEC rather than a MINUS.
	* config/i386/i386.md (UNSPEC_MACHOPIC_OFFSET): Define.
	(builtin_setjmp_receiver): Use machopic_gen_offset.
	* config/i386/predicates.md (pic_symbolic_operand): Handle
	UNSPEC_MACHOPIC_OFFSET.

	* config/rs6000/rs6000.c (rs6000_legitimize_reload_address):
	Use machopic_gen_offset and machopic_operand_p.
	(rs6000_output_addr_const_extra): Handle UNSPEC_MACHOPIC_OFFSET.
	(rs6000_emit_prologue): Use MACHOPIC_FUNCTION_BASE_NAME.
	* config/rs6000/rs6000.md (UNSPEC_MACHOPIC_OFFSET): Define.
	(builtin_setjmp_receiver): Use MACHOPIC_FUNCTION_BASE_NAME.
	Set crtl->uses_pic_offset_table.

Index: gcc/config/darwin-protos.h
===================================================================
--- gcc/config/darwin-protos.h	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/darwin-protos.h	2008-09-22 19:12:40.000000000 +0100
@@ -22,14 +22,13 @@ extern int name_needs_quotes (const char
 
 extern void machopic_validate_stub_or_non_lazy_ptr (const char *);
 
-extern const char *machopic_function_base_name (void);
 extern void machopic_output_function_base_name (FILE *);
 extern const char *machopic_indirection_name (rtx, bool);
 extern const char *machopic_mcount_stub_name (void);
 
 #ifdef RTX_CODE
 
-extern rtx machopic_function_base_sym (void);
+extern rtx machopic_gen_offset (rtx);
 extern int machopic_operand_p (rtx);
 extern enum machopic_addr_class machopic_classify_symbol (rtx);
 
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/darwin.h	2008-09-22 19:12:41.000000000 +0100
@@ -525,6 +525,9 @@ #define TARGET_ASM_DESTRUCTOR   machopic
 
 #define USER_LABEL_PREFIX "_"
 
+/* A dummy symbol that will be replaced with the function base name.  */
+#define MACHOPIC_FUNCTION_BASE_NAME "<pic base>"
+
 /* Don't output a .file directive.  That is only used by the assembler for
    error reporting.  */
 #undef	TARGET_ASM_FILE_START_FILE_DIRECTIVE
@@ -609,7 +612,7 @@ #define ASM_DECLARE_CONSTANT_NAME(FILE, 
 #define ASM_OUTPUT_LABELREF(FILE,NAME)					     \
   do {									     \
        const char *xname = (NAME);					     \
-       if (! strcmp (xname, "<pic base>"))				     \
+       if (! strcmp (xname, MACHOPIC_FUNCTION_BASE_NAME))		     \
          machopic_output_function_base_name(FILE);                           \
        else if (xname[0] == '&' || xname[0] == '*')			     \
          {								     \
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/darwin.c	2008-09-22 19:12:40.000000000 +0100
@@ -267,44 +267,26 @@ machopic_define_symbol (rtx mem)
   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
 }
 
-static GTY(()) const char * function_base;
+/* Return either ORIG or:
 
-const char *
-machopic_function_base_name (void)
-{
-  /* if dynamic-no-pic is on, we should not get here */
-  gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
-
-  if (function_base == NULL)
-    function_base = ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
-
-  crtl->uses_pic_offset_table = 1;
-
-  return function_base;
-}
-
-/* Return a SYMBOL_REF for the PIC function base.  */
+     (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))
 
+   depending on MACHO_DYNAMIC_NO_PIC_P.  */
 rtx
-machopic_function_base_sym (void)
-{
-  rtx sym_ref;
-
-  sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
-  SYMBOL_REF_FLAGS (sym_ref)
-    |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
-  return sym_ref;
-}
-
-/* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
-   on whether pic_base is NULL or not.  */
-static inline rtx
-gen_pic_offset (rtx orig, rtx pic_base)
+machopic_gen_offset (rtx orig)
 {
-  if (!pic_base)
+  if (MACHO_DYNAMIC_NO_PIC_P)
     return orig;
   else
-    return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
+    {
+      /* Play games to avoid marking the function as needing pic if we
+	 are being called as part of the cost-estimation process.  */
+      if (current_ir_type () != IR_GIMPLE)
+	crtl->uses_pic_offset_table = 1;
+      orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
+			     UNSPEC_MACHOPIC_OFFSET);
+      return gen_rtx_CONST (Pmode, orig);
+    }
 }
 
 static GTY(()) const char * function_base_func_name;
@@ -528,8 +510,7 @@ machopic_indirect_data_reference (rtx or
       else if (defined)
 	{
 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
-	  rtx pic_base = machopic_function_base_sym ();
-	  rtx offset = gen_pic_offset (orig, pic_base);
+	  rtx offset = machopic_gen_offset (orig);
 #endif
 
 #if defined (TARGET_TOC) /* i.e., PowerPC */
@@ -675,8 +656,6 @@ machopic_legitimize_pic_address (rtx ori
 	  ))
     {
       /* addr(foo) = &func+(foo-func) */
-      rtx pic_base;
-
       orig = machopic_indirect_data_reference (orig, reg);
 
       if (GET_CODE (orig) == PLUS
@@ -689,12 +668,6 @@ machopic_legitimize_pic_address (rtx ori
 	  return reg;
 	}
 
-      /* if dynamic-no-pic we don't have a pic base  */
-      if (MACHO_DYNAMIC_NO_PIC_P)
-	pic_base = NULL;
-      else
-	pic_base = machopic_function_base_sym ();
-
       if (GET_CODE (orig) == MEM)
 	{
 	  if (reg == 0)
@@ -731,7 +704,7 @@ machopic_legitimize_pic_address (rtx ori
 	  if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
 	      || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
 	    {
-	      rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
+	      rtx offset = machopic_gen_offset (XEXP (orig, 0));
 #if defined (TARGET_TOC) /* i.e., PowerPC */
 	      /* Generating a new reg may expose opportunities for
 		 common subexpression elimination.  */
@@ -787,8 +760,7 @@ machopic_legitimize_pic_address (rtx ori
 	      if (reload_in_progress)
 		df_set_regs_ever_live (REGNO (pic), true);
 	      pic_ref = gen_rtx_PLUS (Pmode, pic,
-				      gen_pic_offset (XEXP (orig, 0),
-						      pic_base));
+				      machopic_gen_offset (XEXP (orig, 0)));
 	    }
 
 #if !defined (TARGET_TOC)
@@ -803,7 +775,7 @@ machopic_legitimize_pic_address (rtx ori
 	  if (GET_CODE (orig) == SYMBOL_REF
 	      || GET_CODE (orig) == LABEL_REF)
 	    {
-	      rtx offset = gen_pic_offset (orig, pic_base);
+	      rtx offset = machopic_gen_offset (orig);
 #if defined (TARGET_TOC) /* i.e., PowerPC */
               rtx hi_sum_reg;
 
@@ -860,7 +832,7 @@ machopic_legitimize_pic_address (rtx ori
 		    df_set_regs_ever_live (REGNO (pic), true);
 		  pic_ref = gen_rtx_PLUS (Pmode,
 					  pic,
-					  gen_pic_offset (orig, pic_base));
+					  machopic_gen_offset (orig));
 		}
 	    }
 	}
@@ -1040,27 +1012,12 @@ machopic_finish (FILE *asm_out_file)
 machopic_operand_p (rtx op)
 {
   if (MACHOPIC_JUST_INDIRECT)
-    {
-      while (GET_CODE (op) == CONST)
-	op = XEXP (op, 0);
-
-      if (GET_CODE (op) == SYMBOL_REF)
-	return machopic_symbol_defined_p (op);
-      else
-	return 0;
-    }
-
-  while (GET_CODE (op) == CONST)
-    op = XEXP (op, 0);
-
-  if (GET_CODE (op) == MINUS
-      && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-      && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
-      && machopic_symbol_defined_p (XEXP (op, 0))
-      && machopic_symbol_defined_p (XEXP (op, 1)))
-      return 1;
-
-  return 0;
+    return (GET_CODE (op) == SYMBOL_REF
+	    && machopic_symbol_defined_p (op));
+  else
+    return (GET_CODE (op) == CONST
+	    && GET_CODE (XEXP (op, 0)) == UNSPEC
+	    && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
 }
 
 /* This function records whether a given name corresponds to a defined
Index: gcc/config/i386/darwin.h
===================================================================
--- gcc/config/i386/darwin.h	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/i386/darwin.h	2008-09-22 19:12:40.000000000 +0100
@@ -176,7 +176,7 @@ #define MASK_MACHO_DYNAMIC_NO_PIC 0
 #define TARGET_DYNAMIC_NO_PIC	  (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
 
 #undef GOT_SYMBOL_NAME
-#define GOT_SYMBOL_NAME (machopic_function_base_name ())
+#define GOT_SYMBOL_NAME MACHOPIC_FUNCTION_BASE_NAME
 
 /* Define the syntax of pseudo-ops, labels and comments.  */
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2008-09-22 08:13:22.000000000 +0100
+++ gcc/config/i386/i386.c	2008-09-22 19:12:40.000000000 +0100
@@ -7267,7 +7267,7 @@ output_set_got (rtx dest, rtx label ATTR
       /* Output the Mach-O "canonical" label name ("Lxx$pb") here too.  This
          is what will be referenced by the Mach-O PIC subsystem.  */
       if (!label)
-	ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+	ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
 #endif
 
       (*targetm.asm_out.internal_label) (asm_out_file, "L",
@@ -7289,7 +7289,7 @@ output_set_got (rtx dest, rtx label ATTR
          is what will be referenced by the Mach-O PIC subsystem.  */
 #if TARGET_MACHO
       if (!label)
-	ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+	ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
       else
         targetm.asm_out.internal_label (asm_out_file, "L",
 					   CODE_LABEL_NUMBER (label));
@@ -8556,19 +8556,8 @@ ix86_address_cost (rtx x, bool speed ATT
 static bool
 darwin_local_data_pic (rtx disp)
 {
-  if (GET_CODE (disp) == MINUS)
-    {
-      if (GET_CODE (XEXP (disp, 0)) == LABEL_REF
-          || GET_CODE (XEXP (disp, 0)) == SYMBOL_REF)
-        if (GET_CODE (XEXP (disp, 1)) == SYMBOL_REF)
-          {
-            const char *sym_name = XSTR (XEXP (disp, 1), 0);
-            if (! strcmp (sym_name, "<pic base>"))
-              return true;
-          }
-    }
-
-  return false;
+  return (GET_CODE (disp) == UNSPEC
+	  && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
 }
 
 /* Determine if a given RTX is a valid constant.  We already know this
@@ -8709,6 +8698,8 @@ legitimate_pic_operand_p (rtx x)
 	    x = XVECEXP (inner, 0, 0);
 	    return (GET_CODE (x) == SYMBOL_REF
 		    && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
+	  case UNSPEC_MACHOPIC_OFFSET:
+	    return legitimate_pic_address_disp_p (x);
 	  default:
 	    return false;
 	  }
@@ -8971,7 +8962,8 @@ legitimate_address_p (enum machine_mode 
       reason_rtx = disp;
 
       if (GET_CODE (disp) == CONST
-	  && GET_CODE (XEXP (disp, 0)) == UNSPEC)
+	  && GET_CODE (XEXP (disp, 0)) == UNSPEC
+	  && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
 	switch (XINT (XEXP (disp, 0), 1))
 	  {
 	  /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit when
@@ -9934,6 +9926,12 @@ output_pic_addr_const (FILE *file, rtx x
 	case UNSPEC_INDNTPOFF:
 	  fputs ("@INDNTPOFF", file);
 	  break;
+#if TARGET_MACHO
+	case UNSPEC_MACHOPIC_OFFSET:
+	  putc ('-', file);
+	  machopic_output_function_base_name (file);
+	  break;
+#endif
 	default:
 	  output_operand_lossage ("invalid UNSPEC as operand");
 	  break;
@@ -10054,7 +10052,7 @@ ix86_delegitimize_address (rtx orig_x)
 
   if (TARGET_MACHO && darwin_local_data_pic (x)
       && !MEM_P (orig_x))
-    result = XEXP (x, 0);
+    result = XVECEXP (x, 0, 0);
 
   if (! result)
     return orig_x;
@@ -11166,6 +11164,13 @@ output_addr_const_extra (FILE *file, rtx
       output_addr_const (file, op);
       fputs ("@INDNTPOFF", file);
       break;
+#if TARGET_MACHO
+    case UNSPEC_MACHOPIC_OFFSET:
+      output_addr_const (file, op);
+      putc ('-', file);
+      machopic_output_function_base_name (file);
+      break;
+#endif
 
     default:
       return false;
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/i386/i386.md	2008-09-22 19:12:41.000000000 +0100
@@ -58,6 +58,7 @@ (define_constants
    (UNSPEC_GOTNTPOFF		7)
    (UNSPEC_INDNTPOFF		8)
    (UNSPEC_PLTOFF		9)
+   (UNSPEC_MACHOPIC_OFFSET	10)
 
    ; Prologue support
    (UNSPEC_STACK_ALLOC		11)
@@ -20315,6 +20316,7 @@ (define_expand "builtin_setjmp_receiver"
   [(label_ref (match_operand 0 "" ""))]
   "!TARGET_64BIT && flag_pic"
 {
+#if TARGET_MACHO
   if (TARGET_MACHO)
     {
       rtx xops[3];
@@ -20322,13 +20324,11 @@ (define_expand "builtin_setjmp_receiver"
       rtx label_rtx = gen_label_rtx ();
       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
       xops[0] = xops[1] = picreg;
-      xops[2] = gen_rtx_CONST (SImode,
-	          gen_rtx_MINUS (SImode,
-		    gen_rtx_LABEL_REF (SImode, label_rtx),
-		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
+      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
       ix86_expand_binary_operator (MINUS, SImode, xops);
     }
   else
+#endif
     emit_insn (gen_set_got (pic_offset_table_rtx));
   DONE;
 })
Index: gcc/config/i386/predicates.md
===================================================================
--- gcc/config/i386/predicates.md	2008-09-22 07:53:34.000000000 +0100
+++ gcc/config/i386/predicates.md	2008-09-22 19:12:41.000000000 +0100
@@ -428,7 +428,8 @@ (define_predicate "pic_symbolic_operand"
 	  || !CONST_INT_P (XEXP (op, 1)))
 	return 0;
       op = XEXP (op, 0);
-      if (GET_CODE (op) == UNSPEC)
+      if (GET_CODE (op) == UNSPEC
+	  && XINT (op, 1) != UNSPEC_MACHOPIC_OFFSET)
 	return 1;
     }
   return 0;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2008-09-22 08:52:04.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2008-09-22 19:24:21.000000000 +0100
@@ -4110,8 +4110,8 @@ #define REG_MODE_OK_FOR_BASE_P(REGNO, MO
 
    On Darwin, we use this to generate code for floating point constants.
    A movsf_low is generated so we wind up with 2 instructions rather than 3.
-   The Darwin code is inside #if TARGET_MACHO because only then is
-   machopic_function_base_name() defined.  */
+   The Darwin code is inside #if TARGET_MACHO because only then are the
+   machopic_* functions defined.  */
 rtx
 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
 				  int opnum, int type,
@@ -4137,11 +4137,8 @@ rs6000_legitimize_reload_address (rtx x,
       && GET_CODE (XEXP (x, 0)) == PLUS
       && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
       && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
-      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
       && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
-      && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
-      && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
-      && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
+      && machopic_operand_p (XEXP (x, 1)))
     {
       /* Result of previous invocation of this function on Darwin
 	 floating point constant.  */
@@ -4233,9 +4230,7 @@ rs6000_legitimize_reload_address (rtx x,
 #if TARGET_MACHO
       if (flag_pic)
 	{
-	  rtx offset = gen_rtx_CONST (Pmode,
-			 gen_rtx_MINUS (Pmode, x,
-					machopic_function_base_sym ()));
+	  rtx offset = machopic_gen_offset (x);
 	  x = gen_rtx_LO_SUM (GET_MODE (x),
 		gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
 		  gen_rtx_HIGH (Pmode, offset)), offset);
@@ -12461,6 +12456,14 @@ rs6000_output_addr_const_extra (FILE *fi
 	else if (TARGET_ELF)
 	  fputs ("@toc", file);
 	return true;
+
+#if TARGET_MACHO
+      case UNSPEC_MACHOPIC_OFFSET:
+	output_addr_const (file, XVECEXP (x, 0, 0));
+	putc ('-', file);
+	machopic_output_function_base_name (file);
+	return true;
+#endif
       }
   return false;
 }
@@ -16539,7 +16542,7 @@ rs6000_emit_prologue (void)
       && flag_pic && crtl->uses_pic_offset_table)
     {
       rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
-      rtx src = machopic_function_base_sym ();
+      rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
 
       /* Save and restore LR locally around this call (in R0).  */
       if (!info->lr_save_p)
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	2008-09-22 08:52:04.000000000 +0100
+++ gcc/config/rs6000/rs6000.md	2008-09-22 19:12:41.000000000 +0100
@@ -100,6 +100,7 @@ (define_constants
    (UNSPEC_DLMZB_STRLEN		47)
    (UNSPEC_RSQRT		48)
    (UNSPEC_TOCREL		49)
+   (UNSPEC_MACHOPIC_OFFSET	50)
   ])
 
 ;;
@@ -10540,12 +10541,12 @@ (define_expand "builtin_setjmp_receiver"
 #if TARGET_MACHO
   if (DEFAULT_ABI == ABI_DARWIN)
     {
-      const char *picbase = machopic_function_base_name ();
-      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (picbase));
+      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
       rtx tmplabrtx;
       char tmplab[20];
 
+      crtl->uses_pic_offset_table = 1;
       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
 				  CODE_LABEL_NUMBER (operands[0]));
       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));


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