From 7d0720375952abd2c48d95f4cf752eff7d732e48 Mon Sep 17 00:00:00 2001
From: Stuart Hastings <stuart@apple.com>
Date: Tue, 10 Jan 2006 23:56:12 +0000
Subject: [PATCH] i386.md (set_got): Update.

	* gcc/config/i386/i386.md (set_got): Update.
	(set_got_labelled): New.  (UNSPEC_LD_MPIC): New.
	(builtin_setjmp_receiver): Mach-O support.
	* gcc/config/i386/darwin.h (TARGET_ASM_FILE_END) Define.
	(GOT_SYMBOL_NAME): Define.
	(FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): New.
	(TARGET_DEEP_BRANCH_PREDICTION): Remove.
	* gcc/config/i386/i386.c (override_options): Revise for Darwin.
	(USE_HIDDEN_LINKONCE): Enable for Mach-O.  (ix86_file_end): Mach-O
	support.  (darwin_x86_file_end): New.  (output_set_got): Add label
	parameter, revise for Mach-O.  (x86_output_mi_thunk): Likewise.
	* gcc/config/i386/i386-protos.h (output_set_got): Likewise.
	* gcc/config/darwin.c (machopic_legitimize_pic_address): Update
	regs_ever_live[].

From-SVN: r109556
---
 gcc/ChangeLog                 | 17 ++++++++++++
 gcc/config/darwin.c           |  4 +++
 gcc/config/i386/darwin.h      | 15 ++++++----
 gcc/config/i386/i386-protos.h |  2 +-
 gcc/config/i386/i386.c        | 52 +++++++++++++++++++++++++++--------
 gcc/config/i386/i386.md       | 30 ++++++++++++++++++--
 6 files changed, 101 insertions(+), 19 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 97ee993314d0..b74c09f64b7e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2006-01-10  Stuart Hastings  <stuart@apple.com>
+
+	* gcc/config/i386/i386.md (set_got): Update.
+	(set_got_labelled): New.  (UNSPEC_LD_MPIC): New.
+	(builtin_setjmp_receiver): Mach-O support.
+	* gcc/config/i386/darwin.h (TARGET_ASM_FILE_END) Define.
+	(GOT_SYMBOL_NAME): Define.
+	(FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): New.
+	(TARGET_DEEP_BRANCH_PREDICTION): Remove.
+	* gcc/config/i386/i386.c (override_options): Revise for Darwin.
+	(USE_HIDDEN_LINKONCE): Enable for Mach-O.  (ix86_file_end): Mach-O
+	support.  (darwin_x86_file_end): New.  (output_set_got): Add label
+	parameter, revise for Mach-O.  (x86_output_mi_thunk): Likewise.
+	* gcc/config/i386/i386-protos.h (output_set_got): Likewise.
+	* gcc/config/darwin.c (machopic_legitimize_pic_address): Update
+	regs_ever_live[].
+
 2006-01-10  Kaz Kojima  <kkojima@gcc.gnu.org>
 
 	* config/sh/sh.h (SH5_WOULD_BE_PARTIAL_NREGS): Use GET_MODE_SIZE
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 920c4784452c..8920d62095c0 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -773,6 +773,8 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
 						   PIC_OFFSET_TABLE_REGNUM)));
 #endif
 
+	      if (reload_in_progress)
+		regs_ever_live[REGNO (pic)] = 1;
 	      pic_ref = gen_rtx_PLUS (Pmode, pic,
 				      gen_pic_offset (XEXP (orig, 0),
 						      pic_base));
@@ -842,6 +844,8 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
 		  emit_insn (gen_rtx_USE (VOIDmode,
 					  pic_offset_table_rtx));
 #endif
+		  if (reload_in_progress)
+		    regs_ever_live[REGNO (pic)] = 1;
 		  pic_ref = gen_rtx_PLUS (Pmode,
 					  pic,
 					  gen_pic_offset (orig, pic_base));
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index b42ed3cdd895..73e080f068aa 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -37,6 +37,9 @@ Boston, MA 02110-1301, USA.  */
     }                                           \
   while (0)
 
+#undef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN (0)
+
 /* We want -fPIC by default, unless we're using -static to compile for
    the kernel or some such.  */
 
@@ -69,6 +72,10 @@ Boston, MA 02110-1301, USA.  */
 
 #define SHIFT_DOUBLE_OMITS_COUNT 0
 
+extern void darwin_x86_file_end (void);
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END darwin_x86_file_end
+
 /* Define the syntax of pseudo-ops, labels and comments.  */
 
 /* String containing the assembler's comment-starter.  */
@@ -80,16 +87,14 @@ Boston, MA 02110-1301, USA.  */
 
 #define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_128BIT_LONG_DOUBLE | MASK_ALIGN_DOUBLE)
 
-/* TARGET_DEEP_BRANCH_PREDICTION is incompatible with Mach-O PIC.  */
-
-#undef TARGET_DEEP_BRANCH_PREDICTION
-#define TARGET_DEEP_BRANCH_PREDICTION   0
-
 /* 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 ())
+
 /* Define the syntax of pseudo-ops, labels and comments.  */
 
 #define LPREFIX "L"
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index df2ba4e88417..188c9677b77d 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -67,7 +67,7 @@ extern bool output_addr_const_extra (FILE*, rtx);
 extern void split_di (rtx[], int, rtx[], rtx[]);
 extern void split_ti (rtx[], int, rtx[], rtx[]);
 
-extern const char *output_set_got (rtx);
+extern const char *output_set_got (rtx, rtx);
 extern const char *output_387_binary_op (rtx, rtx*);
 extern const char *output_387_reg_move (rtx, rtx*);
 extern const char *output_fix_trunc (rtx, rtx*, int);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e48e288cbc8e..5cececebcce4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1589,9 +1589,8 @@ override_options (void)
      The default of 128 bits is for Pentium III's SSE __m128, but we
      don't want additional code to keep the stack aligned when
      optimizing for code size.  */
-  ix86_preferred_stack_boundary = (optimize_size
-				   ? TARGET_64BIT ? 128 : 32
-				   : 128);
+  ix86_preferred_stack_boundary = ((TARGET_64BIT || TARGET_MACHO || !optimize_size)
+				   ? 128 : 32);
   if (ix86_preferred_stack_boundary_string)
     {
       i = atoi (ix86_preferred_stack_boundary_string);
@@ -4431,7 +4430,7 @@ ix86_setup_frame_addresses (void)
   cfun->machine->accesses_prev_frame = 1;
 }
 
-#if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
+#if (defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)) || TARGET_MACHO
 # define USE_HIDDEN_LINKONCE 1
 #else
 # define USE_HIDDEN_LINKONCE 0
@@ -4470,6 +4469,19 @@ ix86_file_end (void)
 
       get_pc_thunk_name (name, regno);
 
+#if TARGET_MACHO
+      if (TARGET_MACHO)
+	{
+	  switch_to_section (darwin_sections[text_coal_section]);
+	  fputs ("\t.weak_definition\t", asm_out_file);
+	  assemble_name (asm_out_file, name);
+	  fputs ("\n\t.private_extern\t", asm_out_file);
+	  assemble_name (asm_out_file, name);
+	  fputs ("\n", asm_out_file);
+	  ASM_OUTPUT_LABEL (asm_out_file, name);
+	}
+      else
+#endif
       if (USE_HIDDEN_LINKONCE)
 	{
 	  tree decl;
@@ -4508,7 +4520,7 @@ ix86_file_end (void)
 /* Emit code for the SET_GOT patterns.  */
 
 const char *
-output_set_got (rtx dest)
+output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
 {
   rtx xops[3];
 
@@ -4517,7 +4529,7 @@ output_set_got (rtx dest)
 
   if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
     {
-      xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
+      xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
 
       if (!flag_pic)
 	output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
@@ -4525,10 +4537,12 @@ output_set_got (rtx dest)
 	output_asm_insn ("call\t%a2", xops);
 
 #if TARGET_MACHO
-      /* Output the "canonical" label name ("Lxx$pb") here too.  This
-         is what will be referred to by the Mach-O PIC subsystem.  */
-      ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+      /* 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 ());
 #endif
+
       (*targetm.asm_out.internal_label) (asm_out_file, "L",
 				 CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
 
@@ -4544,11 +4558,20 @@ output_set_got (rtx dest)
       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
       xops[2] = gen_rtx_MEM (QImode, xops[2]);
       output_asm_insn ("call\t%X2", xops);
+      /* Output the Mach-O "canonical" label name ("Lxx$pb") here too.  This
+         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 ());
+#endif
     }
 
+  if (TARGET_MACHO)
+    return "";
+
   if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
     output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
-  else if (!TARGET_MACHO)
+  else
     output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops);
 
   return "";
@@ -16708,6 +16731,13 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub)
   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   fprintf (file, "\t.long %s\n", binder_name);
 }
+
+void
+darwin_x86_file_end (void)
+{
+  darwin_file_end ();
+  ix86_file_end ();
+}
 #endif /* TARGET_MACHO */
 
 /* Order the registers for register allocator.  */
@@ -16996,7 +17026,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
 #endif /* TARGET_MACHO */
 	{
 	  tmp = gen_rtx_REG (SImode, 2 /* ECX */);
-	  output_set_got (tmp);
+	  output_set_got (tmp, NULL_RTX);
 
 	  xops[1] = tmp;
 	  output_asm_insn ("mov{l}\t{%0@GOT(%1), %1|%1, %0@GOT[%1]}", xops);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f15ecdde4389..99b3acf537a2 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -83,6 +83,7 @@
    (UNSPEC_FLDCW		25)
    (UNSPEC_REP			26)
    (UNSPEC_EH_RETURN		27)
+   (UNSPEC_LD_MPIC		28)	; load_macho_picbase
 
    ; For SSE/MMX support:
    (UNSPEC_FIX_NOTRUNC		30)
@@ -13859,7 +13860,17 @@
 	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT"
-  { return output_set_got (operands[0]); }
+  { return output_set_got (operands[0], NULL_RTX); }
+  [(set_attr "type" "multi")
+   (set_attr "length" "12")])
+
+(define_insn "set_got_labelled"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(label_ref (match_operand 1 "" ""))]
+	 UNSPEC_SET_GOT))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_64BIT"
+  { return output_set_got (operands[0], operands[1]); }
   [(set_attr "type" "multi")
    (set_attr "length" "12")])
 
@@ -18801,7 +18812,22 @@
   [(label_ref (match_operand 0 "" ""))]
   "!TARGET_64BIT && flag_pic"
 {
-  emit_insn (gen_set_got (pic_offset_table_rtx));
+  if (TARGET_MACHO)
+    {
+      rtx xops[3];
+      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
+      rtx label_rtx = gen_label_rtx ();
+      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
+      emit_label (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)));
+      ix86_expand_binary_operator (MINUS, SImode, xops);
+    }
+  else
+    emit_insn (gen_set_got (pic_offset_table_rtx));
   DONE;
 })
 
-- 
GitLab