OSDN Git Service

* i386/i386.h (CPP_486_SPEC, CPP_586_SPEC, CPP_686_SPEC): New specs.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.h
index ef344b2..a575611 100644 (file)
@@ -304,15 +304,21 @@ extern int ix86_arch;
 %{mpentiumpro:-mcpu=pentiumpro}}"
 #endif
 \f
+#define CPP_486_SPEC "%{!ansi:-Di486} -D__i486 -D__i486__"
+#define CPP_586_SPEC "%{!ansi:-Di586 -Dpentium} \
+       -D__i586 -D__i586__ -D__pentium -D__pentium__"
+#define CPP_686_SPEC "%{!ansi:-Di686 -Dpentiumpro} \
+       -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__"
+
 #ifndef CPP_CPU_DEFAULT_SPEC
 #if TARGET_CPU_DEFAULT == 1
-#define CPP_CPU_DEFAULT_SPEC "-Di486"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_486)"
 #else
 #if TARGET_CPU_DEFAULT == 2
-#define CPP_CPU_DEFAULT_SPEC "-Dpentium -Di586"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_586)"
 #else
 #if TARGET_CPU_DEFAULT == 3
-#define CPP_CPU_DEFAULT_SPEC "-Dpentiumpro -Di686"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_686)"
 #else
 #define CPP_CPU_DEFAULT_SPEC ""
 #endif
@@ -322,11 +328,12 @@ extern int ix86_arch;
 
 #ifndef CPP_CPU_SPEC
 #define CPP_CPU_SPEC "\
--Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386) \
-%{mcpu=i486:-Di486} %{m486:-Di486} \
-%{mpentium:-Dpentium -Di586} %{mcpu=pentium:-Dpentium -Di586} \
-%{mpentiumpro:-Dpentiumpro -Di686} %{mcpu=pentiumpro:-Dpentiumpro -Di686} \
-%{!mcpu*:%{!m486:%{!mpentium*: %[cpp_cpu_default]}}}"
+-Asystem(unix) -Acpu(i386) -Amachine(i386) \
+%{!ansi:-Di386} -D__i386 -D__i386__ \
+%{mcpu=i486:%(cpp_486)} %{m486:%(cpp_486)} \
+%{mpentium:%(cpp_586)} %{mcpu=pentium:%(cpp_586)} \
+%{mpentiumpro:%(cpp_686)} %{mcpu=pentiumpro:%(cpp_686)} \
+%{!mcpu*:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}"
 #endif
 
 #ifndef CC1_SPEC
@@ -348,6 +355,9 @@ extern int ix86_arch;
 #endif
 
 #define EXTRA_SPECS                                                    \
+  { "cpp_486", CPP_486_SPEC},                                          \
+  { "cpp_586", CPP_586_SPEC},                                          \
+  { "cpp_686", CPP_686_SPEC},                                          \
   { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC },                         \
   { "cpp_cpu", CPP_CPU_SPEC },                                         \
   { "cc1_cpu",  CC1_CPU_SPEC },                                                \
@@ -419,8 +429,78 @@ extern int ix86_arch;
    aligned on 64 bit boundaries. */
 #define BIGGEST_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)
 
-/* align DFmode constants and nonaggregates */
-#define ALIGN_DFmode (!TARGET_386)
+/* If defined, a C expression to compute the alignment given to a
+   constant that is being placed in memory.  CONSTANT is the constant
+   and ALIGN is the alignment that the object would ordinarily have.
+   The value of this macro is used instead of that alignment to align
+   the object.
+
+   If this macro is not defined, then ALIGN is used.
+
+   The typical use of this macro is to increase alignment for string
+   constants to be word aligned so that `strcpy' calls that copy
+   constants can be done inline.  */
+
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)                                 \
+  (TREE_CODE (EXP) == REAL_CST                                         \
+    ? ((TYPE_MODE (TREE_TYPE (EXP)) == DFmode && (ALIGN) < 64)         \
+       ? 64                                                            \
+       : (TYPE_MODE (TREE_TYPE (EXP)) == XFmode && (ALIGN) < 128)      \
+       ? 128                                                           \
+       : (ALIGN))                                                      \
+    : TREE_CODE (EXP) == STRING_CST                                    \
+    ? ((TREE_STRING_LENGTH (EXP) >= 31 && (ALIGN) < 256)               \
+       ? 256                                                           \
+       : (ALIGN))                                                      \
+    : (ALIGN))
+
+/* If defined, a C expression to compute the alignment for a static
+   variable.  TYPE is the data type, and ALIGN is the alignment that
+   the object would ordinarily have.  The value of this macro is used
+   instead of that alignment to align the object.
+
+   If this macro is not defined, then ALIGN is used.
+
+   One use of this macro is to increase alignment of medium-size
+   data to make it all fit in fewer cache lines.  Another is to
+   cause character arrays to be word-aligned so that `strcpy' calls
+   that copy constants to character arrays can be done inline.  */
+
+#define DATA_ALIGNMENT(TYPE, ALIGN)                                    \
+  ((AGGREGATE_TYPE_P (TYPE)                                            \
+    && TYPE_SIZE (TYPE)                                                        \
+    && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST                     \
+    && (TREE_INT_CST_LOW (TYPE_SIZE (TYPE)) >= 256                     \
+       || TREE_INT_CST_HIGH (TYPE_SIZE (TYPE))) && (ALIGN) < 256)      \
+    ? 256                                                              \
+    : TREE_CODE (TYPE) == ARRAY_TYPE                                   \
+    ? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64)        \
+       ? 64                                                            \
+       : (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128)     \
+       ? 128                                                           \
+       : (ALIGN))                                                      \
+    : TREE_CODE (TYPE) == COMPLEX_TYPE                                 \
+    ? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64)                    \
+       ? 64                                                            \
+       : (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128)                 \
+       ? 128                                                           \
+       : (ALIGN))                                                      \
+    : ((TREE_CODE (TYPE) == RECORD_TYPE                                        \
+       || TREE_CODE (TYPE) == UNION_TYPE                               \
+       || TREE_CODE (TYPE) == QUAL_UNION_TYPE)                         \
+       && TYPE_FIELDS (TYPE))                                          \
+    ? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64)      \
+       ? 64                                                            \
+       : (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128)   \
+       ? 128                                                           \
+       : (ALIGN))                                                      \
+    : TREE_CODE (TYPE) == REAL_TYPE                                    \
+    ? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64)                    \
+       ? 64                                                            \
+       : (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128)                 \
+       ? 128                                                           \
+       : (ALIGN))                                                      \
+    : (ALIGN))
 
 /* Set this non-zero if move instructions will actually fail to work
    when given unaligned data.  */
@@ -436,11 +516,13 @@ extern int ix86_arch;
 
 /* Align loop starts for optimal branching.  */
 #define LOOP_ALIGN(LABEL) (i386_align_loops)
+#define LOOP_ALIGN_MAX_SKIP (i386_align_loops_string ? 0 : 7)
 
 /* This is how to align an instruction for optimal branching.
    On i486 we'll get better performance by aligning on a
    cache line (i.e. 16 byte) boundary.  */
 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) (i386_align_jumps)
+#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (i386_align_jumps_string ? 0 : 7)
 
 \f
 /* Standard register usage.  */
@@ -567,8 +649,7 @@ extern int ix86_arch;
    for cross-compiler testing.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
-  ((REGNO) < 2 ? 1                                             \
-   : (REGNO) < 4 ? 1                                           \
+  ((REGNO) < 4 ? 1                                             \
    : FP_REGNO_P (REGNO)                                                \
    ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT         \
        || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT)     \
@@ -581,7 +662,10 @@ extern int ix86_arch;
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
    for any hard reg, then this must be 0 for correct output.  */
 
-#define MODES_TIEABLE_P(MODE1, MODE2) ((MODE1) == (MODE2))
+#define MODES_TIEABLE_P(MODE1, MODE2)                          \
+  ((MODE1) == (MODE2)                                          \
+   || ((MODE1) == SImode && (MODE2) == HImode                  \
+       || (MODE1) == HImode && (MODE2) == SImode))
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -2697,6 +2781,9 @@ extern int is_fp_dest ();
 extern int is_fp_store ();
 extern int agi_dependent ();
 extern int reg_mentioned_in_mem ();
+extern char *output_int_conditional_move ();
+extern char *output_fp_conditional_move ();
+extern int ix86_can_use_return_insn_p ();
 
 #ifdef NOTYET
 extern struct rtx_def *copy_all_rtx ();