BLOCK_MOVE_LAST /* generate just the last store */
};
+/* Information about one recognised processor. Defined here for the
+ benefit of TARGET_CPU_CPP_BUILTINS. */
+struct mips_cpu_info {
+ /* The 'canonical' name of the processor as far as GCC is concerned.
+ It's typically a manufacturer's prefix followed by a numerical
+ designation. It should be lower case. */
+ const char *name;
+
+ /* The internal processor number that most closely matches this
+ entry. Several processors can have the same value, if there's no
+ difference between them from GCC's point of view. */
+ enum processor_type cpu;
+
+ /* The ISA level that the processor implements. */
+ int isa;
+};
+
extern char mips_reg_names[][8]; /* register names (a0 vs. $4). */
extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */
extern int mips16; /* whether generating mips16 code */
extern int mips16_hard_float; /* mips16 without -msoft-float */
extern int mips_entry; /* generate entry/exit for mips16 */
-extern const char *mips_cpu_string; /* for -mcpu=<xxx> */
extern const char *mips_arch_string; /* for -march=<xxx> */
extern const char *mips_tune_string; /* for -mtune=<xxx> */
extern const char *mips_isa_string; /* for -mips{1,2,3,4} */
extern const char *mips_abi_string; /* for -mabi={32,n32,64} */
extern const char *mips_entry_string; /* for -mentry */
extern const char *mips_no_mips16_string;/* for -mno-mips16 */
-extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
extern int mips_split_addresses; /* perform high/lo_sum support */
extern int dslots_load_total; /* total # load related delay slots */
extern GTY(()) rtx mips_load_reg3; /* 3rd reg to check for load delay */
extern GTY(()) rtx mips_load_reg4; /* 4th reg to check for load delay */
extern int mips_string_length; /* length of strings for mips16 */
+extern const struct mips_cpu_info mips_cpu_info_table[];
+extern const struct mips_cpu_info *mips_arch_info;
+extern const struct mips_cpu_info *mips_tune_info;
/* Functions to change what output section we are using. */
extern void sdata_section PARAMS ((void));
#define MASK_DEBUG_E 0 /* function_arg debug */
#define MASK_DEBUG_F 0 /* ??? */
#define MASK_DEBUG_G 0 /* don't support 64 bit arithmetic */
-#define MASK_DEBUG_H 0 /* allow ints in FP registers */
#define MASK_DEBUG_I 0 /* unused */
/* Dummy switches used only in specs */
#define TARGET_DEBUG_E_MODE (target_flags & MASK_DEBUG_E)
#define TARGET_DEBUG_F_MODE (target_flags & MASK_DEBUG_F)
#define TARGET_DEBUG_G_MODE (target_flags & MASK_DEBUG_G)
-#define TARGET_DEBUG_H_MODE (target_flags & MASK_DEBUG_H)
#define TARGET_DEBUG_I_MODE (target_flags & MASK_DEBUG_I)
/* Reg. Naming in .s ($21 vs. $a0) */
#define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000)
#define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000)
+/* Define preprocessor macros for the -march and -mtune options.
+ PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected
+ processor. If INFO's canonical name is "foo", define PREFIX to
+ be "foo", and define an additional macro PREFIX_FOO. */
+#define MIPS_CPP_SET_PROCESSOR(PREFIX, INFO) \
+ do \
+ { \
+ char *macro, *p; \
+ \
+ macro = concat ((PREFIX), "_", (INFO)->name, NULL); \
+ for (p = macro; *p != 0; p++) \
+ *p = TOUPPER (*p); \
+ \
+ builtin_define (macro); \
+ builtin_define_with_value ((PREFIX), (INFO)->name, 1); \
+ free (macro); \
+ } \
+ while (0)
+
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
do \
if (!flag_iso) \
builtin_define ("mips"); \
\
+ /* Treat _R3000 and _R4000 like register-size defines, \
+ which is how they've historically been used. */ \
if (TARGET_64BIT) \
{ \
builtin_define ("__mips64"); \
- /* Silly, but will do until processor defines. */ \
builtin_define_std ("R4000"); \
builtin_define ("_R4000"); \
} \
else \
{ \
- /* Ditto. */ \
builtin_define_std ("R3000"); \
builtin_define ("_R3000"); \
} \
if (TARGET_MIPS16) \
builtin_define ("__mips16"); \
\
+ MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \
+ MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \
+ \
if (ISA_MIPS1) \
{ \
builtin_define ("__mips=1"); \
N_("Work around early 4300 hardware bug")}, \
{"no-fix4300", -MASK_4300_MUL_FIX, \
N_("Don't work around early 4300 hardware bug")}, \
- {"3900", 0, \
- N_("Optimize for 3900")}, \
- {"4650", 0, \
- N_("Optimize for 4650")}, \
{"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \
N_("Trap on integer divide by zero")}, \
{"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \
NULL}, \
{"debugg", MASK_DEBUG_G, \
NULL}, \
- {"debugh", MASK_DEBUG_H, \
- NULL}, \
{"debugi", MASK_DEBUG_I, \
NULL}, \
{"", (TARGET_DEFAULT \
#define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
#endif
+/* 'from-abi' makes a good default: you get whatever the ABI requires. */
#ifndef MIPS_ISA_DEFAULT
-#define MIPS_ISA_DEFAULT 1
+#ifndef MIPS_CPU_STRING_DEFAULT
+#define MIPS_CPU_STRING_DEFAULT "from-abi"
+#endif
#endif
#ifdef IN_LIBGCC2
#endif
#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT }
+#define MULTILIB_DEFAULTS \
+ { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT, MULTILIB_ABI_DEFAULT }
#endif
/* We must pass -EL to the linker by default for little endian embedded
#define TARGET_OPTIONS \
{ \
SUBTARGET_TARGET_OPTIONS \
- { "cpu=", &mips_cpu_string, \
- N_("Specify CPU for scheduling purposes")}, \
- { "tune=", &mips_tune_string, \
+ { "tune=", &mips_tune_string, \
N_("Specify CPU for scheduling purposes")}, \
{ "arch=", &mips_arch_string, \
N_("Specify CPU for code generation purposes")}, \
+ { "abi=", &mips_abi_string, \
+ N_("Specify an ABI")}, \
{ "ips", &mips_isa_string, \
N_("Specify a Standard MIPS ISA")}, \
{ "entry", &mips_entry_string, \
N_("Use mips16 entry/exit psuedo ops")}, \
{ "no-mips16", &mips_no_mips16_string, \
N_("Don't use MIPS16 instructions")}, \
- { "explicit-type-size", &mips_explicit_type_size_string, \
- NULL}, \
{ "no-flush-func", &mips_cache_flush_func, \
N_("Don't call any cache flush functions")}, \
{ "flush-func=", &mips_cache_flush_func, \
#define BRANCH_LIKELY_P() GENERATE_BRANCHLIKELY
#define HAVE_SQRT_P() (!ISA_MIPS1)
+/* True if the ABI can only work with 64-bit integer registers. We
+ generally allow ad-hoc variations for TARGET_SINGLE_FLOAT, but
+ otherwise floating-point registers must also be 64-bit. */
+#define ABI_NEEDS_64BIT_REGS (mips_abi == ABI_64 \
+ || mips_abi == ABI_O64 \
+ || mips_abi == ABI_N32)
+
+/* Likewise for 32-bit regs. */
+#define ABI_NEEDS_32BIT_REGS (mips_abi == ABI_32)
+
/* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3). */
-#define ISA_HAS_64BIT_REGS (ISA_MIPS3 \
- || ISA_MIPS4 \
+#define ISA_HAS_64BIT_REGS (ISA_MIPS3 \
+ || ISA_MIPS4 \
|| ISA_MIPS64)
/* ISA has branch likely instructions (eg. mips2). */
/* Disable branchlikely for tx39 until compare rewrite. They haven't
been generated up to this point. */
-#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 \
+#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 \
&& !TARGET_MIPS16)
/* ISA has the conditional move instructions introduced in mips4. */
|| ISA_MIPS64)
/* This is a catch all for the other new mips4 instructions: indexed load and
- indexed prefetch instructions, the FP madd,msub,nmadd, and nmsub
- instructions, and the FP recip and recip sqrt instructions */
+ indexed prefetch instructions, the FP madd and msub instructions,
+ and the FP recip and recip sqrt instructions */
#define ISA_HAS_FP4 ((ISA_MIPS4 \
|| ISA_MIPS64) \
&& !TARGET_MIPS16)
#define ISA_HAS_DCLZ_DCLO (ISA_MIPS64 \
&& !TARGET_MIPS16)
+/* ISA has data prefetch instruction. */
+#define ISA_HAS_PREFETCH ((ISA_MIPS4 \
+ || ISA_MIPS32 \
+ || ISA_MIPS64) \
+ && !TARGET_MIPS16)
+
+/* True if trunc.w.s and trunc.w.d are real (not synthetic)
+ instructions. Both require TARGET_HARD_FLOAT, and trunc.w.d
+ also requires TARGET_DOUBLE_FLOAT. */
+#define ISA_HAS_TRUNC_W (!ISA_MIPS1)
+
/* CC1_SPEC causes -mips3 and -mips4 to set -mfp64 and -mgp64; -mips1 or
-mips2 sets -mfp32 and -mgp32. This can be overridden by an explicit
-mfp32, -mfp64, -mgp32 or -mgp64. -mfp64 sets MASK_FLOAT64 in
/* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
assembler. */
-#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
+#define GAS_ASM_SPEC "%{mtune=*} %{v}"
extern int mips_abi;
#define MIPS_ABI_DEFAULT ABI_32
#endif
-#ifndef ABI_GAS_ASM_SPEC
-#define ABI_GAS_ASM_SPEC ""
+/* Use the most portable ABI flag for the ASM specs. */
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define MULTILIB_ABI_DEFAULT "mabi=32"
+#define ASM_ABI_DEFAULT_SPEC "-32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define MULTILIB_ABI_DEFAULT "mabi=o64"
+#define ASM_ABI_DEFAULT_SPEC "-mabi=o64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_N32
+#define MULTILIB_ABI_DEFAULT "mabi=n32"
+#define ASM_ABI_DEFAULT_SPEC "-n32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_64
+#define MULTILIB_ABI_DEFAULT "mabi=64"
+#define ASM_ABI_DEFAULT_SPEC "-64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_EABI
+#define MULTILIB_ABI_DEFAULT "mabi=eabi"
+#define ASM_ABI_DEFAULT_SPEC "-mabi=eabi"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
+/* Most GAS don't know about MEABI. */
+#define MULTILIB_ABI_DEFAULT "mabi=meabi"
+#define ASM_ABI_DEFAULT_SPEC ""
+#endif
+
+/* Only ELF targets can switch the ABI. */
+#ifndef OBJECT_FORMAT_ELF
+#undef ASM_ABI_DEFAULT_SPEC
+#define ASM_ABI_DEFAULT_SPEC ""
#endif
/* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
#define SUBTARGET_ASM_SPEC ""
#endif
-/* ASM_SPEC is the set of arguments to pass to the assembler. */
+/* ASM_SPEC is the set of arguments to pass to the assembler. Note: we
+ pass -mgp32, -mgp64, -march, -mabi=eabi and -meabi=o64 regardless of
+ whether we're using GAS. These options can only be used properly
+ with GAS, and it is better to get an error from a non-GAS assembler
+ than to silently generate bad code. */
#undef ASM_SPEC
#define ASM_SPEC "\
%(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \
%{membedded-pic} \
-%{mabi=32:-32}%{mabi=o32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
+%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
+%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \
+%{mgp32} %{mgp64} %{march=*} \
%(target_asm_spec) \
%(subtarget_asm_spec)"
#define SUBTARGET_CC1_SPEC ""
#endif
-/* Deal with historic options. */
-#ifndef CC1_CPU_SPEC
-#define CC1_CPU_SPEC "\
-%{!mcpu*: \
-%{m3900:-march=r3900 -mips1 -mfp32 -mgp32 \
-%n`-m3900' is deprecated. Use `-march=r3900' instead.\n} \
-%{m4650:-march=r4650 -mmad -msingle-float \
-%n`-m4650' is deprecated. Use `-march=r4650' instead.\n}}"
-#endif
-
/* CC1_SPEC is the set of arguments to pass to the compiler proper. */
/* Note, we will need to adjust the following if we ever find a MIPS variant
that has 32-bit GPRs and 64-bit FPRs as well as fix all of the reload bugs
#ifndef CC1_SPEC
#define CC1_SPEC "\
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
-%{mips1:-mfp32 -mgp32} %{mips2:-mfp32 -mgp32}\
-%{mips3:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
-%{mips4:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
-%{mips32:-mfp32 -mgp32} \
-%{mips64:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
-%{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
-%{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
-%{mint64|mlong64|mlong32:-mexplicit-type-size }\
-%{mgp32: %{mfp64:%emay not use both -mgp32 and -mfp64} %{!mfp32: -mfp32}} \
%{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
%{save-temps: } \
-%(subtarget_cc1_spec) \
-%(cc1_cpu_spec)"
+%(subtarget_cc1_spec)"
#endif
/* Preprocessor specs. */
#define EXTRA_SPECS \
{ "subtarget_cc1_spec", SUBTARGET_CC1_SPEC }, \
- { "cc1_cpu_spec", CC1_CPU_SPEC}, \
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
{ "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \
{ "gas_asm_spec", GAS_ASM_SPEC }, \
- { "abi_gas_asm_spec", ABI_GAS_ASM_SPEC }, \
{ "target_asm_spec", TARGET_ASM_SPEC }, \
{ "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \
{ "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC }, \
{ "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC }, \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
+ { "asm_abi_default_spec", ASM_ABI_DEFAULT_SPEC }, \
{ "endian_spec", ENDIAN_SPEC }, \
SUBTARGET_EXTRA_SPECS
#define PUT_SDB_FUNCTION_START(LINE)
-#define PUT_SDB_FUNCTION_END(LINE) \
-do { \
- extern FILE *asm_out_text_file; \
+#define PUT_SDB_FUNCTION_END(LINE) \
+do { \
+ extern FILE *asm_out_text_file; \
ASM_OUTPUT_SOURCE_LINE (asm_out_text_file, LINE + sdb_begin_function_line); \
} while (0)
#define PUT_SDB_EPILOGUE_END(NAME)
-#define PUT_SDB_SRC_FILE(FILENAME) \
+#define PUT_SDB_SRC_FILE(FILENAME) \
do { \
extern FILE *asm_out_text_file; \
- output_file_directive (asm_out_text_file, (FILENAME)); \
+ output_file_directive (asm_out_text_file, (FILENAME));\
} while (0)
-#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
+#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
sprintf ((BUFFER), ".%dfake", (NUMBER));
/* Correct the offset of automatic variables and arguments. Note that
the frame pointer to be the stack pointer after the initial
adjustment. */
-#define DEBUGGER_AUTO_OFFSET(X) \
+#define DEBUGGER_AUTO_OFFSET(X) \
mips_debugger_offset (X, (HOST_WIDE_INT) 0)
-#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
mips_debugger_offset (X, (HOST_WIDE_INT) OFFSET)
/* Tell collect that the object format is ECOFF */
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally.
- When FP regs are larger than integer regs... Er, anyone remember what
- goes wrong?
In little-endian mode, the hi-lo registers are numbered backwards,
so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
- word as intended. */
+ word as intended.
+
+ Similarly, when using paired floating-point registers, the first
+ register holds the low word, regardless of endianness. So in big
+ endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word
+ as intended.
+
+ Also, loading a 32-bit value into a 64-bit floating-point register
+ will not sign-extend the value, despite what LOAD_EXTEND_OP says.
+ We can't allow 64-bit float registers to change from a 32-bit
+ mode to a 64-bit mode. */
#define CLASS_CANNOT_CHANGE_MODE \
- (TARGET_BIG_ENDIAN \
- ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS) \
- : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
+ (TARGET_BIG_ENDIAN ? FP_REGS \
+ : (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
-/* Structure to be filled in by compute_frame_size with register
- save masks, and offsets for the current function. */
-
-struct mips_frame_info
-{
- long total_size; /* # bytes that the entire frame takes up */
- long var_size; /* # bytes that variables take up */
- long args_size; /* # bytes that outgoing arguments take up */
- long extra_size; /* # bytes of extra gunk */
- int gp_reg_size; /* # bytes needed to store gp regs */
- int fp_reg_size; /* # bytes needed to store fp regs */
- long mask; /* mask of saved gp registers */
- long fmask; /* mask of saved fp registers */
- long gp_save_offset; /* offset from vfp to store gp registers */
- long fp_save_offset; /* offset from vfp to store fp registers */
- long gp_sp_offset; /* offset from new sp to store gp registers */
- long fp_sp_offset; /* offset from new sp to store fp registers */
- int initialized; /* != 0 if frame size already calculated */
- int num_gp; /* number of gp registers saved */
- int num_fp; /* number of fp registers saved */
- long insns_len; /* length of insns; mips16 only */
-};
-
-extern struct mips_frame_info current_frame_info;
-
/* If defined, this macro specifies a table of register pairs used to
eliminate unneeded registers that point into the stack frame. If
it is not defined, the only elimination attempted by the compiler
&& (! TARGET_MIPS16 \
|| compute_frame_size (get_frame_size ()) < 32768)))))
-/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
- specifies the initial difference between the specified pair of
- registers. This macro must be defined if `ELIMINABLE_REGS' is
- defined. */
-
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ compute_frame_size (get_frame_size ()); \
- if (TARGET_MIPS16 && (FROM) == FRAME_POINTER_REGNUM \
- && (TO) == HARD_FRAME_POINTER_REGNUM) \
- (OFFSET) = - current_function_outgoing_args_size; \
- else if ((FROM) == FRAME_POINTER_REGNUM) \
- (OFFSET) = 0; \
- else if (TARGET_MIPS16 && (FROM) == ARG_POINTER_REGNUM \
- && (TO) == HARD_FRAME_POINTER_REGNUM) \
- (OFFSET) = (current_frame_info.total_size \
- - current_function_outgoing_args_size \
- - ((mips_abi != ABI_32 \
- && mips_abi != ABI_O64 \
- && mips_abi != ABI_EABI) \
- ? current_function_pretend_args_size \
- : 0)); \
- else if ((FROM) == ARG_POINTER_REGNUM) \
- (OFFSET) = (current_frame_info.total_size \
- - ((mips_abi != ABI_32 \
- && mips_abi != ABI_O64 \
- && mips_abi != ABI_EABI) \
- ? current_function_pretend_args_size \
- : 0)); \
- /* Some ABIs store 64 bits to the stack, but Pmode is 32 bits, \
- so we must add 4 bytes to the offset to get the right value. */ \
- else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM) \
- { \
- (OFFSET) = current_frame_info.gp_sp_offset \
- + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT)) \
- * (BYTES_BIG_ENDIAN != 0)); \
- if (TARGET_MIPS16 && (TO) != STACK_POINTER_REGNUM) \
- (OFFSET) -= current_function_outgoing_args_size; \
- } \
- else \
- abort(); \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ (OFFSET) = mips_initial_elimination_offset ((FROM), (TO))
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
/* For o64 we should be checking the mode for SFmode as well. */
#define FUNCTION_ARG_REGNO_P(N) \
- ((((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST) \
- || ((N) >= FP_ARG_FIRST && (N) <= FP_ARG_LAST \
- && (((N) % FP_INC) == 0 \
- && (! mips_abi == ABI_O64))) \
- && !fixed_regs[N]))
+ ((IN_RANGE((N), GP_ARG_FIRST, GP_ARG_LAST) \
+ || (IN_RANGE((N), FP_ARG_FIRST, FP_ARG_LAST) \
+ && ((N) % FP_INC == 0) && mips_abi != ABI_O64)) \
+ && !fixed_regs[N])
/* A C expression which can inhibit the returning of certain function
values in registers, based on the type of value. A nonzero value says
(VALIST) = mips_build_va_list ()
/* Implement `va_start' for varargs and stdarg. */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
- mips_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+ mips_va_start (valist, nextarg)
/* Implement `va_arg'. */
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
assembler would use $at as a temp to load in the large offset. In this
case $at is already in use. We convert such problem addresses to
`la $5,s;sw $4,70000($5)' via LEGITIMIZE_ADDRESS. */
-/* ??? SGI Irix 6 assembler fails for CONST address, so reject them. */
+/* ??? SGI Irix 6 assembler fails for CONST address, so reject them
+ when !TARGET_GAS. */
+/* We should be rejecting everything but const addresses. */
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X)) \
- && (mips_abi == ABI_32 \
- || mips_abi == ABI_O64 \
- || mips_abi == ABI_EABI)))
+ && (TARGET_GAS) \
+ && (mips_abi != ABI_N32 \
+ && mips_abi != ABI_64)))
+
/* Define this, so that when PIC, reload won't try to reload invalid
addresses which require two reload registers. */
if (GET_CODE (xinsn) == CONST \
&& ((flag_pic && pic_address_needs_scratch (xinsn)) \
/* ??? SGI's Irix 6 assembler can't handle CONST. */ \
- || (mips_abi != ABI_32 \
- && mips_abi != ABI_O64 \
- && mips_abi != ABI_EABI))) \
+ || (!TARGET_GAS \
+ && (mips_abi == ABI_N32 \
+ || mips_abi == ABI_64)))) \
{ \
rtx ptr_reg = gen_reg_rtx (Pmode); \
rtx constant = XEXP (XEXP (xinsn, 0), 1); \
enum machine_mode xmode = GET_MODE (X); \
if (xmode == SFmode) \
{ \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900 \
- || TUNE_MIPS5000) \
+ if (TUNE_MIPS3000 \
+ || TUNE_MIPS3900 \
+ || TUNE_MIPS5000) \
return COSTS_N_INSNS (4); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (5); \
else \
return COSTS_N_INSNS (7); \
\
if (xmode == DFmode) \
{ \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900 \
- || TUNE_MIPS5000) \
+ if (TUNE_MIPS3000 \
+ || TUNE_MIPS3900 \
+ || TUNE_MIPS5000) \
return COSTS_N_INSNS (5); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (6); \
else \
return COSTS_N_INSNS (8); \
} \
\
- if (TUNE_MIPS3000) \
+ if (TUNE_MIPS3000) \
return COSTS_N_INSNS (12); \
- else if (TUNE_MIPS3900) \
+ else if (TUNE_MIPS3900) \
return COSTS_N_INSNS (2); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (17); \
- else if (TUNE_MIPS5000) \
+ else if (TUNE_MIPS5000) \
return COSTS_N_INSNS (5); \
else \
return COSTS_N_INSNS (10); \
enum machine_mode xmode = GET_MODE (X); \
if (xmode == SFmode) \
{ \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
+ if (TUNE_MIPS3000 \
+ || TUNE_MIPS3900) \
return COSTS_N_INSNS (12); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (15); \
else \
return COSTS_N_INSNS (23); \
\
if (xmode == DFmode) \
{ \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
+ if (TUNE_MIPS3000 \
+ || TUNE_MIPS3900) \
return COSTS_N_INSNS (19); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (16); \
else \
return COSTS_N_INSNS (36); \
\
case UDIV: \
case UMOD: \
- if (TUNE_MIPS3000 \
- || TUNE_MIPS3900) \
+ if (TUNE_MIPS3000 \
+ || TUNE_MIPS3900) \
return COSTS_N_INSNS (35); \
- else if (TUNE_MIPS6000) \
+ else if (TUNE_MIPS6000) \
return COSTS_N_INSNS (38); \
- else if (TUNE_MIPS5000) \
+ else if (TUNE_MIPS5000) \
return COSTS_N_INSNS (36); \
else \
return COSTS_N_INSNS (69); \
{"se_nonmemory_operand", { CONST_INT, CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF, SUBREG, \
REG, SIGN_EXTEND }}, \
- {"se_nonimmediate_operand", { SUBREG, REG, MEM, SIGN_EXTEND }}, \
{"consttable_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \
CONST_DOUBLE, CONST }}, \
{"extend_operator", { SIGN_EXTEND, ZERO_EXTEND }}, \
/* This is how to declare a function name. The actual work of
emitting the label is moved to function_prologue, so that we can
get the line number correctly emitted before the .ent directive,
- and after any .file directives. */
-/*
+ and after any .file directives. Define as empty so that the function
+ is not declared before the .ent directive elsewhere. */
+
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)
-*/
+
/* 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_OUTPUT_ASCII(STREAM, STRING, LEN) \
mips_output_ascii (STREAM, STRING, LEN)
-/* Handle certain cpp directives used in header files on sysV. */
-#define SCCS_DIRECTIVE
-
/* Output #ident as a in the read-only data section. */
#undef ASM_OUTPUT_IDENT
#define ASM_OUTPUT_IDENT(FILE, STRING) \