OSDN Git Service

* flags.h: New flag (optimize_size).
[pf3gnuchains/gcc-fork.git] / gcc / config / i960 / i960.h
index 6765686..1ef3ba7 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for Intel 80960
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1995, 1996, 1998 Free Software Foundation, Inc.
    Contributed by Steven McGeady, Intel Corp.
    Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
    Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.
@@ -18,88 +18,89 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* Note that some other tm.h files may include this one and then override
    many of the definitions that relate to assembler syntax.  */
 
 /* Names to predefine in the preprocessor for this target machine.  */
-#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960"
+#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960 -Acpu(i960) -Amachine(i960)"
 
 /* Name to predefine in the preprocessor for processor variations.  */
 #define        CPP_SPEC "%{mic*:-D__i960\
-                       %{mka:-D__i960KA}%{mkb:-D__i960KB}%{mkc:-D__i960KC}\
-                       %{msa:-D__i960SA}%{msb:-D__i960SB}%{msc:-D__i960SC}\
+                       %{mka:-D__i960KA}%{mkb:-D__i960KB}\
+                       %{mja:-D__i960JA}%{mjd:-D__i960JD}%{mjf:-D__i960JF}\
+                       %{mrp:-D__i960RP}\
+                       %{msa:-D__i960SA}%{msb:-D__i960SB}\
                        %{mmc:-D__i960MC}\
-                       %{mca:-D__i960CA}%{mcb:-D__i960CB}%{mcc:-D__i960CC}\
+                       %{mca:-D__i960CA}%{mcc:-D__i960CC}\
                        %{mcf:-D__i960CF}}\
        %{mka:-D__i960KA__ -D__i960_KA__}\
        %{mkb:-D__i960KB__ -D__i960_KB__}\
-       %{mkc:-D__i960KC__ -D__i960_KC__}\
        %{msa:-D__i960SA__ -D__i960_SA__}\
        %{msb:-D__i960SB__ -D__i960_SB__}\
-       %{msc:-D__i960SC__ -D__i960_SC__}\
        %{mmc:-D__i960MC__ -D__i960_MC__}\
        %{mca:-D__i960CA__ -D__i960_CA__}\
-       %{mcb:-D__i960CB__ -D__i960_CB__}\
        %{mcc:-D__i960CC__ -D__i960_CC__}\
        %{mcf:-D__i960CF__ -D__i960_CF__}\
-       %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\
-               %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}}}}"
+       %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:\
+               %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}"
 
 /* -mic* options make characters signed by default.  */
-#define SIGNED_CHAR_SPEC  \
-  (DEFAULT_SIGNED_CHAR ? "%{funsigned-char:-D__CHAR_UNSIGNED__}"       \
-   : "%{!fsigned-char:%{!mic*:-D__CHAR_UNSIGNED__}}")
+/* Use #if rather than ?: because MIPS C compiler rejects ?: in
+   initializers.  */
+#if DEFAULT_SIGNED_CHAR
+#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
+#else
+#define SIGNED_CHAR_SPEC "%{!fsigned-char:%{!mic*:-D__CHAR_UNSIGNED__}}"
+#endif
 
-/* Specs for the compiler, to handle processor variations.  */
+/* Specs for the compiler, to handle processor variations. 
+   If the user gives an explicit -gstabs or -gcoff option, then do not
+   try to add an implicit one, as this will fail.  */
 #define CC1_SPEC \
-       "%{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\
-               %{!mcc:%{!mcf:-mkb}}}}}}}}}}}\
-       %{mbout:%{g*:-gstabs}}\
-       %{mcoff:%{g*:-gcoff}}\
-       %{!mbout:%{!mcoff:%{g*:-gstabs}}}"
+       "%{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-mka}}}}}}}}}}}}\
+        %{!gs*:%{!gc*:%{mbout:%{g*:-gstabs}}\
+                      %{mcoff:%{g*:-gcoff}}\
+                      %{!mbout:%{!mcoff:%{g*:-gstabs}}}}}"
 
 /* Specs for the assembler, to handle processor variations.
    For compatibility with Intel's gnu960 tool chain, pass -A options to
    the assembler.  */
 #define ASM_SPEC \
-       "%{mka:-AKA}%{mkb:-AKB}%{mkc:-AKC}%{msa:-ASA}%{msb:-ASB}\
-       %{msc:-ASC}%{mmc:-AMC}%{mca:-ACA}%{mcb:-ACB}%{mcc:-ACC}%{mcf:-ACF}\
-       %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\
-               %{!mcc:%{!mcf:-AKB}}}}}}}}}}}"
+       "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\
+       %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\
+        %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX}\
+       %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-AKB}}}}}}}}}}}}\
+       %{mlink-relax:-linkrelax}"
 
 /* Specs for the linker, to handle processor variations.
    For compatibility with Intel's gnu960 tool chain, pass -F and -A options
    to the linker.  */
 #define LINK_SPEC \
-       "%{mka:-AKA}%{mkb:-AKB}%{mkc:-AKC}%{msa:-ASA}%{msb:-ASB}\
-       %{msc:-ASC}%{mmc:-AMC}%{mca:-ACA}%{mcb:-ACB}%{mcc:-ACC}%{mcf:-ACF}\
-       %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\
-               %{!mcc:%{!mcf:-AKB}}}}}}}}}}}\
-       %{mbout:-Fbout}%{mcoff:-Fcoff}"
+       "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\
+       %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\
+        %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX}\
+       %{mbout:-Fbout}%{mcoff:-Fcoff}\
+       %{mlink-relax:-relax}"
 
 /* Specs for the libraries to link with, to handle processor variations.
    Compatible with Intel's gnu960 tool chain.  */
 #define LIB_SPEC "%{!nostdlib:-lcg %{p:-lprof}%{pg:-lgprof}\
          %{mka:-lfpg}%{msa:-lfpg}%{mca:-lfpg}%{mcf:-lfpg} -lgnu}"
 
-/* These compiler options take an argument.  */
-#define WORD_SWITCH_TAKES_ARG(STR)                     \
- (!strcmp (STR, "Tdata") || !strcmp (STR, "include")   \
-  || !strcmp (STR, "imacros") || !strcmp (STR, "Ttext"))
+/* Show we can debug even without a frame pointer.  */
+#define CAN_DEBUG_WITHOUT_FP
 
-/* Omit frame pointer at -O2.  Inline functions at -O3.  */
-#define OPTIMIZATION_OPTIONS(LEVEL)            \
+/* Do leaf procedure and tail call optimizations for -O2 and higher.  */
+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE)       \
 {                                              \
   if ((LEVEL) >= 2)                            \
     {                                          \
-      flag_omit_frame_pointer = 1;             \
       target_flags |= TARGET_FLAG_LEAFPROC;    \
       target_flags |= TARGET_FLAG_TAILCALL;    \
     }                                          \
-  if ((LEVEL) >= 3)                            \
-    flag_inline_functions = 1;                 \
 }
 
 /* Print subsidiary information on the compiler version in use.  */
@@ -110,12 +111,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Generate SDB style debugging information.  */
 #define SDB_DEBUGGING_INFO
+#define EXTENDED_SDB_BASIC_TYPES
 
 /* Generate DBX_DEBUGGING_INFO by default.  */
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
 
-/* Redefine this to print in hex like iC960.  */
-#define PUT_SDB_TYPE(A) fprintf (asm_out_file, "\t.type\t0x%x;", A)
+/* Redefine this to print in hex.  No value adjustment is necessary
+   anymore.  */
+#define PUT_SDB_TYPE(A) \
+  fprintf (asm_out_file, "\t.type\t0x%x;", A)
+
+/* Handle pragmas for compatibility with Intel's compilers.  */
+#define HANDLE_PRAGMA(FILE, NODE) process_pragma (FILE, NODE)
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -129,7 +136,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        TARGET_PROTECTED        (target_flags & TARGET_FLAG_PROTECTED)
 
 /* The following three are mainly used to provide a little sanity checking
-   against the -mARCH flags given.  */
+   against the -mARCH flags given. The Jx series, for the purposes of
+   gcc, is a Kx with a data cache. */
 
 /* Nonzero if we should generate code for the KA and similar processors.
    No FPU, no microcode instructions.  */
@@ -196,7 +204,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        TARGET_ASM_COMPAT       (target_flags & TARGET_FLAG_ASM_COMPAT)
 
 /* For compatibility with the gcc960 v1.2 compiler.  Use the old structure
-   alignement rules.  Also, turns on STRICT_ALIGNMENT.  */
+   alignment rules.  Also, turns on STRICT_ALIGNMENT.  */
 #define TARGET_FLAG_OLD_ALIGN  0x8000
 #define TARGET_OLD_ALIGN       (target_flags & TARGET_FLAG_OLD_ALIGN)
 
@@ -215,22 +223,27 @@ extern int target_flags;
   { {"sa", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
     {"sb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
                        TARGET_FLAG_COMPLEX_ADDR)},\
-    {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
-                       TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\
+/*  {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
+                       TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \
     {"ka", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
     {"kb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
                        TARGET_FLAG_COMPLEX_ADDR)},\
-    {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
-                       TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\
+/*  {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
+                       TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \
+    {"ja", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
+    {"jd", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
+    {"jf", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
+                       TARGET_FLAG_COMPLEX_ADDR)},\
+    {"rp", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
     {"mc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
                        TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\
     {"ca", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
                        TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\
-    {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES|\
+/*  {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES|\
                        TARGET_FLAG_BRANCH_PREDICT|TARGET_FLAG_CODE_ALIGN)},\
     {"cc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
                        TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
-                       TARGET_FLAG_CODE_ALIGN)},       \
+                       TARGET_FLAG_CODE_ALIGN)}, */    \
     {"cf", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
                        TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\
     {"numerics", (TARGET_FLAG_NUMERICS)},              \
@@ -252,10 +265,16 @@ extern int target_flags;
     {"intel-asm",TARGET_FLAG_ASM_COMPAT},              \
     {"strict-align", TARGET_FLAG_STRICT_ALIGN},                \
     {"no-strict-align", -(TARGET_FLAG_STRICT_ALIGN)},  \
-    {"old-align", TARGET_FLAG_OLD_ALIGN},              \
-    {"no-old-align", -(TARGET_FLAG_OLD_ALIGN)},                \
+    {"old-align", (TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)},    \
+    {"no-old-align", -(TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)}, \
+    {"link-relax", 0},                                 \
+    {"no-link-relax", 0},                              \
+    SUBTARGET_SWITCHES                                                  \
     { "", TARGET_DEFAULT}}
 
+/* This are meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+
 /* Override conflicting target switch options.
    Doesn't actually detect if more than one -mARCH option is given, but
    does handle the case of two blatantly conflicting -mARCH options.  */
@@ -296,11 +315,15 @@ extern int target_flags;
 }
 
 /* Don't enable anything by default.  The user is expected to supply a -mARCH
-   option.  If none is given, then -mkb is added by CC1_SPEC.  */
+   option.  If none is given, then -mka is added by CC1_SPEC.  */
 #define TARGET_DEFAULT 0
 \f
 /* Target machine storage layout.  */
 
+/* Define for cross-compilation from a host with a different float format
+   or endianness, as well as to support 80 bit long doubles on the i960.  */
+#define REAL_ARITHMETIC
+
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */
 #define BITS_BIG_ENDIAN 0
@@ -314,7 +337,7 @@ extern int target_flags;
    numbered.  */
 #define WORDS_BIG_ENDIAN 0
 
-/* Number of bits in an addressible storage unit.  */
+/* Number of bits in an addressable storage unit.  */
 #define BITS_PER_UNIT 8
 
 /* Bitfields cannot cross word boundaries.  */
@@ -365,17 +388,24 @@ extern int target_flags;
 /* Define this if move instructions will actually fail to work
    when given unaligned data.
    80960 will work even with unaligned data, but it is slow.  */
-#define STRICT_ALIGNMENT TARGET_OLD_ALIGN
+#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN
 
 /* Specify alignment for string literals (which might be higher than the
-   base type's minimnal alignment requirement.  This allows strings to be
+   base type's minimal alignment requirement.  This allows strings to be
    aligned on word boundaries, and optimizes calls to the str* and mem*
    library functions.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN) \
-  (i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP))) > (ALIGN) \
+  (TREE_CODE (EXP) == STRING_CST       \
+   && i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP))) > (ALIGN) \
    ? i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP)))      \
    : (ALIGN))
 
+/* Make XFmode floating point quantities be 128 bit aligned.  */
+#define DATA_ALIGNMENT(TYPE, ALIGN)                                    \
+  (TREE_CODE (TYPE) == ARRAY_TYPE                                      \
+   && TYPE_MODE (TREE_TYPE (TYPE)) == XFmode                           \
+   && (ALIGN) < 128 ? 128 : (ALIGN))
+
 /* Macros to determine size of aggregates (structures and unions
    in C).  Normally, these may be defined to simply return the maximum
    alignment and simple rounded-up size, but on some machines (like
@@ -383,14 +413,16 @@ extern int target_flags;
    rounding method.  */
 
 #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED)            \
-  ((!TARGET_OLD_ALIGN && TREE_CODE (TYPE) == RECORD_TYPE)      \
-   ? i960_round_align ((SPECIFIED), TYPE_SIZE (TYPE))          \
-   : MAX ((COMPUTED), (SPECIFIED)))
-
-#define ROUND_TYPE_SIZE(TYPE, SIZE, ALIGN)                     \
-  ((!TARGET_OLD_ALIGN && TREE_CODE (TYPE) == RECORD_TYPE)      \
-   ? (tree) i960_round_size (SIZE)                             \
-   : round_up ((SIZE), (ALIGN)))
+  ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode)          \
+   ? 128  /* Put 80 bit floating point elements on 128 bit boundaries.  */ \
+   : ((!TARGET_OLD_ALIGN && !TYPE_PACKED (TYPE)                                   \
+       && TREE_CODE (TYPE) == RECORD_TYPE)                                \
+      ? i960_round_align (MAX ((COMPUTED), (SPECIFIED)), TYPE_SIZE (TYPE)) \
+      : MAX ((COMPUTED), (SPECIFIED))))
+
+#define ROUND_TYPE_SIZE(TYPE, COMPUTED, SPECIFIED)             \
+  ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode)       \
+   ? build_int_2 (128, 0) : round_up (COMPUTED, SPECIFIED))
 \f
 /* Standard register usage.  */
 
@@ -439,6 +471,9 @@ extern int target_flags;
        r1 is the stack pointer,
        r2 is the return instruction pointer,
        r3-r15 are always available,
+       r3 is clobbered by calls in functions that use the arg pointer
+       r4-r11 may be clobbered by the mcount call when profiling
+       r4-r15 if otherwise unused may be used for preserving global registers
        fp0..fp3 are never available.  */
 #define CALL_USED_REGISTERS  \
  {1, 1, 1, 1, 1, 1, 1, 1,      \
@@ -470,7 +505,7 @@ extern int target_flags;
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    On 80960, the cpu registers can hold any mode but the float registers
-   can only hold SFmode, DFmode, or TFmode.  */
+   can only hold SFmode, DFmode, or XFmode.  */
 extern unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER];
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
   ((hard_regno_mode_ok[REGNO] & (1 << (int) (MODE))) != 0)
@@ -503,13 +538,20 @@ extern unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER];
    Zero means the frame pointer need not be set up (and parms
    may be accessed via the stack pointer) in functions that seem suitable.
    This is computed in `reload', in reload1.c.  */
+/* ??? It isn't clear to me why this is here.  Perhaps because of a bug (since
+   fixed) in the definition of INITIAL_FRAME_POINTER_OFFSET which would have
+   caused this to fail.  */
 #define FRAME_POINTER_REQUIRED (! leaf_function_p ())
 
 /* C statement to store the difference between the frame pointer
-   and the stack pointer values immediately after the function prologue.  */
+   and the stack pointer values immediately after the function prologue.
+
+   Since the stack grows upward on the i960, this must be a negative number.
+   This includes the 64 byte hardware register save area and the size of
+   the frame.  */
 
 #define INITIAL_FRAME_POINTER_OFFSET(VAR) \
-  do { (VAR) = compute_frame_size (get_frame_size ()); } while (0)
+  do { (VAR) = - (64 + compute_frame_size (get_frame_size ())); } while (0)
 
 /* Base register for access to arguments of the function.  */
 #define ARG_POINTER_REGNUM 14
@@ -623,19 +665,18 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS,
 #define CONST_OK_FOR_LETTER_P(VALUE, C)                                \
   ((C) == 'I' ? (((unsigned) (VALUE)) <= 31)                           \
    : (C) == 'J' ? ((VALUE) == 0)                                       \
-      : (C) == 'K' ? ((VALUE) > -32 && (VALUE) <= 0)                   \
-       : 0)
+   : (C) == 'K' ? ((VALUE) >= -31 && (VALUE) <= 0)                     \
+   : (C) == 'M' ? ((VALUE) >= -32 && (VALUE) <= 0)                     \
+   : 0)
 
 /* Similar, but for floating constants, and defining letters G and H.
    Here VALUE is the CONST_DOUBLE rtx itself.
    For the 80960, G is 0.0 and H is 1.0.  */
 
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)         \
-  ((TARGET_NUMERICS) &&                                        \
-   (((C) == 'G' && ((VALUE) == CONST0_RTX (DFmode)     \
-                   || (VALUE) == CONST0_RTX (SFmode))) \
-    || ((C) == 'H' && ((VALUE) == CONST1_RTX (DFmode)  \
-                      || (VALUE) == CONST1_RTX (SFmode)))))
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)                         \
+  ((TARGET_NUMERICS) &&                                                        \
+   (((C) == 'G' && (VALUE) == CONST0_RTX (GET_MODE (VALUE)))           \
+    || ((C) == 'H' && ((VALUE) == CONST1_RTX (GET_MODE (VALUE))))))
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
@@ -709,10 +750,11 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS,
 
 /* Value is 1 if returning from a function call automatically
    pops the arguments described by the number-of-args field in the call.
+   FUNDECL is the declaration node of the function (as a tree),
    FUNTYPE is the data type of the function (as a tree),
    or for a library call it is an identifier node for the subroutine name.  */
 
-#define RETURN_POPS_ARGS(FUNTYPE, SIZE) 0
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
@@ -723,7 +765,7 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS,
    as seen by the caller.
    On 80960, returns are in g0..g3 */
 
-#define FUNCTION_VALUE_REGNO_P(N) ((N) < 4)
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
 
 /* 1 if N is a possible register number for function argument passing.
    On 80960, parameters are passed in g0..g11 */
@@ -766,7 +808,7 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; };
 
 /* Define how to round to the next parameter boundary.
    This macro is used only in macro definitions below and/or i960.c.  */
-#define ROUND(X, MULTIPLE_OF)  \
+#define ROUND_PARM(X, MULTIPLE_OF)     \
   ((((X) + (MULTIPLE_OF) - 1) / (MULTIPLE_OF)) * MULTIPLE_OF)
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -775,7 +817,7 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; };
 
    On 80960, the offset always starts at 0; the first parm reg is g0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME      \
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)      \
   ((CUM).ca_nregparms = 0, (CUM).ca_nstackparms = 0)
 
 /* Update the data in CUM to advance over an argument
@@ -790,8 +832,13 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; };
 /* Indicate the alignment boundary for an argument of the specified mode and
    type.  */
 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE)                              \
-  ((TYPE) && TYPE_ALIGN (TYPE) > PARM_BOUNDARY ? TYPE_ALIGN (TYPE)     \
-   : PARM_BOUNDARY)
+  (((TYPE) != 0)                                                       \
+   ? ((TYPE_ALIGN (TYPE) <= PARM_BOUNDARY)                             \
+      ? PARM_BOUNDARY                                                  \
+      : TYPE_ALIGN (TYPE))                                             \
+   : ((GET_MODE_ALIGNMENT (MODE) <= PARM_BOUNDARY)                     \
+      ? PARM_BOUNDARY                                                  \
+      : GET_MODE_ALIGNMENT (MODE)))
 
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
@@ -815,13 +862,18 @@ extern struct rtx_def *i960_function_arg ();
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.  */
 
-extern struct rtx_def *i960_function_value ();
-#define FUNCTION_VALUE(TYPE, FUNC) i960_function_value (TYPE)
+#define FUNCTION_VALUE(TYPE, FUNC) \
+  gen_rtx (REG, TYPE_MODE (TYPE), 0)
+
+/* Force aggregates and objects larger than 16 bytes to be returned in memory,
+   since we only have 4 registers available for return values.  */
 
-/* Force objects larger than 16 bytes to be returned in memory, since we
-   only have 4 registers available for return values.  */
+#define RETURN_IN_MEMORY(TYPE) \
+  (TYPE_MODE (TYPE) == BLKmode || int_size_in_bytes (TYPE) > 16)
 
-#define RETURN_IN_MEMORY(TYPE) (int_size_in_bytes (TYPE) > 16)
+/* Don't default to pcc-struct-return, because we have already specified
+   exactly how to return structures in the RETURN_IN_MEMORY macro.  */
+#define DEFAULT_PCC_STRUCT_RETURN 0
 
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
@@ -848,8 +900,8 @@ extern struct rtx_def *i960_function_value ();
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
-#define FUNCTION_PROFILER(FILE, LABELNO)  \
-  fprintf (FILE, "\tlda        LP%d,g0\n\tbal  mcount\n", (LABELNO))
+#define FUNCTION_PROFILER(FILE, LABELNO)       \
+  output_function_profiler ((FILE), (LABELNO));
 
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in
@@ -907,16 +959,21 @@ extern struct rtx_def *i960_function_value ();
 /* Maximum number of registers that can appear in a valid memory address.  */
 #define        MAX_REGS_PER_ADDRESS 2
 
-#define CONSTANT_ADDRESS_P(X)  CONSTANT_P (X)
+#define CONSTANT_ADDRESS_P(X)   \
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
+   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST               \
+   || GET_CODE (X) == HIGH)
 
 /* LEGITIMATE_CONSTANT_P is nonzero if the constant value X
    is a legitimate general operand.
    It is given that X satisfies CONSTANT_P.
 
-   Anything but a CONST_DOUBLE can be made to work, excepting 0.0 and 1.0.  */
+   Anything but a CONST_DOUBLE can be made to work, excepting 0.0 and 1.0.
+
+   ??? This probably should be defined to 1.  */
 
 #define LEGITIMATE_CONSTANT_P(X) \
-  ((GET_CODE (X) != CONST_DOUBLE) || fp_literal ((X), VOIDmode))
+  ((GET_CODE (X) != CONST_DOUBLE) || fp_literal ((X), GET_MODE (X)))
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
@@ -1000,7 +1057,7 @@ extern struct rtx_def *i960_function_value ();
    It is always safe for this macro to do nothing.  It exists to recognize
    opportunities to optimize the output.  */
 
-/* On 80960, convert non-cannonical addresses to canonical form.  */
+/* On 80960, convert non-canonical addresses to canonical form.  */
 
 extern struct rtx_def *legitimize_address ();
 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
@@ -1019,10 +1076,11 @@ extern struct rtx_def *legitimize_address ();
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE SImode
 
-/* Define this if the tablejump instruction expects the table
-   to contain offsets from the address of the table.
-   Do not define this if the table should contain absolute addresses.  */
-/* #define CASE_VECTOR_PC_RELATIVE */
+/* Define as C expression which evaluates to nonzero if the tablejump
+   instruction expects the table to contain offsets from the address of the
+   table.
+   Do not define this if the table should contain absolute addresses. */
+/* #define CASE_VECTOR_PC_RELATIVE 1 */
 
 /* Specify the tree operation to be used to convert reals to integers.  */
 #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
@@ -1040,9 +1098,15 @@ extern struct rtx_def *legitimize_address ();
    in one reasonably fast instruction.  */
 #define MOVE_MAX 16
 
-/* Define if normal loads of shorter-than-word items from memory clears
-   the rest of the bigs in the register.  */
-#define BYTE_LOADS_ZERO_EXTEND
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, NIL if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
 
 /* Nonzero if access to memory by bytes is no faster than for words.
    Defining this results in worse code on the i960.  */
@@ -1054,10 +1118,9 @@ extern struct rtx_def *legitimize_address ();
 
 #define STORE_FLAG_VALUE 1
 
-/* Define if shifts truncate the shift count
-   which implies one can omit a sign-extension or zero-extension
-   of a shift count.  */
-#define SHIFT_COUNT_TRUNCATED
+/* Define this to be nonzero if shift instructions ignore all but the low-order
+   few bits. */
+#define SHIFT_COUNT_TRUNCATED 0
 
 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
    is done just by pretending it is already truncated.  */
@@ -1094,7 +1157,7 @@ extern struct rtx_def *gen_compare_reg ();
    should be used.  CC_NOOVmode should be used when the first operand is a
    PLUS, MINUS, or NEG.  CCmode should be used when no special processing is
    needed.  */
-#define SELECT_CC_MODE(OP,X) select_cc_mode (OP, X)
+#define SELECT_CC_MODE(OP,X,Y) select_cc_mode (OP, X)
 
 /* A function address in a call instruction is a byte address
    (for indexing purposes) so give the MEM rtx a byte's mode.  */
@@ -1214,10 +1277,9 @@ extern struct rtx_def *gen_compare_reg ();
   assemble_name (FILE, NAME);                  \
   fputs ("\n", FILE); }
 
-/* This is how to output a reference to a user-level label named NAME.
-   `assemble_name' uses this.  */
+/* The prefix to add to user-visible assembler symbols. */
 
-#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME)
+#define USER_LABEL_PREFIX "_"
 
 /* This is how to output an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.  */
@@ -1233,6 +1295,11 @@ extern struct rtx_def *gen_compare_reg ();
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
   sprintf (LABEL, "*%s%d", PREFIX, NUM)
 
+/* This is how to output an assembler line defining a `long double'
+   constant.  */
+
+#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) i960_output_long_double(FILE, VALUE)
+
 /* This is how to output an assembler line defining a `double' constant.  */
 
 #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  i960_output_double(FILE, VALUE)
@@ -1308,7 +1375,7 @@ extern struct rtx_def *gen_compare_reg ();
       assemble_name ((FILE), (NAME)),                  \
       fputs ("\n.comm ", (FILE)),                      \
       assemble_name ((FILE), (NAME)),                  \
-      fprintf ((FILE), ",%d\n", (ROUNDED));            \
+      fprintf ((FILE), ",%d\n", (SIZE));               \
     }                                                  \
 }
 
@@ -1320,10 +1387,20 @@ extern struct rtx_def *gen_compare_reg ();
 ( fputs (".bss\t", (FILE)),                    \
   assemble_name ((FILE), (NAME)),              \
   fprintf ((FILE), ",%d,%d\n", (SIZE),         \
-          ((ALIGN) <= 8 ? 0                    \
-           : ((ALIGN) <= 16 ? 1                \
-              : ((ALIGN) <= 32 ? 2             \
-                 : ((ALIGN <= 64 ? 3 : 4)))))))
+          (floor_log2 ((ALIGN) / BITS_PER_UNIT))))
+
+/* A C statement (sans semicolon) to output to the stdio stream
+   FILE the assembler definition of uninitialized global DECL named
+   NAME whose size is SIZE bytes and alignment is ALIGN bytes.
+   Try to use asm_output_aligned_bss to implement this macro.  */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)  \
+  do {                                                         \
+    fputs (".globl ", (FILE));                                 \
+    assemble_name ((FILE), (NAME));                            \
+    fputs ("\n", (FILE));                                      \
+    ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);                \
+  } while (0)
 
 /* Output text for an #ident directive.  */
 #define        ASM_OUTPUT_IDENT(FILE, STR)  fprintf(FILE, "\t# %s\n", STR);
@@ -1421,7 +1498,7 @@ extern struct rtx_def *gen_compare_reg ();
 }
 
 #if 0
-/* Promote char and short arguments to ints, when want compitibility with
+/* Promote char and short arguments to ints, when want compatibility with
    the iC960 compilers.  */
 
 /* ??? In order for this to work, all users would need to be changed
@@ -1450,6 +1527,7 @@ extern enum insn_types i960_last_insn_type;
   {"fpmove_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,  \
                          LABEL_REF, SUBREG, REG, MEM}},                \
   {"arith_operand", {SUBREG, REG, CONST_INT}},                         \
+  {"logic_operand", {SUBREG, REG, CONST_INT}},                         \
   {"fp_arith_operand", {SUBREG, REG, CONST_DOUBLE}},                   \
   {"signed_arith_operand", {SUBREG, REG, CONST_INT}},                  \
   {"literal", {CONST_INT}},                                            \
@@ -1461,10 +1539,37 @@ extern enum insn_types i960_last_insn_type;
   {"eq_or_neq", {EQ, NE}},                                             \
   {"arith32_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST_INT,  \
                       CONST_DOUBLE, CONST}},                           \
-  {"power2_operand", {CONST_INT}},
+  {"power2_operand", {CONST_INT}},                                     \
+  {"cmplpower2_operand", {CONST_INT}},
 
 /* Define functions in i960.c and used in insn-output.c.  */
 
 extern char *i960_output_ldconst ();
 extern char *i960_output_call_insn ();
 extern char *i960_output_ret_insn ();
+extern char *i960_output_move_double ();
+extern char *i960_output_move_quad ();
+
+/* Defined in reload.c, and used in insn-recog.c.  */
+
+extern int rtx_equal_function_value_matters;
+
+/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
+   Used for C++ multiple inheritance.  */
+#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
+do {                                                                   \
+  int d = (DELTA);                                                     \
+  if (d < 0 && d > -32)                                                        \
+    fprintf (FILE, "\tsubo %d,g0,g0\n", -d);                           \
+  else if (d > 0 && d < 32)                                            \
+    fprintf (FILE, "\taddo %d,g0,g0\n", d);                            \
+  else                                                                 \
+    {                                                                  \
+      fprintf (FILE, "\tldconst %d,r5\n", d);                          \
+      fprintf (FILE, "\taddo r5,g0,g0\n");                             \
+    }                                                                  \
+  fprintf (FILE, "\tbx ");                                             \
+  assemble_name                                                                \
+    (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION)));       \
+  fprintf (FILE, "\n");                                                        \
+} while (0);