aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r--gcc/config/i386/i386.c288
1 files changed, 271 insertions, 17 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index bc680c80df9..ea20c6b901c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -49,6 +49,11 @@ Boston, MA 02111-1307, USA. */
#include "cgraph.h"
#include "tree-gimple.h"
+/* APPLE LOCAL begin pascal strings */
+#include "../../libcpp/internal.h"
+extern struct cpp_reader* parse_in;
+/* APPLE LOCAL end pascal strings */
+
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT (-1)
#endif
@@ -505,6 +510,34 @@ struct processor_costs nocona_cost = {
const struct processor_costs *ix86_cost = &pentium_cost;
+/* APPLE LOCAL begin Altivec */
+/* vector types */
+static GTY(()) tree unsigned_V16QI_type_node;
+static GTY(()) tree unsigned_V4SI_type_node;
+static GTY(()) tree unsigned_V8QI_type_node;
+static GTY(()) tree unsigned_V8HI_type_node;
+static GTY(()) tree unsigned_V4HI_type_node;
+static GTY(()) tree unsigned_V2HI_type_node;
+static GTY(()) tree unsigned_V2SI_type_node;
+static GTY(()) tree unsigned_V2DI_type_node;
+static GTY(()) tree unsigned_V1DI_type_node;
+
+static GTY(()) tree V16QI_type_node;
+static GTY(()) tree V4SF_type_node;
+static GTY(()) tree V4SI_type_node;
+static GTY(()) tree V8QI_type_node;
+static GTY(()) tree V8HI_type_node;
+static GTY(()) tree V4HI_type_node;
+static GTY(()) tree V2HI_type_node;
+static GTY(()) tree V2SI_type_node;
+static GTY(()) tree V2SF_type_node;
+static GTY(()) tree V2DI_type_node;
+static GTY(()) tree V2DF_type_node;
+static GTY(()) tree V16SF_type_node;
+static GTY(()) tree V1DI_type_node;
+static GTY(()) tree V4DF_type_node;
+/* APPLE LOCAL end Altivec */
+
/* Processor feature/optimization bitmasks. */
#define m_386 (1<<PROCESSOR_I386)
#define m_486 (1<<PROCESSOR_I486)
@@ -919,6 +952,11 @@ static rtx ix86_struct_value_rtx (tree, int);
static bool ix86_ms_bitfield_layout_p (tree);
static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);
static int extended_reg_mentioned_1 (rtx *, void *);
+/* APPLE LOCAL begin why is this local? */
+#if TARGET_MACHO
+static bool ix86_binds_local_p (tree);
+#endif
+/* APPLE LOCAL end why is this local? */
static bool ix86_rtx_costs (rtx, int, int, int *);
static int min_insn_size (rtx);
static tree ix86_md_asm_clobbers (tree clobbers);
@@ -1030,6 +1068,13 @@ static void init_ext_80387_constants (void);
#undef TARGET_MS_BITFIELD_LAYOUT_P
#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
+/* APPLE LOCAL begin why is this local? */
+#if TARGET_MACHO
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P ix86_binds_local_p
+#endif
+/* APPLE LOCAL end why is this local? */
+
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
@@ -1043,6 +1088,12 @@ static void init_ext_80387_constants (void);
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST ix86_address_cost
+/* APPLE LOCAL begin SSE stack alignment */
+#ifndef BASIC_STACK_BOUNDARY
+#define BASIC_STACK_BOUNDARY (32)
+#endif
+/* APPLE LOCAL end SSE stack alignment */
+
#undef TARGET_FIXED_CONDITION_CODE_REGS
#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
#undef TARGET_CC_MODES_COMPATIBLE
@@ -1203,6 +1254,12 @@ override_options (void)
SUBTARGET_OVERRIDE_OPTIONS;
#endif
+ /* APPLE LOCAL begin constant cfstrings */
+#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
+ SUBSUBTARGET_OVERRIDE_OPTIONS;
+#endif
+ /* APPLE LOCAL end constant cfstrings */
+
/* Set the default values for switches whose default depends on TARGET_64BIT
in case they weren't overwritten by command line options. */
if (TARGET_64BIT)
@@ -1426,9 +1483,11 @@ 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. */
+ /* APPLE LOCAL begin SSE stack alignment */
ix86_preferred_stack_boundary = (optimize_size
- ? TARGET_64BIT ? 128 : 32
+ ? TARGET_64BIT ? 128 : BASIC_STACK_BOUNDARY
: 128);
+ /* APPLE LOCAL end SSE stack alignment */
if (ix86_preferred_stack_boundary_string)
{
i = atoi (ix86_preferred_stack_boundary_string);
@@ -1583,11 +1642,34 @@ override_options (void)
so it won't slow down the compilation and make x87 code slower. */
if (!TARGET_SCHEDULE)
flag_schedule_insns_after_reload = flag_schedule_insns = 0;
+
+ /* APPLE LOCAL begin dynamic-no-pic */
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ {
+ if (flag_pic)
+ warning ("-mdynamic-no-pic overrides -fpic or -fPIC");
+ flag_pic = 0;
+ }
+ else
+#endif
+ if (flag_pic == 1)
+ {
+ /* Darwin doesn't support -fpic. */
+ warning ("-fpic is not supported; -fPIC assumed");
+ flag_pic = 2;
+ }
+ /* APPLE LOCAL end dynamic-no-pic */
}
void
optimization_options (int level, int size ATTRIBUTE_UNUSED)
{
+ /* APPLE LOCAL begin disable strict aliasing; breaks too much existing code. */
+#if TARGET_MACHO
+ flag_strict_aliasing = 0;
+#endif
+ /* APPLE LOCAL end disable strict aliasing; breaks too much existing code. */
/* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
make the problem with not enough registers even worse. */
#ifdef INSN_SCHEDULING
@@ -1595,6 +1677,14 @@ optimization_options (int level, int size ATTRIBUTE_UNUSED)
flag_schedule_insns = 0;
#endif
+ /* APPLE LOCAL begin pragma fenv */
+ /* Trapping math is not needed by many users, and is expensive.
+ C99 permits us to default it off and we do that. It is
+ turned on when <fenv.h> is included (see darwin_pragma_fenv
+ in darwin-c.c). */
+ flag_trapping_math = 0;
+ /* APPLE LOCAL end pragma fenv */
+
/* The default values of these switches depend on the TARGET_64BIT
that is not known at this moment. Mark these values with 2 and
let user the to override these. In case there is no command line option
@@ -3877,7 +3967,8 @@ static int pic_labels_used;
static void
get_pc_thunk_name (char name[32], unsigned int regno)
{
- if (USE_HIDDEN_LINKONCE)
+ /* APPLE LOCAL deep branch prediction pic-base. */
+ if (USE_HIDDEN_LINKONCE || TARGET_MACHO)
sprintf (name, "__i686.get_pc_thunk.%s", reg_names[regno]);
else
ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
@@ -3921,6 +4012,18 @@ ix86_file_end (void)
fputc ('\n', asm_out_file);
ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
}
+ /* APPLE LOCAL begin deep branch prediction pic-base */
+ else if (TARGET_MACHO)
+ {
+ darwin_textcoal_nt_section ();
+ fputs (".weak_definition\t", asm_out_file);
+ assemble_name (asm_out_file, name);
+ fputs ("\n.private_extern\t", asm_out_file);
+ assemble_name (asm_out_file, name);
+ fputs ("\n", asm_out_file);
+ ASM_OUTPUT_LABEL (asm_out_file, name);
+ }
+ /* APPLE LOCAL end deep branch prediction pic-base */
else
{
text_section ();
@@ -3976,12 +4079,24 @@ 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);
+ /* APPLE LOCAL begin deep branch prediction pic-base */
+#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. */
+ if (cfun)
+ ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+#endif
+ /* APPLE LOCAL end deep branch prediction pic-base */
}
+ /* APPLE LOCAL begin deep branch prediction pic-base */
+#if !TARGET_MACHO
if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
else if (!TARGET_MACHO)
output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %a1+(.-%a2)}", xops);
+#endif /* !TARGET_MACHO */
+ /* APPLE LOCAL end deep branch prediction pic-base */
return "";
}
@@ -4651,6 +4766,24 @@ ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
{
if (pic_offset_table_rtx)
REGNO (pic_offset_table_rtx) = REAL_PIC_OFFSET_TABLE_REGNUM;
+ /* APPLE LOCAL begin */
+#if TARGET_MACHO
+ /* Mach-O doesn't support labels at the end of objects, so if
+ it looks like we might want one, insert a NOP. */
+ {
+ rtx insn = get_last_insn ();
+ while (insn
+ && NOTE_P (insn)
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
+ insn = PREV_INSN (insn);
+ if (insn
+ && (LABEL_P (insn)
+ || (NOTE_P (insn)
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
+ fputs ("\tnop\n", file);
+ }
+#endif
+ /* APPLE LOCAL end */
}
/* Extract the parts of an RTL expression that is a valid memory address
@@ -4971,7 +5104,21 @@ legitimate_constant_p (rtx x)
/* TLS symbols are never valid. */
if (tls_symbolic_operand (x, Pmode))
return false;
+ /* APPLE LOCAL begin dynamic-no-pic */
+ if (TARGET_MACHO && TARGET_DYNAMIC_NO_PIC)
+ 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;
+ }
break;
+ /* APPLE LOCAL end dynamic-no-pic */
default:
break;
@@ -5273,7 +5420,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error;
}
- else if (flag_pic && (SYMBOLIC_CONST (disp)
+ /* APPLE LOCAL dynamic-no-pic */
+ else if (MACHOPIC_INDIRECT && (SYMBOLIC_CONST (disp)
#if TARGET_MACHO
&& !machopic_operand_p (disp)
#endif
@@ -5294,11 +5442,18 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
goto report_error;
}
}
- else if (! legitimate_pic_address_disp_p (disp))
+ /* APPLE LOCAL begin dynamic-no-pic */
+ else if (flag_pic && ! legitimate_pic_address_disp_p (disp))
{
reason = "displacement is an invalid pic construct";
goto report_error;
}
+ else if (TARGET_DYNAMIC_NO_PIC && !legitimate_constant_p (disp))
+ {
+ reason = "displacment must be referenced via non_lazy_pointer";
+ goto report_error;
+ }
+ /* APPLE LOCAL end dynamic-no-pic */
/* This code used to verify that a symbolic pic displacement
includes the pic_offset_table_rtx register.
@@ -5721,6 +5876,10 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
if (flag_pic && SYMBOLIC_CONST (x))
return legitimize_pic_address (x, 0);
+ /* APPLE LOCAL begin dynamic-no-pic */
+ if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
+ return machopic_indirect_data_reference (x, 0);
+ /* APPLE LOCAL end dynamic-no-pic */
/* Canonicalize shifts by 0, 1, 2, 3 into multiply */
if (GET_CODE (x) == ASHIFT
@@ -5891,7 +6050,19 @@ output_pic_addr_const (FILE *file, rtx x, int code)
if (SYMBOL_REF_DECL (x))
mark_decl_referenced (SYMBOL_REF_DECL (x));
+ /* APPLE LOCAL begin stubify optimized symbols */
+#if TARGET_MACHO
+ {
+ const char *name = XSTR (x, 0);
+ if (MACHOPIC_INDIRECT
+ && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
+ name = machopic_indirection_name (x, /*stub_p=*/true);
+ assemble_name (file, name);
+ }
+#else
assemble_name (file, XSTR (x, 0));
+#endif
+ /* APPLE LOCAL end stubify optimized symbols */
if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
fputs ("@PLT", file);
break;
@@ -6721,7 +6892,13 @@ print_operand (FILE *file, rtx x, int code)
}
if (GET_CODE (x) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
- else if (flag_pic)
+ /* APPLE LOCAL begin dynamic-no-pic */
+ else if (flag_pic
+#if TARGET_MACHO
+ || MACHOPIC_INDIRECT
+#endif
+ )
+ /* APPLE LOCAL end dynamic-no-pic */
output_pic_addr_const (file, x, code);
else
output_addr_const (file, x);
@@ -7515,7 +7692,8 @@ void
ix86_expand_move (enum machine_mode mode, rtx operands[])
{
int strict = (reload_in_progress || reload_completed);
- rtx op0, op1;
+ /* APPLE LOCAL dynamic-no-pic */
+ rtx insn, op0, op1;
enum tls_model model;
op0 = operands[0];
@@ -7549,29 +7727,49 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
}
}
- if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
+ /* APPLE LOCAL begin dynamic-no-pic */
+ if (MACHOPIC_INDIRECT
+ && mode == Pmode && symbolic_operand (op1, Pmode))
+ /* APPLE LOCAL end dynamic-no-pic */
{
#if TARGET_MACHO
- if (MACHOPIC_PURE)
+ /* APPLE LOCAL begin dynamic-no-pic */
+ if (MACHOPIC_INDIRECT)
{
rtx temp = ((reload_in_progress
|| ((op0 && GET_CODE (op0) == REG)
&& 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)
- return;
-#else
+ if (op0 != op1 && GET_CODE (op0) != MEM)
+ {
+ 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;
+ }
+#else /* TARGET_MACHO */
if (GET_CODE (op0) == MEM)
op1 = force_reg (Pmode, op1);
else
op1 = legitimize_address (op1, op1, Pmode);
#endif /* TARGET_MACHO */
+ /* APPLE LOCAL end dynamic-no-pic */
}
else
{
@@ -11699,7 +11897,8 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
abort ();
#if TARGET_MACHO
- if (flag_pic && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
+ /* APPLE LOCAL dynamic-no-pic */
+ if (MACHOPIC_INDIRECT && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
fnaddr = machopic_indirect_call_target (fnaddr);
#else
/* Static functions and indirect calls don't need the pic register. */
@@ -13235,6 +13434,12 @@ ix86_init_builtins (void)
{
if (TARGET_MMX)
ix86_init_mmx_sse_builtins ();
+
+ /* APPLE LOCAL begin constant cfstrings */
+#ifdef SUBTARGET_INIT_BUILTINS
+ SUBTARGET_INIT_BUILTINS;
+#endif
+ /* APPLE LOCAL end constant cfstrings */
}
/* Set up all the MMX/SSE builtins. This is not called if TARGET_MMX
@@ -15190,6 +15395,21 @@ ix86_memory_move_cost (enum machine_mode mode, enum reg_class class, int in)
}
}
+/* APPLE LOCAL begin why is this local? */
+#if TARGET_MACHO
+/* Cross-module name binding. Darwin does not support overriding
+ functions at dynamic-link time. */
+
+static bool
+ix86_binds_local_p (tree decl)
+{
+ /* APPLE LOCAL kext treat vtables as overridable */
+ return default_binds_local_p_1 (decl,
+ flag_apple_kext && lang_hooks.vtable_p (decl));
+}
+#endif
+/* APPLE LOCAL end why is this local? */
+
/* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be
scanned. In either case, *TOTAL contains the cost result. */
@@ -15548,11 +15768,37 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub)
fprintf (file, "\tjmp dyld_stub_binding_helper\n");
- machopic_lazy_symbol_ptr_section ();
+ /* APPLE LOCAL begin deep branch prediction pic-base. */
+ /* 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)
+ machopic_lazy_symbol_ptr2_section (); /* PIC stub using "CALL get_pc_thunk". */
+ else
+ machopic_lazy_symbol_ptr_section (); /* PIC stub using inline picbase: "CALL L42 ! L42: pop %ebx". */
+ }
+ else
+ {
+ machopic_lazy_symbol_ptr3_section (); /* -mdynamic-no-pic stub. */
+ }
+ /* APPLE LOCAL end deep branch prediction pic-base. */
fprintf (file, "%s:\n", lazy_ptr_name);
fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
fprintf (file, "\t.long %s\n", binder_name);
}
+
+/* APPLE LOCAL begin deep branch prediction pic-base */
+void
+darwin_x86_file_end (void)
+{
+ darwin_file_end ();
+ ix86_file_end ();
+}
+/* APPLE LOCAL end deep branch prediction pic-base */
#endif /* TARGET_MACHO */
/* Order the registers for register allocator. */
@@ -15873,6 +16119,14 @@ x86_field_alignment (tree field, int computed)
if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
return computed;
+ /* APPLE LOCAL begin mac68k alignment */
+ if (TARGET_ALIGN_MAC68K)
+ {
+ if (computed >= 128)
+ return computed;
+ return MIN (computed, 16);
+ }
+ /* APPLE LOCAL end mac68k alignment */
mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
? get_inner_array_type (type) : type);
if (mode == DFmode || mode == DCmode