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 53c08b0..a575611 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler for Intel X86
    (386, 486, Pentium).
-   Copyright (C) 1988, 92, 94-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1988, 92, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -304,36 +304,37 @@ extern int ix86_arch;
 %{mpentiumpro:-mcpu=pentiumpro}}"
 #endif
 \f
-#ifndef CPP_CPU_SPEC
-#ifdef __STDC__
+#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 "-Di486"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_486)"
 #else
 #if TARGET_CPU_DEFAULT == 2
-#define CPP_CPU_DEFAULT "-Di586"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_586)"
 #else
 #if TARGET_CPU_DEFAULT == 3
-#define CPP_CPU_DEFAULT "-Di686"
+#define CPP_CPU_DEFAULT_SPEC "%(cpp_686)"
 #else
-#define CPP_CPU_DEFAULT ""
+#define CPP_CPU_DEFAULT_SPEC ""
 #endif
 #endif
-#endif /* TARGET_CPU_DEFAULT */
-
-#define CPP_CPU_SPEC "\
--Di386 " CPP_CPU_DEFAULT " -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}"
+#endif
+#endif /* CPP_CPU_DEFAULT_SPEC */
 
-#else
+#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}"
-#endif /* __STDC__ */
-#endif /* CPP_CPU_SPEC */
+-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
 #define CC1_SPEC "%(cc1_spec) "
@@ -354,6 +355,10 @@ 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 },                                                \
   SUBTARGET_EXTRA_SPECS
@@ -424,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,22 +511,18 @@ extern int ix86_arch;
 /* Required on the 386 since it doesn't have bitfield insns.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* An integer expression for the size in bits of the largest integer
-   machine mode that should actually be used.  All integer machine modes of
-   this size or smaller can be used for structures and unions with the
-   appropriate sizes.  */
-#define MAX_FIXED_MODE_SIZE 32
-
 /* Maximum power of 2 that code can be aligned to.  */
 #define MAX_CODE_ALIGN 6                       /* 64 byte alignment */
 
 /* 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.  */
@@ -578,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)     \
@@ -592,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.  */
@@ -721,16 +794,16 @@ enum reg_class
    of length N_REG_CLASSES.  */
 
 #define REG_CLASS_CONTENTS \
-{      0,                                                      \
-     0x1,    0x2,  0x4,         0x8,   /* AREG, DREG, CREG, BREG */    \
-     0x3,                      /* AD_REGS */                   \
-     0xf,                      /* Q_REGS */                    \
-    0x10,   0x20,              /* SIREG, DIREG */              \
0x7f,                         /* INDEX_REGS */                \
0x100ff,                      /* GENERAL_REGS */              \
-  0x0100, 0x0200,              /* FP_TOP_REG, FP_SECOND_REG */ \
-  0xff00,                      /* FLOAT_REGS */                \
0x1ffff }
+{      {0},                                                    \
+     {0x1},    {0x2},  {0x4},   {0x8}, /* AREG, DREG, CREG, BREG */    \
+     {0x3},                    /* AD_REGS */                   \
+     {0xf},                    /* Q_REGS */                    \
+    {0x10},   {0x20},          /* SIREG, DIREG */              \
{0x7f},                               /* INDEX_REGS */                \
{0x100ff},                    /* GENERAL_REGS */              \
+  {0x0100}, {0x0200},          /* FP_TOP_REG, FP_SECOND_REG */ \
+  {0xff00},                    /* FLOAT_REGS */                \
{0x1ffff}}
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -1870,6 +1943,7 @@ while (0)
 
 #define CONST_COSTS(RTX,CODE,OUTER_CODE) \
   case CONST_INT:                                              \
+    return (unsigned) INTVAL (RTX) < 256 ? 0 : 1;              \
   case CONST:                                                  \
   case LABEL_REF:                                              \
   case SYMBOL_REF:                                             \
@@ -2079,7 +2153,7 @@ while (0)
    between two registers, you should define this macro to express the
    relative cost.  */
 
-/* #define MEMORY_MOVE_COST(M) 2  */
+/* #define MEMORY_MOVE_COST(M,C,I) 2  */
 
 /* A C expression for the cost of a branch instruction.  A value of 1
    is the default; other values are interpreted relative to that.  */
@@ -2514,9 +2588,13 @@ do { long l;                                             \
    R -- print the prefix for register names.
    z -- print the opcode suffix for the size of the current operand.
    * -- print a star (in certain assembler syntax)
-   w -- print the operand as if it's a "word" (HImode) even if it isn't.
-   b -- print the operand as if it's a byte (QImode) even if it isn't.
-   c -- don't print special prefixes before constant operands.  */
+   P -- if PIC, print an @PLT suffix.
+   X -- don't print any sort of PIC '@' suffix for a symbol.
+   J -- print jump insn for arithmetic_comparison_operator.
+   s -- ??? something to do with double shifts.  not actually used, afaik.
+   C -- print a conditional move suffix corresponding to the op code.
+   c -- likewise, but reverse the condition.
+   F,f -- likewise, but for floating-point.  */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
   ((CODE) == '*')
@@ -2703,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 ();