Patchwork [x86,Darwin] update darwin's x86 output.

login
register
mail settings
Submitter IainS
Date Oct. 31, 2010, 5:07 p.m.
Message ID <0C9D7B56-EE4B-4638-9352-DEF5829D1E3A@sandoe-acoustics.co.uk>
Download mbox | patch
Permalink /patch/69722/
State New
Headers show

Comments

IainS - Oct. 31, 2010, 5:07 p.m.
Hi,

This is a merge from the FSF apple 'trunk' branch - a  
"modernization"  (if somewhat slow in arriving) of the darwin x86  
output.

It makes the stub choices and sections agree with those used by the  
Darwin system tools, and also finally enables -mdynamic-no-pic for  
i686-darwin.

This is all darwin-specific - but, because I've tried to minimize the  
use of #ifdef, there are changes to the code in i386.c which, in  
principle, could affect other platforms ...

The code (less the changes to minimize #ifdefs) is pretty much what's  
in the darwin 9 & 10 XCode compilers... although I fixed one bug (in  
darwin.c)...

It became a complete mess to try and remove all the #ifdefs by macro- 
izing the machopic functions and, therefore, there are still  a couple  
of #ifdef'd sections ***.

anyway,
bootstrapped on x86-darwin{8,9,10} , ppc-darwin9 and on x86-64-unk- 
linux.

OK for trunk?
Iain

***
In principle, we should be able to split the machopic implementation  
from darwin.{c,h} and move the target-specific bits into i386/rs6000.c  
which would allow us to do away with the ifdefs completely - perhaps  
that's a project for 4.7 (or maybe a branch).

------

gcc:

	Merge from FSF "apple/trunk" branch.

	* config/i386/darwin.opt (mdynamic-no-pic): move from here ...
	* config/rs6000/darwin.opt (mdynamic-no-pic): ... and here ...
	* config/darwin.opt: .. to here.
	(matt-stubs): New option.
	* config/i386/i386.h (MACHOPIC_ATT_STUB): New.
	(MACHO_DYNAMIC_NO_PIC_P): New.
	(MACHOPIC_INDIRECT): New.
	(MACHOPIC_PURE): New.
	* config/i386/darwin.h (DARWIN_X86) Define to 1.
	(MACHOPIC_ATT_STUB): New.
	(CC1_SPEC): Do not remove mdynamic-no-pic.
	Move HOT_TEXT_SECTION_NAME: move to config/darwin.h
	UNLIKELY_EXECUTED_TEXT_SECTION_NAME: Likewise.
	(FUNCTION_PROFILER): Correct over-length line.
	(SUBTARGET_OVERRIDE_OPTIONS): New.
	(MACHOPIC_NL_SYMBOL_PTR_SECTION): New.
	* config/i386/i386.c (config/i386/i386.c): Darwin has no PLT.
	(legitimate_constant_p): Handle mdynamic-no-pic.
	(ix86_legitimate_address_p): Likewise.
	(ix86_legitimize_address): Likewise.
	(ix86_expand_move): Likewise.
	(machopic_output_stub): Update for ATT-style stubs and
	mdynamic-no-pic.
	* config/darwin-protos.h (machopic_symbol_defined_p): New.
	* config/rs6000/darwin.h (DARWIN_PPC): Define to 1.
	TARGET_DYNAMIC_NO_PIC: Remove.
	Move HOT_TEXT_SECTION_NAME: move to config/darwin.h
	UNLIKELY_EXECUTED_TEXT_SECTION_NAME: Likewise.
	* config/rs6000/rs6000.c (darwin_rs6000_override_options):
	Remove handling of mdynamic-no-pic.
	* config/darwin.c (HAVE_lo_sum, gen_macho_high, gen_macho_low):
	Define if required.
	(machopic_symbol_defined_p): Do not try to use current_function_decl
	when generating _get_pc thunks within stubs.
	(machopic_indirect_data_reference): Rework for direct conditionals  
rather
	than #ifdefs, add x86 mdynamic-no-pic
	(machopic_legitimize_pic_address): Update to use HAVE_lo_sum with a
	defined value.
	(darwin_override_options): Handle mdynamic-no-pic here.
	* config/darwin-sections.def (machopic_lazy_symbol_ptr2_section): New.
	(machopic_lazy_symbol_ptr3_section): New.
	(machopic_picsymbol_stub2_section): New.
	(machopic_picsymbol_stub3_section): New.
	* config/darwin.h (DARWIN_X86, DARWIN_PPC): Define to 0.
	(MACHOPIC_NL_SYMBOL_PTR_SECTION): New.
	(HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME):
	Moved common definition from x86 and rs6000.
	(MACHO_DYNAMIC_NO_PIC_P): Override value.
	(MACHOPIC_INDIRECT): Likewise.
	(MACHOPIC_PURE): Likewise.
Joseph S. Myers - Oct. 31, 2010, 6:36 p.m.
On Sun, 31 Oct 2010, IainS wrote:

> 	* config/i386/darwin.opt (mdynamic-no-pic): move from here ...

This leaves no options in this file.  So you might as well remove it and 
update config.gcc accordingly.
Richard Henderson - Oct. 31, 2010, 11:38 p.m.
> +  if (!TARGET_MACHO
> +      && !TARGET_64BIT && flag_pic && (!decl || !targetm.binds_local_p (decl)))

Please format this better.

> @@ -11478,8 +11479,25 @@ legitimate_constant_p (rtx x)
... 
> +    case PLUS:
> +      {
> +	rtx left = XEXP (x, 0);
> +	rtx right = XEXP (x, 1);
> +	bool left_is_constant = legitimate_constant_p (left);
> +	bool right_is_constant = legitimate_constant_p (right);
> +	return left_is_constant && right_is_constant;
> +      }
> +     /* mdynamic-no-pic */
> + #endif
> +      break;

This is very inkorrekt.

PLUS is RTX_COMM_ARITH.  A constant must be RTX_CONST_OBJ.

The correct way to handle this is to wrap a PLUS inside of
a CONST, which means this code is in the wrong place, and
the thing that's generating this is also incorrect.

The rest of it looks plausible.


r~
IainS - Oct. 31, 2010, 11:43 p.m.
On 31 Oct 2010, at 23:38, Richard Henderson wrote:

>> @@ -11478,8 +11479,25 @@ legitimate_constant_p (rtx x)
> ...
>> +    case PLUS:
>> +      {
>> +	rtx left = XEXP (x, 0);
>> +	rtx right = XEXP (x, 1);
>> +	bool left_is_constant = legitimate_constant_p (left);
>> +	bool right_is_constant = legitimate_constant_p (right);
>> +	return left_is_constant && right_is_constant;
>> +      }
>> +     /* mdynamic-no-pic */
>> + #endif
>> +      break;
>
> This is very inkorrekt.
>
> PLUS is RTX_COMM_ARITH.  A constant must be RTX_CONST_OBJ.
>
> The correct way to handle this is to wrap a PLUS inside of
> a CONST, which means this code is in the wrong place, and
> the thing that's generating this is also incorrect.


thanks, will try and figure out what's happened here (and why it seems  
to work).
Iain
IainS - Nov. 1, 2010, 11:57 a.m.
On 31 Oct 2010, at 23:43, IainS wrote:

>
> On 31 Oct 2010, at 23:38, Richard Henderson wrote:
>
>>> @@ -11478,8 +11479,25 @@ legitimate_constant_p (rtx x)
>> ...
>>> +    case PLUS:
>>> +      {
>>> +	rtx left = XEXP (x, 0);
>>> +	rtx right = XEXP (x, 1);
>>> +	bool left_is_constant = legitimate_constant_p (left);
>>> +	bool right_is_constant = legitimate_constant_p (right);
>>> +	return left_is_constant && right_is_constant;
>>> +      }
>>> +     /* mdynamic-no-pic */
>>> + #endif
>>> +      break;
>>
>> This is very inkorrekt.
>>
>> PLUS is RTX_COMM_ARITH.  A constant must be RTX_CONST_OBJ.
>>
>> The correct way to handle this is to wrap a PLUS inside of
>> a CONST, which means this code is in the wrong place, and
>> the thing that's generating this is also incorrect.
>
>
> thanks, will try and figure out what's happened here (and why it  
> seems to work).

Looking closer, it seems that I've merged code that was dead in the  
original :-(

I tested this hypothesis by placing a gcc_unreachable () after the  
case PLUS:
and bootstrapping (with -mdynamic-no-pic in boot flags) and doing make  
check-gcc with
-m32/-mdynamic-no-pic
-m32/-mdynamic-no-pic/-mno-att-stubs
-m32/-mdynamic-no-pic/-mmacosx-version-min=10.4

no ices attributable to this...

but I really need Mike to comment since he is (much) closer to this  
code than I am.

cheers
Iain
Mike Stump - Nov. 1, 2010, 7:09 p.m.
On Nov 1, 2010, at 4:57 AM, IainS wrote:
> Looking closer, it seems that I've merged code that was dead in the original :-(

Yes, that's a distinct possibility.  The old code did it one way, it was fixed up to do it better, but this remnant remained.  I'd remove it and proceed forward.  Worse case scenario would be we find a fault down the road and have to change the code that builds up a plus to instead wrap a const around it.  I'm thinking this code should fall over often and fairly quickly if we get it wrong.  For example, a mere bootstrap with -mdynamic-no-pic on a -m32 style build should excise it sufficiently well.

> I tested this hypothesis by placing a gcc_unreachable () after the case PLUS:
> and bootstrapping (with -mdynamic-no-pic in boot flags) and doing make check-gcc with
> -m32/-mdynamic-no-pic

Sounds sufficient.

> OK for trunk?

Ok with the rth please format this better fix and the dropping of the dead code rth pointed out.

I'd pre-approve the mh-*darwin changes as well, either to have just a mh-darwin, if both architectures are now the same, or to have one per architecture.  Preference for the former, unless you have visibility into more code that might want to go into one but not the other file.  If -m64 warns and needs something different, I'd rather have two files, unless we want to make it not warn.  Similar comment about the .opt file.  If we know of things that might go into it in the future, I'm fine with leaving a stub.  Doing then undoing and redoing configure work is just annoying.

Patch

Index: gcc/config/darwin.opt
===================================================================
--- gcc/config/darwin.opt	(revision 166105)
+++ gcc/config/darwin.opt	(working copy)
@@ -1,6 +1,6 @@ 
 ; Processor-independent options for Darwin.
 
-; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2007, 2010 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -26,6 +26,15 @@  Wnonportable-cfstrings
 Target Report Var(darwin_warn_nonportable_cfstrings) Init(1) Warning
 Warn if constant CFString objects contain non-portable characters
 
+; Use new-style pic stubs if this is true, x86 only so far.
+matt-stubs
+Target Report Var(darwin_macho_att_stub) Init(1)
+Generate AT&T-style stubs for Mach-O
+
+mdynamic-no-pic
+Target Common Report Mask(MACHO_DYNAMIC_NO_PIC)
+Generate code suitable for executables (NOT shared libs)
+
 mfix-and-continue
 Target Report Var(darwin_fix_and_continue)
 Generate code suitable for fast turn around debugging
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 166105)
+++ gcc/config/i386/i386.h	(working copy)
@@ -476,16 +476,15 @@  extern tree x86_mfence;
 #define TARGET_SUBTARGET64_DEFAULT 0
 #define TARGET_SUBTARGET64_ISA_DEFAULT 0
 
-/* This is not really a target flag, but is done this way so that
-   it's analogous to similar code for Mach-O on PowerPC.  darwin.h
-   redefines this to 1.  */
+/* Replace MACH-O, ifdefs by in-line tests, where possible. 
+   (a) Macros defined in config/i386/darwin.h  */
 #define TARGET_MACHO 0
-
-/* Branch island 'stubs' are emitted for earlier versions of darwin.
-   This provides a default (over-ridden in darwin.h.)  */
-#ifndef TARGET_MACHO_BRANCH_ISLANDS
 #define TARGET_MACHO_BRANCH_ISLANDS 0
-#endif
+#define MACHOPIC_ATT_STUB 0
+/* (b) Macros defined in config/darwin.h  */
+#define MACHO_DYNAMIC_NO_PIC_P 0
+#define MACHOPIC_INDIRECT 0
+#define MACHOPIC_PURE 0
 
 /* For the Windows 64-bit ABI.  */
 #define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
Index: gcc/config/i386/darwin.opt
===================================================================
--- gcc/config/i386/darwin.opt	(revision 166105)
+++ gcc/config/i386/darwin.opt	(working copy)
@@ -17,6 +17,3 @@ 
 ; You should have received a copy of the GNU General Public License
 ; along with GCC; see the file COPYING3.  If not see
 ; <http://www.gnu.org/licenses/>.
-
-mdynamic-no-pic
-Target RejectNegative Ignore
Index: gcc/config/i386/darwin.h
===================================================================
--- gcc/config/i386/darwin.h	(revision 166105)
+++ gcc/config/i386/darwin.h	(working copy)
@@ -23,6 +23,9 @@  along with GCC; see the file COPYING3.  If not see
 #undef TARGET_MACHO
 #define TARGET_MACHO 1
 
+#undef DARWIN_X86
+#define DARWIN_X86 1
+
 #define TARGET_VERSION fprintf (stderr, " (i686 Darwin)");
 
 #undef  TARGET_64BIT
@@ -66,6 +69,11 @@  extern int darwin_emit_branch_islands;
 #undef TARGET_MACHO_BRANCH_ISLANDS
 #define TARGET_MACHO_BRANCH_ISLANDS darwin_emit_branch_islands
 
+/* For compatibility with OSX system tools, use the new style of pic stub
+   if this is set.  */
+#undef  MACHOPIC_ATT_STUB
+#define MACHOPIC_ATT_STUB (darwin_macho_att_stub)
+
 #undef MAX_BITS_PER_WORD
 #define MAX_BITS_PER_WORD 64
 
@@ -100,7 +108,6 @@  extern int darwin_emit_branch_islands;
 
 #undef CC1_SPEC
 #define CC1_SPEC "%(cc1_cpu) \
-  %<mdynamic-no-pic " /* For now, we just ignore this flag */ " \
   %{!mkernel:%{!static:%{!mdynamic-no-pic:-fPIC}}} \
   %{!mmacosx-version-min=*:-mmacosx-version-min=%(darwin_minversion)} \
   %{g: %{!fno-eliminate-unused-debug-symbols: -feliminate-unused-debug-symbols }}"
@@ -182,11 +189,6 @@  extern int darwin_emit_branch_islands;
 #undef TARGET_SUBTARGET64_ISA_DEFAULT
 #define TARGET_SUBTARGET64_ISA_DEFAULT TARGET_SUBTARGET32_ISA_DEFAULT
 
-/* For now, disable dynamic-no-pic.  We'll need to go through i386.c
-   with a fine-tooth comb looking for refs to flag_pic!  */
-#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
 
@@ -194,11 +196,6 @@  extern int darwin_emit_branch_islands;
 
 #define LPREFIX "L"
 
-/* These are used by -fbranch-probabilities */
-#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
-#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
-                              "__TEXT,__unlikely,regular,pure_instructions"
-
 /* Assembler pseudos to introduce constants of various size.  */
 
 #define ASM_BYTE "\t.byte\t"
@@ -239,7 +236,8 @@  extern int darwin_emit_branch_islands;
 #undef FUNCTION_PROFILER
 #define FUNCTION_PROFILER(FILE, LABELNO)				\
     do {								\
-      if (TARGET_MACHO_BRANCH_ISLANDS && MACHOPIC_INDIRECT && !TARGET_64BIT)		\
+      if (TARGET_MACHO_BRANCH_ISLANDS 					\
+	   && MACHOPIC_INDIRECT && !TARGET_64BIT)			\
 	{								\
 	  const char *name = machopic_mcount_stub_name ();		\
 	  fprintf (FILE, "\tcall %s\n", name+1);  /*  skip '&'  */	\
@@ -253,6 +251,13 @@  extern int darwin_emit_branch_islands;
     SUBTARGET_C_COMMON_OVERRIDE_OPTIONS;				\
   } while (0)
 
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do {									\
+  if (TARGET_64BIT && MACHO_DYNAMIC_NO_PIC_P)				\
+    target_flags &= ~MASK_MACHO_DYNAMIC_NO_PIC;				\
+} while (0)
+
 /* Darwin on x86_64 uses dwarf-2 by default.  Pre-darwin9 32-bit
    compiles default to stabs+.  darwin9+ defaults to dwarf-2.  */
 #ifndef DARWIN_PREFER_DWARF
@@ -313,6 +318,10 @@  extern int darwin_emit_branch_islands;
 #undef MACHO_SYMBOL_FLAG_VARIABLE
 #define MACHO_SYMBOL_FLAG_VARIABLE ((SYMBOL_FLAG_MACH_DEP) << 3)
 
+#undef MACHOPIC_NL_SYMBOL_PTR_SECTION
+#define MACHOPIC_NL_SYMBOL_PTR_SECTION \
+		".section __IMPORT,__pointers,non_lazy_symbol_pointers"
+
 #define SUBTARGET32_DEFAULT_CPU "i686"
 
 #undef  SUBTARGET_INIT_BUILTINS
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 166105)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4926,8 +4926,9 @@  ix86_function_ok_for_sibcall (tree decl, tree exp)
 
   /* If we are generating position-independent code, we cannot sibcall
      optimize any indirect call, or a direct call to a global function,
-     as the PLT requires %ebx be live.  */
-  if (!TARGET_64BIT && flag_pic && (!decl || !targetm.binds_local_p (decl)))
+     as the PLT requires %ebx be live. (Darwin does not have a PLT.)  */
+  if (!TARGET_MACHO
+      && !TARGET_64BIT && flag_pic && (!decl || !targetm.binds_local_p (decl)))
     return false;
 
   /* If we need to align the outgoing stack, then sibcalling would
@@ -11478,8 +11479,25 @@  legitimate_constant_p (rtx x)
       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
 	  && SYMBOL_REF_DLLIMPORT_P (x))
 	return false;
+
+#if TARGET_MACHO
+      /* mdynamic-no-pic */
+      if (MACHO_DYNAMIC_NO_PIC_P)
+	return machopic_symbol_defined_p (x);
       break;
 
+    case PLUS:
+      {
+	rtx left = XEXP (x, 0);
+	rtx right = XEXP (x, 1);
+	bool left_is_constant = legitimate_constant_p (left);
+	bool right_is_constant = legitimate_constant_p (right);
+	return left_is_constant && right_is_constant;
+      }
+     /* mdynamic-no-pic */
+ #endif
+      break;
+
     case CONST_DOUBLE:
       if (GET_MODE (x) == TImode
 	  && x != CONST0_RTX (TImode)
@@ -11848,9 +11866,15 @@  ix86_legitimate_address_p (enum machine_mode mode
 		/* Non-constant pic memory reference.  */
 		return false;
 	    }
-	  else if (! legitimate_pic_address_disp_p (disp))
+	  else if ((!TARGET_MACHO || flag_pic)
+		    && ! legitimate_pic_address_disp_p (disp))
 	    /* Displacement is an invalid pic construct.  */
 	    return false;
+#if TARGET_MACHO
+	  else if (MACHO_DYNAMIC_NO_PIC_P && !legitimate_constant_p (disp))
+	    /* displacment must be referenced via non_lazy_pointer */
+	    return false;
+#endif
 
           /* This code used to verify that a symbolic pic displacement
 	     includes the pic_offset_table_rtx register.
@@ -12459,6 +12483,11 @@  ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE
   if (flag_pic && SYMBOLIC_CONST (x))
     return legitimize_pic_address (x, 0);
 
+#if TARGET_MACHO
+  if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
+    return machopic_indirect_data_reference (x, 0);
+#endif
+
   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   if (GET_CODE (x) == ASHIFT
       && CONST_INT_P (XEXP (x, 1))
@@ -13956,7 +13985,7 @@  ix86_print_operand (FILE *file, rtx x, int code)
 	}
       if (CONST_INT_P (x))
 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
-      else if (flag_pic)
+      else if (flag_pic || MACHOPIC_INDIRECT)
 	output_pic_addr_const (file, x, code);
       else
 	output_addr_const (file, x);
@@ -14937,25 +14966,43 @@  ix86_expand_move (enum machine_mode mode, rtx oper
 	}
     }
 
-  if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
+  if ((flag_pic || MACHOPIC_INDIRECT) 
+       && mode == Pmode && symbolic_operand (op1, Pmode))
     {
       if (TARGET_MACHO && !TARGET_64BIT)
 	{
 #if TARGET_MACHO
-	  if (MACHOPIC_PURE)
+	  /* dynamic-no-pic */
+	  if (MACHOPIC_INDIRECT)
 	    {
 	      rtx temp = ((reload_in_progress
 			   || ((op0 && REG_P (op0))
 			       && mode == Pmode))
 			  ? op0 : gen_reg_rtx (Pmode));
 	      op1 = machopic_indirect_data_reference (op1, temp);
-	      op1 = machopic_legitimize_pic_address (op1, mode,
-						     temp == op1 ? 0 : temp);
+	      if (MACHOPIC_PURE)
+		op1 = machopic_legitimize_pic_address (op1, mode,
+						       temp == op1 ? 0 : temp);
 	    }
-	  else if (MACHOPIC_INDIRECT)
-	    op1 = machopic_indirect_data_reference (op1, 0);
-	  if (op0 == op1)
+	  if (op0 != op1 && GET_CODE (op0) != MEM)
+	    {
+	      rtx insn = gen_rtx_SET (VOIDmode, op0, op1);
+	      emit_insn (insn);
+	      return;
+	    }
+	  if (GET_CODE (op0) == MEM)
+	    op1 = force_reg (Pmode, op1);
+	  else
+	    {
+	      rtx temp = op0;
+	      if (GET_CODE (temp) != REG)
+		temp = gen_reg_rtx (Pmode);
+	      temp = legitimize_pic_address (op1, temp);
+	      if (temp == op0)
 	    return;
+	      op1 = temp;
+	    }
+      /* dynamic-no-pic */
 #endif
 	}
       else
@@ -28218,36 +28265,81 @@  machopic_output_stub (FILE *file, const char *symb
 
   sprintf (lazy_ptr_name, "L%d$lz", label);
 
-  if (MACHOPIC_PURE)
+  if (MACHOPIC_ATT_STUB)
+    switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
+  else if (MACHOPIC_PURE)
+    {
+      if (TARGET_DEEP_BRANCH_PREDICTION)
+	switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
+      else
     switch_to_section (darwin_sections[machopic_picsymbol_stub_section]);
+    }
   else
     switch_to_section (darwin_sections[machopic_symbol_stub_section]);
 
   fprintf (file, "%s:\n", stub);
   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
 
-  if (MACHOPIC_PURE)
+  if (MACHOPIC_ATT_STUB)
     {
-      fprintf (file, "\tcall\tLPC$%d\nLPC$%d:\tpopl\t%%eax\n", label, label);
-      fprintf (file, "\tmovl\t%s-LPC$%d(%%eax),%%edx\n", lazy_ptr_name, label);
-      fprintf (file, "\tjmp\t*%%edx\n");
+      fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
     }
+  else if (MACHOPIC_PURE)
+    {
+      /* PIC stub.  */
+      if (TARGET_DEEP_BRANCH_PREDICTION)
+	{
+	  /* 25-byte PIC stub using "CALL get_pc_thunk".  */
+	  rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
+	  output_set_got (tmp, NULL_RTX);	/* "CALL ___<cpu>.get_pc_thunk.cx".  */
+	  fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n", label, lazy_ptr_name, label);
+	}
+      else
+	{
+	  /* 26-byte PIC stub using inline picbase: "CALL L42 ! L42: pop %eax".  */
+	  fprintf (file, "\tcall LPC$%d\nLPC$%d:\tpopl %%ecx\n", label, label);
+	  fprintf (file, "\tmovl %s-LPC$%d(%%ecx),%%ecx\n", lazy_ptr_name, label);
+	}
+      fprintf (file, "\tjmp\t*%%ecx\n");
+    }
   else
     fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
 
+  /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
+     it needs no stub-binding-helper.  */
+  if (MACHOPIC_ATT_STUB)
+    return;
+
   fprintf (file, "%s:\n", binder_name);
 
   if (MACHOPIC_PURE)
     {
-      fprintf (file, "\tlea\t%s-LPC$%d(%%eax),%%eax\n", lazy_ptr_name, label);
-      fputs ("\tpushl\t%eax\n", file);
+      fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
+      fprintf (file, "\tpushl\t%%ecx\n");
     }
   else
     fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
 
   fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
 
+  /* N.B. Keep the correspondence of these
+     'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
+     old-pic/new-pic/non-pic stubs; altering this will break
+     compatibility with existing dylibs.  */
+  if (MACHOPIC_PURE)
+    {
+      /* PIC stubs.  */
+      if (TARGET_DEEP_BRANCH_PREDICTION)
+	/* 25-byte PIC stub using "CALL get_pc_thunk".  */
+	switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
+      else
+	/* 26-byte PIC stub using inline picbase: "CALL L42 ! L42: pop %ebx".  */
   switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
+    }
+  else
+    /* 16-byte -mdynamic-no-pic stub.  */
+    switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
+
   fprintf (file, "%s:\n", lazy_ptr_name);
   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   fprintf (file, ASM_LONG "%s\n", binder_name);
Index: gcc/config/darwin-protos.h
===================================================================
--- gcc/config/darwin-protos.h	(revision 166105)
+++ gcc/config/darwin-protos.h	(working copy)
@@ -1,5 +1,5 @@ 
 /* Prototypes.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -31,6 +31,7 @@  extern const char *machopic_mcount_stub_name (void
 
 extern rtx machopic_gen_offset (rtx);
 extern int machopic_operand_p (rtx);
+extern int machopic_symbol_defined_p (rtx sym_ref);
 extern enum machopic_addr_class machopic_classify_symbol (rtx);
 
 extern rtx machopic_indirect_data_reference (rtx, rtx);
Index: gcc/config/rs6000/darwin.opt
===================================================================
--- gcc/config/rs6000/darwin.opt	(revision 166105)
+++ gcc/config/rs6000/darwin.opt	(working copy)
@@ -1,6 +1,6 @@ 
 ; Darwin options for PPC port.
 ;
-; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2007, 2010 Free Software Foundation, Inc.
 ; Contributed by Aldy Hernandez <aldy@quesejoda.com>.
 ;
 ; This file is part of GCC.
@@ -26,7 +26,3 @@  Generate 64-bit code
 m32
 Target RejectNegative Negative(m64) InverseMask(64BIT)
 Generate 32-bit code
-
-mdynamic-no-pic
-Target Report Mask(MACHO_DYNAMIC_NO_PIC)
-Generate code suitable for executables (NOT shared libs)
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h	(revision 166105)
+++ gcc/config/rs6000/darwin.h	(working copy)
@@ -1,5 +1,5 @@ 
 /* Target definitions for PowerPC running Darwin (Mac OS X).
-   Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2010
    Free Software Foundation, Inc.
    Contributed by Apple Computer Inc.
 
@@ -19,6 +19,9 @@ 
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#undef DARWIN_PPC
+#define DARWIN_PPC 1
+
 #undef  TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (Darwin/PowerPC)");
 
@@ -51,9 +54,6 @@ 
 #undef  PTRDIFF_TYPE
 #define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
 
-/* Translate config/rs6000/darwin.opt to config/darwin.h.  */
-#define TARGET_DYNAMIC_NO_PIC (TARGET_MACHO_DYNAMIC_NO_PIC)
-
 #define TARGET_OS_CPP_BUILTINS()			\
   do							\
     {							\
@@ -184,11 +184,6 @@  extern int darwin_emit_branch_islands;
   (RS6000_ALIGN (crtl->outgoing_args_size, 16)		\
    + (STACK_POINTER_OFFSET))
 
-/* These are used by -fbranch-probabilities */
-#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
-#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
-                              "__TEXT,__unlikely,regular,pure_instructions"
-
 /* Define cutoff for using external functions to save floating point.
    Currently on Darwin, always use inline stores.  */
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 166105)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2366,21 +2366,11 @@  darwin_rs6000_override_options (void)
      off.  */
   rs6000_altivec_abi = 1;
   TARGET_ALTIVEC_VRSAVE = 1;
-  if (DEFAULT_ABI == ABI_DARWIN)
-  {
-    if (MACHO_DYNAMIC_NO_PIC_P)
-      {
-        if (flag_pic)
-            warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
-        flag_pic = 0;
-      }
-    else if (flag_pic == 1)
-      {
-        flag_pic = 2;
-      }
-    if (TARGET_64BIT)
+
+  if (DEFAULT_ABI == ABI_DARWIN
+      && TARGET_64BIT)
       darwin_one_byte_bool = 1;
-  }
+
   if (TARGET_64BIT && ! TARGET_POWERPC64)
     {
       target_flags |= MASK_POWERPC64;
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	(revision 166105)
+++ gcc/config/darwin.c	(working copy)
@@ -95,6 +95,13 @@  int darwin_running_cxx;
 /* Section names.  */
 section * darwin_sections[NUM_DARWIN_SECTIONS];
 
+/* While we transition to using in-tests instead of ifdef'd code.  */
+#ifndef HAVE_lo_sum
+#define HAVE_lo_sum 0
+#define gen_macho_high(a,b) (a)
+#define gen_macho_low(a,b,c) (a)
+#endif
+
 /* True if we're setting __attribute__ ((ms_struct)).  */
 int darwin_ms_struct = false;
 
@@ -179,7 +186,7 @@  name_needs_quotes (const char *name)
 }
 
 /* Return true if SYM_REF can be used without an indirection.  */
-static int
+int
 machopic_symbol_defined_p (rtx sym_ref)
 {
   if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
@@ -319,12 +326,22 @@  machopic_output_function_base_name (FILE *file)
 
   /* If dynamic-no-pic is on, we should not get here.  */
   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
-  current_name =
-    IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
-  if (function_base_func_name != current_name)
+  /* When we are generating _get_pc thunks within stubs, there is no current
+     function.  */
+  if (current_function_decl)
     {
+      current_name =
+	IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+      if (function_base_func_name != current_name)
+	{
+	  ++current_pic_label_num;
+	  function_base_func_name = current_name;
+	}
+    }
+  else
+    {
       ++current_pic_label_num;
-      function_base_func_name = current_name;
+      function_base_func_name = "L_machopic_stub_dummy";
     }
   fprintf (file, "L%011d$pb", current_pic_label_num);
 }
@@ -514,24 +531,28 @@  machopic_indirect_data_reference (rtx orig, rtx re
 
       if (defined && MACHO_DYNAMIC_NO_PIC_P)
 	{
-#if defined (TARGET_TOC)
+	  if (DARWIN_PPC)
+	    {
 	  /* Create a new register for CSE opportunities.  */
 	  rtx hi_reg = (!can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode));
  	  emit_insn (gen_macho_high (hi_reg, orig));
  	  emit_insn (gen_macho_low (reg, hi_reg, orig));
-#else
+	      return reg;
+ 	    }
+	  else if (DARWIN_X86)
+	    return orig;
+	  else
 	   /* some other cpu -- writeme!  */
 	   gcc_unreachable ();
-#endif
-	   return reg;
 	}
       else if (defined)
 	{
-#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
-	  rtx offset = machopic_gen_offset (orig);
-#endif
+	  rtx offset = NULL;
+	  if (DARWIN_PPC || HAVE_lo_sum)
+	    offset = machopic_gen_offset (orig);
 
-#if defined (TARGET_TOC) /* i.e., PowerPC */
+	  if (DARWIN_PPC)
+	    {
 	  rtx hi_sum_reg = (!can_create_pseudo_p ()
 			    ? reg
 			    : gen_reg_rtx (Pmode));
@@ -546,8 +567,9 @@  machopic_indirect_data_reference (rtx orig, rtx re
 						  copy_rtx (offset))));
 
 	  orig = reg;
-#else
-#if defined (HAVE_lo_sum)
+	    }
+	  else if (HAVE_lo_sum)
+	    {
 	  gcc_assert (reg);
 
 	  emit_insn (gen_rtx_SET (VOIDmode, reg,
@@ -558,8 +580,7 @@  machopic_indirect_data_reference (rtx orig, rtx re
 	  emit_use (pic_offset_table_rtx);
 
 	  orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
-#endif
-#endif
+	    }
 	  return orig;
 	}
 
@@ -572,24 +593,56 @@  machopic_indirect_data_reference (rtx orig, rtx re
       ptr_ref = gen_const_mem (Pmode, ptr_ref);
       machopic_define_symbol (ptr_ref);
 
+      if (DARWIN_X86 
+          && reg 
+          && MACHO_DYNAMIC_NO_PIC_P)
+	{
+	    emit_insn (gen_rtx_SET (Pmode, reg, ptr_ref));
+	    ptr_ref = reg;
+	}
+
       return ptr_ref;
     }
   else if (GET_CODE (orig) == CONST)
     {
+      /* If "(const (plus ...", walk the PLUS and return that result.
+	 PLUS processing (below) will restore the "(const ..." if
+	 appropriate.  */
+      if (GET_CODE (XEXP (orig, 0)) == PLUS)
+	return machopic_indirect_data_reference (XEXP (orig, 0), reg);
+      else 
+	return orig;
+    }
+  else if (GET_CODE (orig) == MEM)
+    {
+      XEXP (ptr_ref, 0) = 
+		machopic_indirect_data_reference (XEXP (orig, 0), reg);
+      return ptr_ref;
+    }
+  else if (GET_CODE (orig) == PLUS)
+    {
       rtx base, result;
-
-      /* legitimize both operands of the PLUS */
-      if (GET_CODE (XEXP (orig, 0)) == PLUS)
+      /* When the target is i386, this code prevents crashes due to the
+	compiler's ignorance on how to move the PIC base register to
+	other registers.  (The reload phase sometimes introduces such
+	insns.)  */
+      if (GET_CODE (XEXP (orig, 0)) == REG
+	   && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
+	   /* Prevent the same register from being erroneously used
+	      as both the base and index registers.  */
+	   && (DARWIN_X86 && (GET_CODE (XEXP (orig, 1)) == CONST))
+	   && reg)
 	{
-	  base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
-						   reg);
-	  orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
-						   (base == reg ? 0 : reg));
+	  emit_move_insn (reg, XEXP (orig, 0));
+	  XEXP (ptr_ref, 0) = reg;
+	  return ptr_ref;
 	}
-      else
-	return orig;
 
-      if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
+      /* Legitimize both operands of the PLUS.  */
+      base = machopic_indirect_data_reference (XEXP (orig, 0), reg);
+      orig = machopic_indirect_data_reference (XEXP (orig, 1),
+					       (base == reg ? 0 : reg));
+      if (MACHOPIC_INDIRECT && (GET_CODE (orig) == CONST_INT))
 	result = plus_constant (base, INTVAL (orig));
       else
 	result = gen_rtx_PLUS (Pmode, base, orig);
@@ -608,27 +661,7 @@  machopic_indirect_data_reference (rtx orig, rtx re
 	}
 
       return result;
-
     }
-  else if (GET_CODE (orig) == MEM)
-    XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
-  /* When the target is i386, this code prevents crashes due to the
-     compiler's ignorance on how to move the PIC base register to
-     other registers.  (The reload phase sometimes introduces such
-     insns.)  */
-  else if (GET_CODE (orig) == PLUS
-	   && GET_CODE (XEXP (orig, 0)) == REG
-	   && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
-#ifdef I386
-	   /* Prevent the same register from being erroneously used
-	      as both the base and index registers.  */
-	   && GET_CODE (XEXP (orig, 1)) == CONST
-#endif
-	   && reg)
-    {
-      emit_move_insn (reg, XEXP (orig, 0));
-      XEXP (ptr_ref, 0) = reg;
-    }
   return ptr_ref;
 }
 
@@ -697,7 +730,7 @@  machopic_legitimize_pic_address (rtx orig, enum ma
 	      reg = gen_reg_rtx (Pmode);
 	    }
 
-#ifdef HAVE_lo_sum
+#if HAVE_lo_sum
 	  if (MACHO_DYNAMIC_NO_PIC_P
 	      && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
 		  || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
@@ -792,7 +825,7 @@  machopic_legitimize_pic_address (rtx orig, enum ma
       else
 	{
 
-#ifdef HAVE_lo_sum
+#if HAVE_lo_sum
 	  if (GET_CODE (orig) == SYMBOL_REF
 	      || GET_CODE (orig) == LABEL_REF)
 	    {
@@ -1915,6 +1948,18 @@  darwin_override_options (void)
       && debug_hooks->var_location != do_nothing_debug_hooks.var_location)
     flag_var_tracking_uninit = 1;
 
+  if (MACHO_DYNAMIC_NO_PIC_P)
+    {
+      if (flag_pic)
+	warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
+      flag_pic = 0;
+    }
+  else if (flag_pic == 1)
+    {
+      /* Darwin's -fpic is -fPIC.  */
+      flag_pic = 2;
+    }
+
   /* It is assumed that branch island stubs are needed for earlier systems.  */
   if (darwin_macosx_version_min
       && strverscmp (darwin_macosx_version_min, "10.5") < 0)
Index: gcc/config/darwin-sections.def
===================================================================
--- gcc/config/darwin-sections.def	(revision 166105)
+++ gcc/config/darwin-sections.def	(working copy)
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -66,17 +66,30 @@  DEF_SECTION (objc_class_names_section, 0, ".objc_c
 DEF_SECTION (objc_meth_var_names_section, 0, ".objc_meth_var_names", 1)
 DEF_SECTION (objc_meth_var_types_section, 0, ".objc_meth_var_types", 1)
 DEF_SECTION (objc_cls_refs_section, SECTION_MERGE, ".objc_cls_refs", 1)
-
+/* lazy symbol pointers.  */
 DEF_SECTION (machopic_lazy_symbol_ptr_section, 0, ".lazy_symbol_pointer", 0)
-DEF_SECTION (machopic_nl_symbol_ptr_section, 0, ".non_lazy_symbol_pointer", 0)
+DEF_SECTION (machopic_lazy_symbol_ptr2_section,	0,
+	     ".section __DATA, __la_sym_ptr2,lazy_symbol_pointers", 0)
+DEF_SECTION (machopic_lazy_symbol_ptr3_section, 0,
+	     ".section __DATA, __la_sym_ptr3,lazy_symbol_pointers", 0)
+/* non-lazy symbol pointers.  */
+DEF_SECTION (machopic_nl_symbol_ptr_section, 0,
+	     MACHOPIC_NL_SYMBOL_PTR_SECTION, 0)
+/* Symbol stubs.  */
 DEF_SECTION (machopic_symbol_stub_section, 0, ".symbol_stub", 0)
 DEF_SECTION (machopic_symbol_stub1_section, 0,
 	     ".section __TEXT,__symbol_stub1,symbol_stubs,"
 	     "pure_instructions,16", 0)
+/* PIC symbol stubs.  */
 DEF_SECTION (machopic_picsymbol_stub_section, 0, ".picsymbol_stub", 0)
 DEF_SECTION (machopic_picsymbol_stub1_section, 0,
 	     ".section __TEXT,__picsymbolstub1,symbol_stubs,"
 	     "pure_instructions,32", 0)
+DEF_SECTION (machopic_picsymbol_stub2_section, 0,
+	     ".section __TEXT,__picsymbolstub2,symbol_stubs,pure_instructions,25", 0)
+DEF_SECTION (machopic_picsymbol_stub3_section, 0,
+	     ".section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5", 0)
+/* Exception-related.  */
 DEF_SECTION (darwin_exception_section, 0,
 	     ".section __DATA,__gcc_except_tab", 0)
 DEF_SECTION (darwin_eh_frame_section, 0,
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	(revision 166105)
+++ gcc/config/darwin.h	(working copy)
@@ -42,7 +42,8 @@  see the files COPYING3 and COPYING.RUNTIME respect
    like a.out and partly like COFF, with additional features like
    multi-architecture binary support.  */
 
-#define OBJECT_FORMAT_MACHO
+#define DARWIN_X86 0
+#define DARWIN_PPC 0
 
 /* Don't assume anything about the header files.  */
 #define NO_IMPLICIT_EXTERN_C
@@ -752,6 +753,14 @@  int darwin_label_is_anonymous_local_objc_name (con
 #undef	MAX_OFILE_ALIGNMENT
 #define MAX_OFILE_ALIGNMENT (0x8000 * 8)
 
+/* The generic version, archs should over-ride where required.  */
+#define MACHOPIC_NL_SYMBOL_PTR_SECTION ".non_lazy_symbol_pointer"
+
+/* These are used by -fbranch-probabilities */
+#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
+#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
+                              "__TEXT,__unlikely,regular,pure_instructions"
+
 /* Declare the section variables.  */
 #ifndef USED_FOR_TARGET
 enum darwin_section_enum {
@@ -852,9 +861,12 @@  enum machopic_addr_class {
 
 /* Macros defining the various PIC cases.  */
 
-#define MACHO_DYNAMIC_NO_PIC_P	(TARGET_DYNAMIC_NO_PIC)
+#undef  MACHO_DYNAMIC_NO_PIC_P
+#define MACHO_DYNAMIC_NO_PIC_P	(TARGET_MACHO_DYNAMIC_NO_PIC)
+#undef  MACHOPIC_INDIRECT
 #define MACHOPIC_INDIRECT	(flag_pic || MACHO_DYNAMIC_NO_PIC_P)
 #define MACHOPIC_JUST_INDIRECT	(MACHO_DYNAMIC_NO_PIC_P)
+#undef  MACHOPIC_PURE
 #define MACHOPIC_PURE		(flag_pic && ! MACHO_DYNAMIC_NO_PIC_P)
 
 #undef TARGET_ENCODE_SECTION_INFO