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 set_volatile; /* # of nested .set volatile's */
extern int mips_branch_likely; /* emit 'l' after br (branch likely) */
extern int mips_dbx_regno[]; /* Map register # to debug register # */
-extern struct rtx_def *branch_cmp[2]; /* operands for compare */
+extern GTY(()) rtx branch_cmp[2]; /* operands for compare */
extern enum cmp_type branch_type; /* what type of branch to use */
extern enum processor_type mips_arch; /* which cpu to codegen for */
extern enum processor_type mips_tune; /* which cpu to schedule for */
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 int dslots_jump_filled; /* # filled jump delay slots */
extern int dslots_number_nops; /* # of nops needed by previous insn */
extern int num_refs[3]; /* # 1/2/3 word references */
-extern struct rtx_def *mips_load_reg; /* register to check for load delay */
-extern struct rtx_def *mips_load_reg2; /* 2nd reg to check for load delay */
-extern struct rtx_def *mips_load_reg3; /* 3rd reg to check for load delay */
-extern struct rtx_def *mips_load_reg4; /* 4th reg to check for load delay */
+extern GTY(()) rtx mips_load_reg; /* register to check for load delay */
+extern GTY(()) rtx mips_load_reg2; /* 2nd reg to check for load delay */
+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 rdata_section PARAMS ((void));
extern void sdata_section PARAMS ((void));
extern void sbss_section PARAMS ((void));
-/* Stubs for half-pic support if not OSF/1 reference platform. */
-
-#ifndef HALF_PIC_P
-#define HALF_PIC_P() 0
-#define HALF_PIC_NUMBER_PTRS 0
-#define HALF_PIC_NUMBER_REFS 0
-#define HALF_PIC_ENCODE(DECL)
-#define HALF_PIC_DECLARE(NAME)
-#define HALF_PIC_INIT() error ("half-pic init called on systems that don't support it")
-#define HALF_PIC_ADDRESS_P(X) 0
-#define HALF_PIC_PTR(X) X
-#define HALF_PIC_FINISH(STREAM)
-#endif
-
/* Macros to silence warnings about numbers being signed in traditional
C and unsigned in ISO C when compiled on 32-bit hosts. */
#define MASK_SOFT_FLOAT 0x00000100 /* software floating point */
#define MASK_FLOAT64 0x00000200 /* fp registers are 64 bits */
#define MASK_ABICALLS 0x00000400 /* emit .abicalls/.cprestore/.cpload */
-#define MASK_HALF_PIC 0x00000800 /* Emit OSF-style pic refs to externs*/
+#define MASK_UNUSED1 0x00000800 /* Unused Mask. */
#define MASK_LONG_CALLS 0x00001000 /* Always call through a register */
#define MASK_64BIT 0x00002000 /* Use 64 bit GP registers and insns */
#define MASK_EMBEDDED_PIC 0x00004000 /* Generate embedded PIC code */
#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) */
/* .abicalls, etc from Pyramid V.4 */
#define TARGET_ABICALLS (target_flags & MASK_ABICALLS)
- /* OSF pic references to externs */
-#define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC)
-
/* software floating point */
#define TARGET_SOFT_FLOAT (target_flags & MASK_SOFT_FLOAT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
/* Generate mips16 code */
#define TARGET_MIPS16 (target_flags & MASK_MIPS16)
+/* Generic ISA defines. */
+#define ISA_MIPS1 (mips_isa == 1)
+#define ISA_MIPS2 (mips_isa == 2)
+#define ISA_MIPS3 (mips_isa == 3)
+#define ISA_MIPS4 (mips_isa == 4)
+#define ISA_MIPS32 (mips_isa == 32)
+#define ISA_MIPS64 (mips_isa == 64)
+
/* Architecture target defines. */
#define TARGET_MIPS3900 (mips_arch == PROCESSOR_R3900)
#define TARGET_MIPS4000 (mips_arch == PROCESSOR_R4000)
#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 \
+ { \
+ builtin_assert ("cpu=mips"); \
+ builtin_define ("__mips__"); \
+ builtin_define ("_mips"); \
+ \
+ /* We do this here because __mips is defined below \
+ and so we can't use builtin_define_std. */ \
+ 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"); \
+ builtin_define_std ("R4000"); \
+ builtin_define ("_R4000"); \
+ } \
+ else \
+ { \
+ builtin_define_std ("R3000"); \
+ builtin_define ("_R3000"); \
+ } \
+ if (TARGET_FLOAT64) \
+ builtin_define ("__mips_fpr=64"); \
+ else \
+ builtin_define ("__mips_fpr=32"); \
+ \
+ 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"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS1"); \
+ } \
+ else if (ISA_MIPS2) \
+ { \
+ builtin_define ("__mips=2"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS2"); \
+ } \
+ else if (ISA_MIPS3) \
+ { \
+ builtin_define ("__mips=3"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS3"); \
+ } \
+ else if (ISA_MIPS4) \
+ { \
+ builtin_define ("__mips=4"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS4"); \
+ } \
+ else if (ISA_MIPS32) \
+ { \
+ builtin_define ("__mips=32"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \
+ } \
+ else if (ISA_MIPS64) \
+ { \
+ builtin_define ("__mips=64"); \
+ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
+ } \
+ \
+ if (TARGET_HARD_FLOAT) \
+ builtin_define ("__mips_hard_float"); \
+ else if (TARGET_SOFT_FLOAT) \
+ builtin_define ("__mips_soft_float"); \
+ \
+ if (TARGET_SINGLE_FLOAT) \
+ builtin_define ("__mips_single_float"); \
+ \
+ if (TARGET_BIG_ENDIAN) \
+ { \
+ builtin_define_std ("MIPSEB"); \
+ builtin_define ("_MIPSEB"); \
+ } \
+ else \
+ { \
+ builtin_define_std ("MIPSEL"); \
+ builtin_define ("_MIPSEL"); \
+ } \
+ \
+ /* Macros dependent on the C dialect. */ \
+ if (preprocessing_asm_p ()) \
+ { \
+ builtin_define_std ("LANGUAGE_ASSEMBLY"); \
+ builtin_define ("_LANGUAGE_ASSEMBLY"); \
+ } \
+ else if (c_language == clk_c) \
+ { \
+ builtin_define_std ("LANGUAGE_C"); \
+ builtin_define ("_LANGUAGE_C"); \
+ } \
+ else if (c_language == clk_cplusplus) \
+ { \
+ builtin_define ("_LANGUAGE_C_PLUS_PLUS"); \
+ builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
+ builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
+ } \
+ else if (c_language == clk_objective_c) \
+ { \
+ builtin_define ("_LANGUAGE_OBJECTIVE_C"); \
+ builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
+ /* Bizzare, but needed at least for Irix. */ \
+ builtin_define_std ("LANGUAGE_C"); \
+ builtin_define ("_LANGUAGE_C"); \
+ } \
+ \
+ if (mips_abi == ABI_EABI) \
+ builtin_define ("__mips_eabi"); \
+ \
+} while (0)
+
+
+
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE }
N_("Use Irix PIC")}, \
{"no-abicalls", -MASK_ABICALLS, \
N_("Don't use Irix PIC")}, \
- {"half-pic", MASK_HALF_PIC, \
- N_("Use OSF PIC")}, \
- {"no-half-pic", -MASK_HALF_PIC, \
- N_("Don't use OSF PIC")}, \
{"long-calls", MASK_LONG_CALLS, \
N_("Use indirect calls")}, \
{"no-long-calls", -MASK_LONG_CALLS, \
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 \
#endif
#ifndef TARGET_ENDIAN_DEFAULT
-#ifndef DECSTATION
#define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
-#else
-#define TARGET_ENDIAN_DEFAULT 0
-#endif
#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, \
/* This is meant to be redefined in the host dependent files. */
#define SUBTARGET_TARGET_OPTIONS
-#define GENERATE_BRANCHLIKELY (!TARGET_MIPS16 && ISA_HAS_BRANCHLIKELY)
+#define GENERATE_BRANCHLIKELY (!TARGET_MIPS16 && ISA_HAS_BRANCHLIKELY)
/* Generate three-operand multiply instructions for SImode. */
#define GENERATE_MULT3_SI ((TARGET_MIPS3900 \
- || mips_isa == 32 \
- || mips_isa == 64) \
+ || ISA_MIPS32 \
+ || ISA_MIPS64) \
&& !TARGET_MIPS16)
/* Generate three-operand multiply instructions for DImode. */
depending on the instruction set architecture level. */
#define BRANCH_LIKELY_P() GENERATE_BRANCHLIKELY
-#define HAVE_SQRT_P() (mips_isa != 1)
+#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 (mips_isa == 3 \
- || mips_isa == 4 \
- || mips_isa == 64)
+#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 (mips_isa != 1 \
- && ! TARGET_MIPS16)
+#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 \
+ && !TARGET_MIPS16)
/* ISA has the conditional move instructions introduced in mips4. */
-#define ISA_HAS_CONDMOVE ((mips_isa == 4 \
- || mips_isa == 32 \
- || mips_isa == 64) \
- && ! TARGET_MIPS16)
+#define ISA_HAS_CONDMOVE ((ISA_MIPS4 \
+ || ISA_MIPS32 \
+ || ISA_MIPS64) \
+ && !TARGET_MIPS16)
/* ISA has just the integer condition move instructions (movn,movz) */
#define ISA_HAS_INT_CONDMOVE 0
/* ISA has the mips4 FP condition code instructions: FP-compare to CC,
branch on CC, and move (both FP and non-FP) on CC. */
-#define ISA_HAS_8CC (mips_isa == 4 \
- || mips_isa == 32 \
- || mips_isa == 64)
+#define ISA_HAS_8CC (ISA_MIPS4 \
+ || ISA_MIPS32 \
+ || 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,
+ indexed prefetch instructions, the FP madd and msub instructions,
and the FP recip and recip sqrt instructions */
-#define ISA_HAS_FP4 (mips_isa == 4 \
- && ! TARGET_MIPS16)
+#define ISA_HAS_FP4 ((ISA_MIPS4 \
+ || ISA_MIPS64) \
+ && !TARGET_MIPS16)
/* ISA has conditional trap instructions. */
-#define ISA_HAS_COND_TRAP (mips_isa >= 2 \
- && ! TARGET_MIPS16)
+#define ISA_HAS_COND_TRAP (!ISA_MIPS1 \
+ && !TARGET_MIPS16)
-/* ISA has multiply-accumulate instructions, madd and msub. */
-#define ISA_HAS_MADD_MSUB ((mips_isa == 32 \
- || mips_isa == 64 \
- ) && ! TARGET_MIPS16)
+/* ISA has integer multiply-accumulate instructions, madd and msub. */
+#define ISA_HAS_MADD_MSUB ((ISA_MIPS32 \
+ || ISA_MIPS64 \
+ ) && !TARGET_MIPS16)
-/* ISA has nmadd and nmsub instructions. */
-#define ISA_HAS_NMADD_NMSUB (mips_isa == 4 \
+/* ISA has floating-point nmadd and nmsub instructions. */
+#define ISA_HAS_NMADD_NMSUB ((ISA_MIPS4 \
+ || ISA_MIPS64) \
&& ! TARGET_MIPS16)
/* ISA has count leading zeroes/ones instruction (not implemented). */
-#define ISA_HAS_CLZ_CLO ((mips_isa == 32 \
- || mips_isa == 64 \
- ) && ! TARGET_MIPS16)
+#define ISA_HAS_CLZ_CLO ((ISA_MIPS32 \
+ || ISA_MIPS64 \
+ ) && !TARGET_MIPS16)
/* ISA has double-word count leading zeroes/ones instruction (not
implemented). */
-#define ISA_HAS_DCLZ_DCLO (mips_isa == 64 \
- && ! 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
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
\f
-/* Complain about missing specs and predefines that should be defined in each
- of the target tm files to override the defaults. This is mostly a place-
- holder until I can get each of the files updated [mm]. */
-
-#if defined(OSF_OS) \
- || defined(DECSTATION) \
- || defined(SGI_TARGET) \
- || defined(MIPS_NEWS) \
- || defined(MIPS_SYSV) \
- || defined(MIPS_SVR4) \
- || defined(MIPS_BSD43)
-
-#ifndef CPP_PREDEFINES
- #error "Define CPP_PREDEFINES in the appropriate tm.h file"
-#endif
-
-#ifndef LIB_SPEC
- #error "Define LIB_SPEC in the appropriate tm.h file"
-#endif
-
-#ifndef STARTFILE_SPEC
- #error "Define STARTFILE_SPEC in the appropriate tm.h file"
-#endif
-
-#ifndef MACHINE_TYPE
- #error "Define MACHINE_TYPE in the appropriate tm.h file"
-#endif
-#endif
-
/* Tell collect what flags to pass to nm. */
#ifndef NM_FLAGS
#define NM_FLAGS "-Bn"
#endif
\f
-/* Names to predefine in the preprocessor for this target machine. */
-
-#ifndef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \
--D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43 \
--Asystem=unix -Asystem=bsd -Acpu=mips -Amachine=mips"
-#endif
-
/* Assembler specs. */
/* MIPS_AS_ASM_SPEC is passed when using the MIPS assembler rather
/* 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}} \
-%{pic-none: -mno-half-pic} \
-%{pic-lib: -mhalf-pic} \
-%{pic-extern: -mhalf-pic} \
-%{pic-calls: -mhalf-pic} \
%{save-temps: } \
-%(subtarget_cc1_spec) \
-%(cc1_cpu_spec)"
+%(subtarget_cc1_spec)"
#endif
/* Preprocessor specs. */
-/* Rules for SIZE_TYPE and PTRDIFF_TYPE are:
-
- both gp64 and long64 (not the options, but the corresponding flags,
- so defaults came into play) are required in order to have `long' in
- SIZE_TYPE and PTRDIFF_TYPE.
-
- on eabi, -mips1, -mips2 and -mips32 disable gp64, whereas mips3,
- -mips4, -mips5 and -mips64 enable it.
-
- on other ABIs, -mips* options do not affect gp32/64, but the
- default ISA affects the default gp size.
-
- -mgp32 disables gp64, whereas -mgp64 enables it.
-
- on eabi, gp64 implies long64.
-
- -mlong64, and -mabi=64 are the only other ways to enable long64.
-
-*/
-
-#if MIPS_ISA_DEFAULT != 3 && MIPS_ISA_DEFAULT != 4 && MIPS_ISA_DEFAULT != 5 && MIPS_ISA_DEFAULT != 64
-
-/* 32-bit cases first. */
-
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi|!mabi=*:\
- %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
- %{mips3|mips4|mips5|mips64|mgp64: \
- -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
-"
-#else /* ABI_DEFAULT != ABI_EABI */
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi:\
- %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
- %{mips3|mips4|mips5|mips64|mgp64: \
- -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
-"
-#endif
-
-#else
-
-/* 64-bit default ISA. */
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi|!mabi=*:\
- %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
- -D__LONG_MAX__=9223372036854775807L}}}}}}}\
-"
-#else /* ABI_DEFAULT != ABI_EABI */
-#define LONG_MAX_SPEC "\
-%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
-%{!mlong64:\
- %{mabi=eabi:\
- %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
- -D__LONG_MAX__=9223372036854775807L}}}}}}}\
-"
-#endif
-
-#endif
-
/* SUBTARGET_CPP_SPEC is passed to the preprocessor. It may be
overridden by subtargets. */
#ifndef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC ""
#endif
-/* Define appropriate macros for fpr register size. */
-#ifndef CPP_FPR_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_FLOAT64)
-#define CPP_FPR_SPEC "-D__mips_fpr=64"
-#else
-#define CPP_FPR_SPEC "-D__mips_fpr=32"
-#endif
-#endif
-
-/* For C++ we need to ensure that _LANGUAGE_C_PLUS_PLUS is defined independent
- of the source file extension. */
-#undef CPLUSPLUS_CPP_SPEC
-#define CPLUSPLUS_CPP_SPEC "\
--D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS \
-%(cpp) \
-"
-/* CPP_SPEC is the set of arguments to pass to the preprocessor. */
-
-#ifndef CPP_SPEC
-#define CPP_SPEC "\
-%{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C -D__LANGUAGE_C -D_LANGUAGE_C} \
-%{.S|.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
-%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.cpp: %{!.cp: %{!.c++: %{!.C: %{!.m: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}}}}}}}} \
-%(subtarget_cpp_size_spec) \
-%{mips3:-U__mips -D__mips=3 -D__mips64} \
-%{mips4:-U__mips -D__mips=4 -D__mips64} \
-%{mips32:-U__mips -D__mips=32} \
-%{mips64:-U__mips -D__mips=64 -D__mips64} \
-%{mgp32:-U__mips64} %{mgp64:-D__mips64} \
-%{mfp32:-D__mips_fpr=32} %{mfp64:-D__mips_fpr=64} %{!mfp32: %{!mfp64: %{mgp32:-D__mips_fpr=32} %{!mgp32: %(cpp_fpr_spec)}}} \
-%{msingle-float:%{!msoft-float:-D__mips_single_float}} \
-%{m4650:%{!msoft-float:-D__mips_single_float}} \
-%{msoft-float:-D__mips_soft_float} \
-%{mabi=eabi:-D__mips_eabi} \
-%{mips16:%{!mno-mips16:-D__mips16}} \
-%{EB:-UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__ -D_MIPSEB -D__MIPSEB -D__MIPSEB__ %{!ansi:-DMIPSEB}} \
-%{EL:-UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__ -D_MIPSEL -D__MIPSEL -D__MIPSEL__ %{!ansi:-DMIPSEL}} \
-%(long_max_spec) \
-%(subtarget_cpp_spec) "
-#endif
+#define CPP_SPEC "%(subtarget_cpp_spec)"
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
#define EXTRA_SPECS \
{ "subtarget_cc1_spec", SUBTARGET_CC1_SPEC }, \
- { "cc1_cpu_spec", CC1_CPU_SPEC}, \
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
- { "long_max_spec", LONG_MAX_SPEC }, \
- { "cpp_fpr_spec", CPP_FPR_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 */
`Q' is for mips16 GP relative constants
`R' is for memory references which take 1 word for the instruction.
- `S' is for references to extern items which are PIC for OSF/rose.
`T' is for memory addresses that can be used to load two words. */
#define EXTRA_CONSTRAINT(OP,CODE) \
&& mips16_gp_offset_p (OP)) \
: (GET_CODE (OP) != MEM) ? FALSE \
: ((CODE) == 'R') ? simple_memory_operand (OP, GET_MODE (OP)) \
- : ((CODE) == 'S') ? (HALF_PIC_P () && CONSTANT_P (OP) \
- && HALF_PIC_ADDRESS_P (OP)) \
: FALSE)
/* Given an rtx X being reloaded into a reg required to be
/* 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. */
: current_function_outgoing_args_size)
#endif
-/* The return address for the current frame is in r31 is this is a leaf
+/* The return address for the current frame is in r31 if this is a leaf
function. Otherwise, it is on the stack. It is at a variable offset
from sp/fp/ap, so we define a fake hard register rap which is a
poiner to the return address on the stack. This always gets eliminated
#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
the shift patterns, and function_arg, which returns them when given
a VOIDmode argument. */
unsigned int num_adjusts;
- struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS];
+ rtx adjust[MAX_ARGS_IN_REGISTERS];
} CUMULATIVE_ARGS;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
(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) \
/* A C compound statement with a conditional `goto LABEL;' executed
if X (an RTX) is a legitimate memory address on the target
- machine for a memory operand of mode MODE.
-
- It usually pays to define several simpler macros to serve as
- subroutines for this one. Otherwise it may be too complicated
- to understand.
-
- This macro must exist in two variants: a strict variant and a
- non-strict one. The strict variant is used in the reload pass.
- It must be defined so that any pseudo-register that has not been
- allocated a hard register is considered a memory reference. In
- contexts where some kind of register is required, a
- pseudo-register with no hard register must be rejected.
-
- The non-strict variant is used in other passes. It must be
- defined to accept all pseudo-registers in every context where
- some kind of register is required.
-
- Compiler source files that want to use the strict variant of
- this macro define the macro `REG_OK_STRICT'. You should use an
- `#ifdef REG_OK_STRICT' conditional to define the strict variant
- in that case and the non-strict variant otherwise.
-
- Typically among the subroutines used to define
- `GO_IF_LEGITIMATE_ADDRESS' are subroutines to check for
- acceptable registers for various purposes (one for base
- registers, one for index registers, and so on). Then only these
- subroutine macros need have two variants; the higher levels of
- macros may be the same whether strict or not.
-
- Normally, constant addresses which are the sum of a `symbol_ref'
- and an integer are stored inside a `const' RTX to mark them as
- constant. Therefore, there is no need to recognize such sums
- specifically as legitimate addresses. Normally you would simply
- recognize any `const' as legitimate.
-
- Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle
- constant sums that are not marked with `const'. It assumes
- that a naked `plus' indicates indexing. If so, then you *must*
- reject such naked constant sums as illegitimate addresses, so
- that none of them will be given to `PRINT_OPERAND_ADDRESS'.
-
- On some machines, whether a symbolic address is legitimate
- depends on the section that the address refers to. On these
- machines, define the macro `ENCODE_SECTION_INFO' to store the
- information into the `symbol_ref', and then check for it here.
- When you see a `const', you will have to look inside it to find
- the `symbol_ref' in order to determine the section. */
+ machine for a memory operand of mode MODE. */
#if 1
#define GO_PRINTF(x) fprintf(stderr, (x))
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) == 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))) \
- && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
+ && (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); \
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- The macro definition, if any, is executed immediately after the
- rtl for DECL has been created and stored in `DECL_RTL (DECL)'.
- The value of the rtl will be a `mem' whose address is a
- `symbol_ref'.
-
- The usual thing for this macro to do is to a flag in the
- `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
- name string in the `symbol_ref' (if one bit is not enough
- information).
-
- The best way to modify the name string is by adding text to the
- beginning, with suitable punctuation to prevent any ambiguity.
- Allocate the new name in `saveable_obstack'. You will have to
- modify `ASM_OUTPUT_LABELREF' to remove and decode the added text
- and output the name accordingly.
-
- You can also check the information stored in the `symbol_ref' in
- the definition of `GO_IF_LEGITIMATE_ADDRESS' or
- `PRINT_OPERAND_ADDRESS'.
-
- When optimizing for the $gp pointer, SYMBOL_REF_FLAG is set for all
- small objects.
-
- When generating embedded PIC code, SYMBOL_REF_FLAG is set for
- symbols which are not in the .text section.
-
- When generating mips16 code, SYMBOL_REF_FLAG is set for string
- constants which are put in the .text section. We also record the
- total length of all such strings; this total is used to decide
- whether we need to split the constant table, and need not be
- precisely correct.
-
- When not mips16 code nor embedded PIC, if a symbol is in a
- gp addresable section, SYMBOL_REF_FLAG is set prevent gcc from
- splitting the reference so that gas can generate a gp relative
- reference.
-
- When TARGET_EMBEDDED_DATA is set, we assume that all const
- variables will be stored in ROM, which is too far from %gp to use
- %gprel addressing. Note that (1) we include "extern const"
- variables in this, which mips_select_section doesn't, and (2) we
- can't always tell if they're really const (they might be const C++
- objects with non-const constructors), so we err on the side of
- caution and won't use %gprel anyway (otherwise we'd have to defer
- this decision to the linker/loader). The handling of extern consts
- is why the DECL_INITIAL macros differ from mips_select_section.
-
- If you are changing this macro, you should look at
- mips_select_section and see if it needs a similar change. */
-
-#define ENCODE_SECTION_INFO(DECL, FIRST) \
-do \
- { \
- if (TARGET_MIPS16) \
- { \
- if ((FIRST) && TREE_CODE (DECL) == STRING_CST \
- && ! flag_writable_strings \
- /* If this string is from a function, and the function will \
- go in a gnu linkonce section, then we can't directly \
- access the string. This gets an assembler error \
- "unsupported PC relative reference to different section".\
- If we modify SELECT_SECTION to put it in function_section\
- instead of text_section, it still fails because \
- DECL_SECTION_NAME isn't set until assemble_start_function.\
- If we fix that, it still fails because strings are shared\
- among multiple functions, and we have cross section \
- references again. We force it to work by putting string \
- addresses in the constant pool and indirecting. */ \
- && (! current_function_decl \
- || ! DECL_ONE_ONLY (current_function_decl))) \
- { \
- SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 1; \
- mips_string_length += TREE_STRING_LENGTH (DECL); \
- } \
- } \
- \
- if (TARGET_EMBEDDED_DATA \
- && (TREE_CODE (DECL) == VAR_DECL \
- && TREE_READONLY (DECL) && !TREE_SIDE_EFFECTS (DECL)) \
- && (!DECL_INITIAL (DECL) \
- || TREE_CONSTANT (DECL_INITIAL (DECL)))) \
- { \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 0; \
- } \
- \
- else if (TARGET_EMBEDDED_PIC) \
- { \
- if (TREE_CODE (DECL) == VAR_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- else if (TREE_CODE (DECL) == FUNCTION_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 0; \
- else if (TREE_CODE (DECL) == STRING_CST \
- && ! flag_writable_strings) \
- SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 0; \
- else \
- SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (DECL), 0)) = 1; \
- } \
- \
- else if (TREE_CODE (DECL) == VAR_DECL \
- && DECL_SECTION_NAME (DECL) != NULL_TREE \
- && (0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (DECL)), \
- ".sdata") \
- || 0 == strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (DECL)),\
- ".sbss"))) \
- { \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- } \
- \
- /* We can not perform GP optimizations on variables which are in \
- specific sections, except for .sdata and .sbss which are \
- handled above. */ \
- else if (TARGET_GP_OPT && TREE_CODE (DECL) == VAR_DECL \
- && DECL_SECTION_NAME (DECL) == NULL_TREE \
- && ! (TARGET_MIPS16 && TREE_PUBLIC (DECL) \
- && (DECL_COMMON (DECL) \
- || DECL_ONE_ONLY (DECL) \
- || DECL_WEAK (DECL)))) \
- { \
- int size = int_size_in_bytes (TREE_TYPE (DECL)); \
- \
- if (size > 0 && size <= mips_section_threshold) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- } \
- \
- else if (HALF_PIC_P ()) \
- { \
- if (FIRST) \
- HALF_PIC_ENCODE (DECL); \
- } \
- } \
-while (0)
-
/* This handles the magic '..CURRENT_FUNCTION' symbol, which means
'the start of the function that this code is output in'. */
#define FUNCTION_MODE (Pmode == DImode ? DImode : SImode)
-/* Define TARGET_MEM_FUNCTIONS if we want to use calls to memcpy and
- memset, instead of the BSD functions bcopy and bzero. */
-
-#if defined(MIPS_SYSV) || defined(OSF_OS)
-#define TARGET_MEM_FUNCTIONS
-#endif
-
\f
/* A part of a C `switch' statement that describes the relative
costs of constant RTL expressions. It must contain `case'
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 }}, \
ALL_COP_ADDITIONAL_REGISTER_NAMES \
}
-/* This is meant to be redefined in the host dependent files. It is a
+/* This is meant to be redefined in the host dependent files. It is a
set of alternative names and regnums for mips coprocessors. */
#define ALL_COP_ADDITIONAL_REGISTER_NAMES
/* A C compound statement to output to stdio stream STREAM the
assembler syntax for an instruction operand that is a memory
- reference whose address is ADDR. ADDR is an RTL expression.
-
- On some machines, the syntax for a symbolic address depends on
- the section that the address refers to. On these machines,
- define the macro `ENCODE_SECTION_INFO' to store the information
- into the `symbol_ref', and then check for it here. */
+ reference whose address is ADDR. ADDR is an RTL expression. */
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
LM[0-9]+ Silicon Graphics/ECOFF stabs label before each stmt.
$Lb[0-9]+ Begin blocks for MIPS debug support
$Lc[0-9]+ Label for use in s<xx> operation.
- $Le[0-9]+ End blocks for MIPS debug support
- $Lp\..+ Half-pic labels. */
+ $Le[0-9]+ End blocks for MIPS debug support */
/* This is how to output the definition of a user-level label named NAME,
such as the label on a static function or variable NAME.
do \
{ \
mips_declare_object (STREAM, NAME, "", ":\n", 0); \
- HALF_PIC_DECLARE (NAME); \
} \
while (0)
if (TREE_PUBLIC (DECL) && DECL_NAME (DECL)) \
ASM_GLOBALIZE_LABEL (STREAM, NAME); \
\
- READONLY_DATA_SECTION (); \
+ readonly_data_section (); \
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
mips_declare_object (STREAM, NAME, "", ":\n\t.space\t%u\n", \
(SIZE)); \
/* 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) \
- HALF_PIC_DECLARE (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) \
{ \
const char *p = STRING; \
int size = strlen (p) + 1; \
- rdata_section (); \
+ readonly_data_section (); \
assemble_string (p, size); \
}
\f
#define TEXT_SECTION_ASM_OP "\t.text" /* instructions */
#define DATA_SECTION_ASM_OP "\t.data" /* large data */
#define SDATA_SECTION_ASM_OP "\t.sdata" /* small data */
-#define RDATA_SECTION_ASM_OP "\t.rdata" /* read-only data */
-#undef READONLY_DATA_SECTION
-#define READONLY_DATA_SECTION rdata_section
+#ifndef READONLY_DATA_SECTION_ASM_OP
+#define READONLY_DATA_SECTION_ASM_OP "\t.rdata" /* read-only data */
+#endif
#define SMALL_DATA_SECTION sdata_section
/* What other sections we support other than the normal .data/.text. */
#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_sdata, in_rdata
+#define EXTRA_SECTIONS in_sdata
/* Define the additional functions to select our additional sections. */
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
in_section = in_sdata; \
} \
-} \
- \
-void \
-rdata_section () \
-{ \
- if (in_section != in_rdata) \
- { \
- fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP); \
- in_section = in_rdata; \
- } \
}
/* Given a decl node or constant node, choose the section to output it in
and select that section. */
-#undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
- mips_select_rtx_section (MODE, RTX)
-
-#undef SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC, ALIGN) \
- mips_select_section (DECL, RELOC)
-
+#undef TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION mips_select_section
\f
/* Store in OUTPUT a string (made with alloca) containing
an assembler-name for a local static variable named NAME.
} \
} \
while (0)
+
+#define DFMODE_NAN \
+ unsigned short DFbignan[4] = {0x7ff7, 0xffff, 0xffff, 0xffff}; \
+ unsigned short DFlittlenan[4] = {0xffff, 0xffff, 0xffff, 0xfff7}
+#define SFMODE_NAN \
+ unsigned short SFbignan[2] = {0x7fbf, 0xffff}; \
+ unsigned short SFlittlenan[2] = {0xffff, 0xffbf}