OSDN Git Service

* flags.h: New flag (optimize_size).
[pf3gnuchains/gcc-fork.git] / gcc / config / i960 / i960.h
index 265a2e6..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,17 +18,20 @@ 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}\
+                       %{mja:-D__i960JA}%{mjd:-D__i960JD}%{mjf:-D__i960JF}\
+                       %{mrp:-D__i960RP}\
                        %{msa:-D__i960SA}%{msb:-D__i960SB}\
                        %{mmc:-D__i960MC}\
                        %{mca:-D__i960CA}%{mcc:-D__i960CC}\
@@ -45,16 +48,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                %{!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:%{!msa:%{!msb:%{!mmc:%{!mca:%{!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
@@ -62,8 +71,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define ASM_SPEC \
        "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\
        %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\
-       %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:-AKB}}}}}}}}\
-       %{mlink-relax:-link-relax}"
+        %{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
@@ -71,7 +81,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define LINK_SPEC \
        "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\
        %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\
-       %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:-AKB}}}}}}}}\
+        %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX}\
        %{mbout:-Fbout}%{mcoff:-Fcoff}\
        %{mlink-relax:-relax}"
 
@@ -80,12 +90,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define LIB_SPEC "%{!nostdlib:-lcg %{p:-lprof}%{pg:-lgprof}\
          %{mka:-lfpg}%{msa:-lfpg}%{mca:-lfpg}%{mcf:-lfpg} -lgnu}"
 
-/* Omit frame pointer at -O2.  Inline functions at -O3.  */
-#define OPTIMIZATION_OPTIONS(LEVEL)            \
+/* Show we can debug even without a frame pointer.  */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* 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;    \
     }                                          \
@@ -99,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.  */
 
@@ -118,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.  */
@@ -211,6 +230,11 @@ extern int target_flags;
                        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|\
@@ -241,12 +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.  */
@@ -287,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
@@ -356,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 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
@@ -374,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.  */
 
@@ -430,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,      \
@@ -461,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)
@@ -494,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
@@ -614,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.
@@ -700,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.  */
@@ -714,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 +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
@@ -814,10 +865,15 @@ extern struct rtx_def *i960_function_arg ();
 #define FUNCTION_VALUE(TYPE, FUNC) \
   gen_rtx (REG, TYPE_MODE (TYPE), 0)
 
-/* Force objects larger than 16 bytes to be returned in memory, since we
-   only have 4 registers available for return values.  */
+/* Force aggregates and 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) (int_size_in_bytes (TYPE) > 16)
+#define RETURN_IN_MEMORY(TYPE) \
+  (TYPE_MODE (TYPE) == BLKmode || 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.
@@ -844,8 +900,8 @@ extern struct rtx_def *i960_function_arg ();
 /* 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
@@ -903,16 +959,21 @@ extern struct rtx_def *i960_function_arg ();
 /* 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.
@@ -1015,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
@@ -1036,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.  */
@@ -1050,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.  */
@@ -1210,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.  */
@@ -1229,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)
@@ -1304,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));               \
     }                                                  \
 }
 
@@ -1316,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);
@@ -1446,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}},                                            \
@@ -1457,14 +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);