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>"));
-
- current_function_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;
static int
machopic_indirection_eq (const void *slot, const void *key)
{
- return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
+ return strcmp (((const machopic_indirection *) slot)->ptr_name,
+ (const char *) key) == 0;
}
/* Return the name of the non-lazy pointer (if STUB_P is false) or
else
suffix = NON_LAZY_POINTER_SUFFIX;
- buffer = alloca (strlen ("&L")
+ buffer = XALLOCAVEC (char, strlen ("&L")
+ strlen (prefix)
+ namelen
+ strlen (suffix)
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 */
emit_insn (gen_rtx_SET (VOIDmode, reg,
gen_rtx_LO_SUM (Pmode, reg,
copy_rtx (offset))));
- emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
+ emit_use (pic_offset_table_rtx);
orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
#endif
))
{
/* addr(foo) = &func+(foo-func) */
- rtx pic_base;
-
orig = machopic_indirect_data_reference (orig, reg);
if (GET_CODE (orig) == PLUS
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)
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. */
pic_ref = reg;
#else
- emit_insn (gen_rtx_USE (VOIDmode,
- gen_rtx_REG (Pmode,
- PIC_OFFSET_TABLE_REGNUM)));
+ emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
emit_insn (gen_rtx_SET (VOIDmode, reg,
gen_rtx_HIGH (Pmode,
pic = reg;
}
#if 0
- emit_insn (gen_rtx_USE (VOIDmode,
- gen_rtx_REG (Pmode,
- PIC_OFFSET_TABLE_REGNUM)));
+ emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
#endif
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)
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;
pic = reg;
}
#if 0
- emit_insn (gen_rtx_USE (VOIDmode,
- pic_offset_table_rtx));
+ emit_use (pic_offset_table_rtx);
#endif
if (reload_in_progress)
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));
}
}
}
sym_name = IDENTIFIER_POINTER (id);
}
- sym = alloca (strlen (sym_name) + 2);
+ sym = XALLOCAVEC (char, strlen (sym_name) + 2);
if (sym_name[0] == '*' || sym_name[0] == '&')
strcpy (sym, sym_name + 1);
else if (sym_name[0] == '-' || sym_name[0] == '+')
else
sprintf (sym, "%s%s", user_label_prefix, sym_name);
- stub = alloca (strlen (ptr_name) + 2);
+ stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
if (ptr_name[0] == '*' || ptr_name[0] == '&')
strcpy (stub, ptr_name + 1);
else
rtx init = const0_rtx;
switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
+
+ /* Mach-O symbols are passed around in code through indirect
+ references and the original symbol_ref hasn't passed through
+ the generic handling and reference-catching in
+ output_operand, so we need to manually mark weak references
+ as such. */
+ if (SYMBOL_REF_WEAK (symbol))
+ {
+ tree decl = SYMBOL_REF_DECL (symbol);
+ gcc_assert (DECL_P (decl));
+
+ if (decl != NULL_TREE
+ && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
+ /* Handle only actual external-only definitions, not
+ e.g. extern inline code or variables for which
+ storage has been allocated. */
+ && !TREE_STATIC (decl))
+ {
+ fputs ("\t.weak_reference ", asm_out_file);
+ assemble_name (asm_out_file, sym_name);
+ fputc ('\n', asm_out_file);
+ }
+ }
+
assemble_name (asm_out_file, ptr_name);
fprintf (asm_out_file, ":\n");
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
flag_var_tracking_uninit = 1;
}
+/* Add $LDBL128 suffix to long double builtins. */
+
+static void
+darwin_patch_builtin (int fncode)
+{
+ tree fn = built_in_decls[fncode];
+ tree sym;
+ char *newname;
+
+ if (!fn)
+ return;
+
+ sym = DECL_ASSEMBLER_NAME (fn);
+ newname = ACONCAT (("_", IDENTIFIER_POINTER (sym), "$LDBL128", NULL));
+
+ set_user_assembler_name (fn, newname);
+
+ fn = implicit_built_in_decls[fncode];
+ if (fn)
+ set_user_assembler_name (fn, newname);
+}
+
+void
+darwin_patch_builtins (void)
+{
+ if (LONG_DOUBLE_TYPE_SIZE != 128)
+ return;
+
+#define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
+#define PATCH_BUILTIN_NO64(fncode) \
+ if (!TARGET_64BIT) \
+ darwin_patch_builtin (fncode);
+#define PATCH_BUILTIN_VARIADIC(fncode) \
+ if (!TARGET_64BIT \
+ && (strverscmp (darwin_macosx_version_min, "10.3.9") >= 0)) \
+ darwin_patch_builtin (fncode);
+#include "darwin-ppc-ldouble-patch.def"
+#undef PATCH_BUILTIN
+#undef PATCH_BUILTIN_NO64
+#undef PATCH_BUILTIN_VARIADIC
+}
+
+
#include "gt-darwin.h"