/* Definitions of target machine for GCC for IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* The purpose of this file is to define the characteristics of the i386,
independent of assembler syntax or operating system.
/* configure can arrange to make this 2, to force a 486. */
#ifndef TARGET_CPU_DEFAULT
-#ifdef TARGET_64BIT_DEFAULT
-#define TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT_k8
-#else
-#define TARGET_CPU_DEFAULT 0
-#endif
+#define TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT_generic
#endif
#ifndef TARGET_FPMATH_DEFAULT
#define TARGET_K8 (ix86_tune == PROCESSOR_K8)
#define TARGET_ATHLON_K8 (TARGET_K8 || TARGET_ATHLON)
#define TARGET_NOCONA (ix86_tune == PROCESSOR_NOCONA)
+#define TARGET_GENERIC32 (ix86_tune == PROCESSOR_GENERIC32)
+#define TARGET_GENERIC64 (ix86_tune == PROCESSOR_GENERIC64)
+#define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64)
#define TUNEMASK (1 << ix86_tune)
extern const int x86_use_leave, x86_push_memory, x86_zero_extend_with_and;
extern const int x86_use_bit_test, x86_cmove, x86_fisttp, x86_deep_branch;
extern const int x86_branch_hints, x86_unroll_strlen;
extern const int x86_double_with_add, x86_partial_reg_stall, x86_movx;
-extern const int x86_use_loop, x86_use_himode_fiop, x86_use_simode_fiop;
+extern const int x86_use_himode_fiop, x86_use_simode_fiop;
extern const int x86_use_mov0, x86_use_cltd, x86_read_modify_write;
extern const int x86_read_modify, x86_split_long_moves;
extern const int x86_promote_QImode, x86_single_stringop, x86_fast_prefix;
extern const int x86_use_ffreep;
extern const int x86_inter_unit_moves, x86_schedule;
extern const int x86_use_bt;
-extern const int x86_cmpxchg, x86_xadd;
+extern const int x86_cmpxchg, x86_cmpxchg8b, x86_cmpxchg16b, x86_xadd;
+extern const int x86_use_incdec;
+extern const int x86_pad_returns;
extern int x86_prefetch_sse;
#define TARGET_USE_LEAVE (x86_use_leave & TUNEMASK)
/* For sane SSE instruction set generation we need fcomi instruction. It is
safe to enable all CMOVE instructions. */
#define TARGET_CMOVE ((x86_cmove & (1 << ix86_arch)) || TARGET_SSE)
-#define TARGET_FISTTP (x86_fisttp & (1 << ix86_arch))
+#define TARGET_FISTTP (((x86_fisttp & (1 << ix86_arch)) || TARGET_SSE3) \
+ && TARGET_80387)
#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & TUNEMASK)
#define TARGET_BRANCH_PREDICTION_HINTS (x86_branch_hints & TUNEMASK)
#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & TUNEMASK)
#define TARGET_USE_SAHF ((x86_use_sahf & TUNEMASK) && !TARGET_64BIT)
#define TARGET_MOVX (x86_movx & TUNEMASK)
#define TARGET_PARTIAL_REG_STALL (x86_partial_reg_stall & TUNEMASK)
-#define TARGET_USE_LOOP (x86_use_loop & TUNEMASK)
#define TARGET_USE_HIMODE_FIOP (x86_use_himode_fiop & TUNEMASK)
#define TARGET_USE_SIMODE_FIOP (x86_use_simode_fiop & TUNEMASK)
#define TARGET_USE_MOV0 (x86_use_mov0 & TUNEMASK)
#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & TUNEMASK)
#define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & TUNEMASK)
#define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & TUNEMASK)
-#define TARGET_DECOMPOSE_LEA (x86_decompose_lea & TUNEMASK)
#define TARGET_PREFETCH_SSE (x86_prefetch_sse)
#define TARGET_SHIFT1 (x86_shift1 & TUNEMASK)
#define TARGET_USE_FFREEP (x86_use_ffreep & TUNEMASK)
#define TARGET_FOUR_JUMP_LIMIT (x86_four_jump_limit & TUNEMASK)
#define TARGET_SCHEDULE (x86_schedule & TUNEMASK)
#define TARGET_USE_BT (x86_use_bt & TUNEMASK)
+#define TARGET_USE_INCDEC (x86_use_incdec & TUNEMASK)
+#define TARGET_PAD_RETURNS (x86_pad_returns & TUNEMASK)
#define ASSEMBLER_DIALECT (ix86_asm_dialect)
&& (ix86_fpmath & FPMATH_387))
#define TARGET_GNU_TLS (ix86_tls_dialect == TLS_DIALECT_GNU)
+#define TARGET_GNU2_TLS (ix86_tls_dialect == TLS_DIALECT_GNU2)
+#define TARGET_ANY_GNU_TLS (TARGET_GNU_TLS || TARGET_GNU2_TLS)
#define TARGET_SUN_TLS (ix86_tls_dialect == TLS_DIALECT_SUN)
#define TARGET_CMPXCHG (x86_cmpxchg & (1 << ix86_arch))
+#define TARGET_CMPXCHG8B (x86_cmpxchg8b & (1 << ix86_arch))
+#define TARGET_CMPXCHG16B (x86_cmpxchg16b & (1 << ix86_arch))
#define TARGET_XADD (x86_xadd & (1 << ix86_arch))
#ifndef TARGET_64BIT_DEFAULT
#define TARGET_CPU_DEFAULT_pentium_m 14
#define TARGET_CPU_DEFAULT_prescott 15
#define TARGET_CPU_DEFAULT_nocona 16
+#define TARGET_CPU_DEFAULT_generic 17
#define TARGET_CPU_DEFAULT_NAMES {"i386", "i486", "pentium", "pentium-mmx",\
"pentiumpro", "pentium2", "pentium3", \
"pentium4", "k6", "k6-2", "k6-3",\
"athlon", "athlon-4", "k8", \
- "pentium-m", "prescott", "nocona"}
+ "pentium-m", "prescott", "nocona", \
+ "generic"}
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
#define EXTRA_SPECS \
{ "cc1_cpu", CC1_CPU_SPEC }, \
SUBTARGET_EXTRA_SPECS
+
+#define LINK_GCC_MATH_SPEC "%{msselibm:-lgcc-math}"
\f
/* target machine storage layout */
aligned; the compiler cannot rely on having this alignment. */
#define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary
-/* As of July 2001, many runtimes to not align the stack properly when
+/* As of July 2001, many runtimes do not align the stack properly when
entering main. This causes expand_main_function to forcibly align
the stack, which results in aligned frames for functions called from
main, though it does nothing for the alignment of main itself. */
/* Decide whether a variable of mode MODE should be 128 bit aligned. */
#define ALIGN_MODE_128(MODE) \
- ((MODE) == XFmode || (MODE) == TFmode || SSE_REG_MODE_P (MODE))
+ ((MODE) == XFmode || SSE_REG_MODE_P (MODE))
/* The published ABIs say that doubles should be aligned on word
boundaries, so lower the alignment for structure fields unless
#define STACK_REGS
#define IS_STACK_MODE(MODE) \
- ((MODE) == DFmode || (MODE) == SFmode || (MODE) == XFmode) \
+ (((MODE) == SFmode && (!TARGET_SSE || !TARGET_SSE_MATH)) \
+ || ((MODE) == DFmode && (!TARGET_SSE2 || !TARGET_SSE_MATH)) \
+ || (MODE) == XFmode)
/* Number of actual hardware registers.
The hardware registers are assigned numbers for the compiler
int i; \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
+ fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
} \
if (! TARGET_SSE) \
{ \
int i; \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
+ fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
} \
if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387) \
{ \
COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]); \
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
if (TEST_HARD_REG_BIT (x, i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
+ fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; \
+ } \
+ if (! TARGET_64BIT) \
+ { \
+ int i; \
+ for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++) \
+ reg_names[i] = ""; \
+ for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
+ reg_names[i] = ""; \
} \
} while (0)
/* ??? No autovectorization into MMX or 3DNOW until we can reliably
place emms and femms instructions. */
-#define UNITS_PER_SIMD_WORD (TARGET_SSE ? 16 : 0)
+#define UNITS_PER_SIMD_WORD (TARGET_SSE ? 16 : UNITS_PER_WORD)
#define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \
#define REAL_PIC_OFFSET_TABLE_REGNUM 3
#define PIC_OFFSET_TABLE_REGNUM \
- (TARGET_64BIT || !flag_pic ? INVALID_REGNUM \
+ ((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \
+ || !flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM)
#define INDEX_REG_CLASS INDEX_REGS
#define BASE_REG_CLASS GENERAL_REGS
-/* Unused letters:
- B TU W
- h jk vw z
-*/
-
-/* Get reg_class from a letter such as appears in the machine description. */
-
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'r' ? GENERAL_REGS : \
- (C) == 'R' ? LEGACY_REGS : \
- (C) == 'q' ? TARGET_64BIT ? GENERAL_REGS : Q_REGS : \
- (C) == 'Q' ? Q_REGS : \
- (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
- ? FLOAT_REGS \
- : NO_REGS) : \
- (C) == 't' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
- ? FP_TOP_REG \
- : NO_REGS) : \
- (C) == 'u' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
- ? FP_SECOND_REG \
- : NO_REGS) : \
- (C) == 'a' ? AREG : \
- (C) == 'b' ? BREG : \
- (C) == 'c' ? CREG : \
- (C) == 'd' ? DREG : \
- (C) == 'x' ? TARGET_SSE ? SSE_REGS : NO_REGS : \
- (C) == 'Y' ? TARGET_SSE2? SSE_REGS : NO_REGS : \
- (C) == 'y' ? TARGET_MMX ? MMX_REGS : NO_REGS : \
- (C) == 'A' ? AD_REGS : \
- (C) == 'D' ? DIREG : \
- (C) == 'S' ? SIREG : \
- (C) == 'l' ? INDEX_REGS : \
- NO_REGS)
-
-/* The letters I, J, K, L and M in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C.
-
- I is for non-DImode shifts.
- J is for DImode shifts.
- K is for signed imm8 operands.
- L is for andsi as zero-extending move.
- M is for shifts that can be executed by the "lea" opcode.
- N is for immediate operands for out/in instructions (0-255)
- */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 31 \
- : (C) == 'J' ? (VALUE) >= 0 && (VALUE) <= 63 \
- : (C) == 'K' ? (VALUE) >= -128 && (VALUE) <= 127 \
- : (C) == 'L' ? (VALUE) == 0xff || (VALUE) == 0xffff \
- : (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 \
- : (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 \
- : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
- Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if
- TARGET_387 isn't set, because the stack register converter may need to
- load 0.0 into the function value register. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' ? standard_80387_constant_p (VALUE) \
- : 0)
-
-/* A C expression that defines the optional machine-dependent
- constraint letters that can be used to segregate specific types of
- operands, usually memory references, for the target machine. Any
- letter that is not elsewhere defined and not matched by
- `REG_CLASS_FROM_LETTER' may be used. Normally this macro will not
- be defined.
-
- If it is required for a particular target machine, it should
- return 1 if VALUE corresponds to the operand type represented by
- the constraint letter C. If C is not defined as an extra
- constraint, the value returned should be 0 regardless of VALUE. */
-
-#define EXTRA_CONSTRAINT(VALUE, D) \
- ((D) == 'e' ? x86_64_immediate_operand (VALUE, VOIDmode) \
- : (D) == 'Z' ? x86_64_zext_immediate_operand (VALUE, VOIDmode) \
- : (D) == 'C' ? standard_sse_constant_p (VALUE) \
- : 0)
-
/* Place additional restrictions on the register class to use when it
is necessary to be able to hold a value of mode MODE in a reload
register for which class CLASS would ordinarily be used. */
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
ix86_preferred_reload_class ((X), (CLASS))
+/* Discourage putting floating-point values in SSE registers unless
+ SSE math is being used, and likewise for the 387 registers. */
+
+#define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \
+ ix86_preferred_output_reload_class ((X), (CLASS))
+
/* If we are copying between general and FP registers, we need a memory
location. The same is true for SSE and MMX registers. */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
|| ((CLASS) == FP_TOP_REG) \
|| ((CLASS) == FP_SECOND_REG))
-/* Return a class of registers that cannot change FROM mode to TO mode.
-
- x87 registers can't do subreg as all values are reformated to extended
- precision. XMM registers does not support with nonzero offsets equal
- to 4, 8 and 12 otherwise valid for integer registers. Since we can't
- determine these, prohibit all nonparadoxical subregs changing size. */
+/* Return a class of registers that cannot change FROM mode to TO mode. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (GET_MODE_SIZE (TO) < GET_MODE_SIZE (FROM) \
- ? reg_classes_intersect_p (FLOAT_SSE_REGS, (CLASS)) \
- || MAYBE_MMX_CLASS_P (CLASS) \
- : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ ix86_cannot_change_mode_class (FROM, TO, CLASS)
\f
/* Stack layout; function entry, exit and calling. */
makes the stack pointer a smaller address. */
#define STACK_GROWS_DOWNWARD
-/* Define this if the nominal address of the stack frame
+/* Define this to nonzero if the nominal address of the stack frame
is at the high-address end of the local variables;
that is, each additional local variable allocated
goes at a more negative offset in the frame. */
-#define FRAME_GROWS_DOWNWARD
+#define FRAME_GROWS_DOWNWARD 1
/* Offset within stack frame to start allocating local variables at.
If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
- On 386 pushw decrements by exactly 2 no matter what the position was.
- On the 386 there is no pushb; we use pushw instead, and this
- has the effect of rounding up to 2.
+ On 386, we have pushw instruction that decrements by exactly 2 no
+ matter what the position was, there is no pushb.
+ But as CIE data alignment factor on this arch is -4, we need to make
+ sure all stack pointer adjustments are in multiple of 4.
For 64bit ABI we round up to 8 bytes.
*/
#define PUSH_ROUNDING(BYTES) \
(TARGET_64BIT \
? (((BYTES) + 7) & (-8)) \
- : (((BYTES) + 1) & (-2)))
+ : (((BYTES) + 3) & (-4)))
/* If defined, the maximum amount of space required for outgoing arguments will
be computed and placed into the variable
#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \
ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE))
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- ix86_function_value (VALTYPE, FUNC)
-
#define FUNCTION_VALUE_REGNO_P(N) \
ix86_function_value_regno_p (N)
int mmx_nregs; /* # mmx registers available for passing */
int mmx_regno; /* next available mmx register number */
int maybe_vaarg; /* true for calls to possibly vardic fncts. */
- int float_in_sse; /* true if in 32-bit mode SFmode/DFmode should
- be passed in SSE registers. */
+ int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should
+ be passed in SSE registers. Otherwise 0. */
} CUMULATIVE_ARGS;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
-/* In order to refer to the first 8 regs as 32 bit regs prefix an "e"
+/* In order to refer to the first 8 regs as 32 bit regs, prefix an "e".
For non floating point regs, the following are the HImode names.
For float regs, the stack top is sometimes referred to as "%st(0)"
{ "rax", 0 }, { "rdx", 1 }, { "rcx", 2 }, { "rbx", 3 }, \
{ "rsi", 4 }, { "rdi", 5 }, { "rbp", 6 }, { "rsp", 7 }, \
{ "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 }, \
- { "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 }, \
- { "mm0", 8}, { "mm1", 9}, { "mm2", 10}, { "mm3", 11}, \
- { "mm4", 12}, { "mm5", 13}, { "mm6", 14}, { "mm7", 15} }
+ { "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 } }
/* Note we are omitting these since currently I don't know how
to get gcc to use these, since they want the same but different
#define DBX_REGISTER_NUMBER(N) \
(TARGET_64BIT ? dbx64_register_map[(N)] : dbx_register_map[(N)])
-extern int const dbx_register_map[FIRST_PSEUDO_REGISTER];
-extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER];
-extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
+extern int const dbx_register_map[FIRST_PSEUDO_REGISTER+1];
+extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER+1];
+extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER+1];
/* Before the prologue, RA is at 0(%esp). */
#define INCOMING_RETURN_ADDR_RTX \
Whether or not a particular assembler allows us to enter such, I
guess we'll have to see. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- (flag_pic \
- ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
- : DW_EH_PE_absptr)
+ asm_preferred_eh_data_format ((CODE), (GLOBAL))
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
#define JUMP_TABLES_IN_TEXT_SECTION \
(!TARGET_64BIT && flag_pic && !HAVE_AS_GOTOFF_IN_DATA)
-/* Emit a dtp-relative reference to a TLS variable. */
-
-#ifdef HAVE_AS_TLS
-#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
- i386_output_dwarf_dtprel (FILE, SIZE, X)
-#endif
-
/* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
and switch back. For x86 we do this only to save a few bytes that
would otherwise be unused in the text section. */
PROCESSOR_PENTIUM4,
PROCESSOR_K8,
PROCESSOR_NOCONA,
+ PROCESSOR_GENERIC32,
+ PROCESSOR_GENERIC64,
PROCESSOR_max
};
extern enum processor_type ix86_tune;
-extern const char *ix86_tune_string;
-
extern enum processor_type ix86_arch;
-extern const char *ix86_arch_string;
enum fpmath_unit
{
enum tls_dialect
{
TLS_DIALECT_GNU,
+ TLS_DIALECT_GNU2,
TLS_DIALECT_SUN
};
CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */
CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
CM_LARGE, /* No assumptions. */
- CM_SMALL_PIC /* Assumes code+data+got/plt fits in a 31 bit region. */
+ CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */
+ CM_MEDIUM_PIC /* Assumes code+got/plt fits in a 31 bit region. */
};
extern enum cmodel ix86_cmodel;
extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary;
-extern int ix86_branch_cost;
+extern int ix86_branch_cost, ix86_section_threshold;
/* Smallest class containing REGNO. */
extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
Post-reload pass may be later used to eliminate the redundant fildcw if
needed. */
+enum ix86_entity
+{
+ I387_TRUNC = 0,
+ I387_FLOOR,
+ I387_CEIL,
+ I387_MASK_PM,
+ MAX_386_ENTITIES
+};
+
+enum ix86_stack_slot
+{
+ SLOT_TEMP = 0,
+ SLOT_CW_STORED,
+ SLOT_CW_TRUNC,
+ SLOT_CW_FLOOR,
+ SLOT_CW_CEIL,
+ SLOT_CW_MASK_PM,
+ MAX_386_STACK_LOCALS
+};
/* Define this macro if the port needs extra instructions inserted
for mode switching in an optimizing compilation. */
-#define OPTIMIZE_MODE_SWITCHING(ENTITY) ix86_optimize_mode_switching
+#define OPTIMIZE_MODE_SWITCHING(ENTITY) \
+ ix86_optimize_mode_switching[(ENTITY)]
/* If you define `OPTIMIZE_MODE_SWITCHING', you have to define this as
initializer for an array of integers. Each initializer element N
starting counting at zero - determines the integer that is used to
refer to the mode-switched entity in question. */
-#define NUM_MODES_FOR_MODE_SWITCHING { I387_CW_ANY }
+#define NUM_MODES_FOR_MODE_SWITCHING \
+ { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY }
/* ENTITY is an integer specifying a mode-switched entity. If
`OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
return an integer value not larger than the corresponding element
in `NUM_MODES_FOR_MODE_SWITCHING', to denote the mode that ENTITY
- must be switched into prior to the execution of INSN.
-
- The mode UNINITIALIZED is used to force re-load of possibly previously
- stored control word after function call. The mode ANY specify that
- function has no requirements on the control word and make no changes
- in the bits we are interested in. */
-
-#define MODE_NEEDED(ENTITY, I) \
- (GET_CODE (I) == CALL_INSN \
- || (GET_CODE (I) == INSN && (asm_noperands (PATTERN (I)) >= 0 \
- || GET_CODE (PATTERN (I)) == ASM_INPUT))\
- ? I387_CW_UNINITIALIZED \
- : recog_memoized (I) < 0 \
- ? I387_CW_ANY \
- : get_attr_i387_cw (I))
+ must be switched into prior to the execution of INSN. */
+
+#define MODE_NEEDED(ENTITY, I) ix86_mode_needed ((ENTITY), (I))
/* This macro specifies the order in which modes for ENTITY are
processed. 0 is the highest priority. */
#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
((MODE) != I387_CW_ANY && (MODE) != I387_CW_UNINITIALIZED \
- ? emit_i387_cw_initialization (assign_386_stack_local (HImode, 1), \
- assign_386_stack_local (HImode, 2), \
- MODE), 0 \
+ ? emit_i387_cw_initialization (MODE), 0 \
: 0)
+
\f
/* Avoid renaming of stack registers, as doing so in combination with
scheduling just increases amount of live registers at time and in
{
struct stack_local_entry *stack_locals;
const char *some_ld_name;
+ rtx force_align_arg_pointer;
int save_varrargs_registers;
int accesses_prev_frame;
- int optimize_mode_switching;
+ int optimize_mode_switching[MAX_386_ENTITIES];
/* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to
determine the style used. */
int use_fast_prologue_epilogue;
/* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE has been computed
for. */
int use_fast_prologue_epilogue_nregs;
+ /* If true, the current function needs the default PIC register, not
+ an alternate register (on x86) and must not use the red zone (on
+ x86_64), even if it's a leaf function. We don't want the
+ function to be regarded as non-leaf because TLS calls need not
+ affect register allocation. This flag is set when a TLS call
+ instruction is expanded within a function, and never reset, even
+ if all such instructions are optimized away. Use the
+ ix86_current_function_calls_tls_descriptor macro for a better
+ approximation. */
+ int tls_descriptor_call_expanded_p;
};
#define ix86_stack_locals (cfun->machine->stack_locals)
#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
#define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
+#define ix86_tls_descriptor_calls_expanded_in_cfun \
+ (cfun->machine->tls_descriptor_call_expanded_p)
+/* Since tls_descriptor_call_expanded is not cleared, even if all TLS
+ calls are optimized away, we try to detect cases in which it was
+ optimized away. Since such instructions (use (reg REG_SP)), we can
+ verify whether there's any such instruction live by testing that
+ REG_SP is live. */
+#define ix86_current_function_calls_tls_descriptor \
+ (ix86_tls_descriptor_calls_expanded_in_cfun && regs_ever_live[SP_REG])
/* Control behavior of x86_file_start. */
#define X86_FILE_START_VERSION_DIRECTIVE false
#define X86_FILE_START_FLTUSED false
+/* Flag to mark data that is in the large address area. */
+#define SYMBOL_FLAG_FAR_ADDR (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_REF_FAR_ADDR_P(X) \
+ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FAR_ADDR) != 0)
/*
Local variables:
version-control: t