/* Functions for generic Darwin as target machine for GNU C compiler.
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004,
+ 2005
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
return 0;
}
-/*
- * flag_pic = 1 ... generate only indirections
- * flag_pic = 2 ... generate indirections and pure code
- */
-
+/* Return true if SYM_REF can be used without an indirection. */
static int
machopic_symbol_defined_p (rtx sym_ref)
{
- return (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
- || (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref));
+ if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
+ return true;
+
+ /* If a symbol references local and is not an extern to this
+ file, then the symbol might be able to declared as defined. */
+ if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
+ {
+ /* If the symbol references a variable and the variable is a
+ common symbol, then this symbol is not defined. */
+ if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
+ {
+ tree decl = SYMBOL_REF_DECL (sym_ref);
+ if (!decl)
+ return true;
+ if (DECL_COMMON (decl))
+ return false;
+ }
+ return true;
+ }
+ return false;
}
/* This module assumes that (const (symbol_ref "foo")) is a legal pic
/* Indicate when fix-and-continue style code generation is being used
and when a reference to data should be indirected so that it can be
- rebound in a new translation unit to refernce the original instance
+ rebound in a new translation unit to reference the original instance
of that data. Symbol names that are for code generation local to
the translation unit are bound to the new translation unit;
currently this means symbols that begin with L or _OBJC_;
switch (machopic_classify_symbol (sym_ref))
{
case MACHOPIC_DEFINED_DATA:
+ case MACHOPIC_DEFINED_FUNCTION:
return 1;
default:
return 0;
if (defined && MACHO_DYNAMIC_NO_PIC_P)
{
#if defined (TARGET_TOC)
- emit_insn (GET_MODE (orig) == DImode
- ? gen_macho_high_di (reg, orig)
- : gen_macho_high (reg, orig));
- emit_insn (GET_MODE (orig) == DImode
- ? gen_macho_low_di (reg, reg, orig)
- : gen_macho_low (reg, reg, orig));
+ emit_insn (gen_macho_high (reg, orig));
+ emit_insn (gen_macho_low (reg, reg, orig));
#else
/* some other cpu -- writeme! */
abort ();
rtx asym = XEXP (orig, 0);
rtx mem;
- emit_insn (mode == DImode
- ? gen_macho_high_di (temp_reg, asym)
- : gen_macho_high (temp_reg, asym));
+ emit_insn (gen_macho_high (temp_reg, asym));
mem = gen_const_mem (GET_MODE (orig),
gen_rtx_LO_SUM (Pmode, temp_reg, asym));
emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
else
#endif /* HAVE_lo_sum */
{
- if (GET_CODE (orig) == REG)
+ if (REG_P (orig)
+ || GET_CODE (orig) == SUBREG)
{
return orig;
}
else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
&& flag_merge_constants)
{
- tree size = TYPE_SIZE (TREE_TYPE (exp));
+ tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
if (TREE_CODE (size) == INTEGER_CST &&
TREE_INT_CST_LOW (size) == 4 &&
/* Darwin does not use unique sections. */
}
-#define HAVE_DEAD_STRIP 0
+/* Handle a "weak_import" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+tree
+darwin_handle_weak_import_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool * no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
+ {
+ warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+ else
+ declare_weak (*node);
+
+ return NULL_TREE;
+}
static void
no_dead_strip (FILE *file, const char *lab)
{
- if (HAVE_DEAD_STRIP)
- fprintf (file, ".no_dead_strip %s\n", lab);
+ fprintf (file, ".no_dead_strip %s\n", lab);
}
/* Emit a label for an FDE, making it global and/or weak if appropriate.
fputs ("\n", asm_out_file);
}
else
- warning ("internal and protected visibility attributes not supported"
+ warning ("internal and protected visibility attributes not supported "
"in this configuration; ignored");
}
static int darwin_dwarf_label_counter;
void
-darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
+darwin_asm_output_dwarf_delta (FILE *file, int size,
const char *lab1, const char *lab2)
{
int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
&& lab2[0] == '*' && lab2[1] == 'L');
+ const char *directive = (size == 8 ? ".quad" : ".long");
if (islocaldiff)
fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
else
- fprintf (file, "\t%s\t", ".long");
- assemble_name (file, lab1);
+ fprintf (file, "\t%s\t", directive);
+ assemble_name_raw (file, lab1);
fprintf (file, "-");
- assemble_name (file, lab2);
+ assemble_name_raw (file, lab2);
if (islocaldiff)
- fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
+ fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
}
void