/* 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.
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. */
/* 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. */
#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. */
#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)
{ {"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)}, \
{"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. */
}
/* 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
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. */
/* 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
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. */
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, \
/* 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)
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
#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.
/* 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. */
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 */
/* 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
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
/* 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,
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.
/* 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
/* 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.
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) \
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
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. */
#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. */
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. */
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. */
#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)
assemble_name ((FILE), (NAME)), \
fputs ("\n.comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%d\n", (ROUNDED)); \
+ fprintf ((FILE), ",%d\n", (SIZE)); \
} \
}
( 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);
}
#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
{"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}}, \
{"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);