X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fmips%2Fmips.h;h=84b6880ddf1dd1cb9437c6ae08548b64d5421035;hb=5153cc324bf014b2e720609830f8bf1c27b0fecc;hp=7778361e8597046c8a48ed2ad6099fc497c8ed0d;hpb=d8c4db284ae7ae3efa6d39187caa0ecff2f3dae0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 7778361e859..84b6880ddf1 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -118,6 +118,23 @@ enum block_move_type { 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 */ @@ -146,14 +163,12 @@ extern int mips_isa; /* architectural level */ 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= */ extern const char *mips_arch_string; /* for -march= */ extern const char *mips_tune_string; /* for -mtune= */ 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 */ @@ -167,6 +182,9 @@ 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 sdata_section PARAMS ((void)); @@ -225,7 +243,6 @@ extern void sbss_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 */ @@ -253,7 +270,6 @@ extern void sbss_section PARAMS ((void)); #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) */ @@ -344,6 +360,25 @@ extern void sbss_section PARAMS ((void)); #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 \ @@ -357,16 +392,16 @@ extern void sbss_section PARAMS ((void)); 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"); \ } \ @@ -378,6 +413,9 @@ extern void sbss_section PARAMS ((void)); 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"); \ @@ -561,10 +599,6 @@ extern void sbss_section PARAMS ((void)); 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, \ @@ -589,8 +623,6 @@ extern void sbss_section PARAMS ((void)); NULL}, \ {"debugg", MASK_DEBUG_G, \ NULL}, \ - {"debugh", MASK_DEBUG_H, \ - NULL}, \ {"debugi", MASK_DEBUG_I, \ NULL}, \ {"", (TARGET_DEFAULT \ @@ -613,8 +645,11 @@ extern void sbss_section PARAMS ((void)); #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 @@ -664,7 +699,8 @@ extern void sbss_section PARAMS ((void)); #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 @@ -683,20 +719,18 @@ extern void sbss_section PARAMS ((void)); #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, \ @@ -724,15 +758,25 @@ extern void sbss_section PARAMS ((void)); #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. */ @@ -751,8 +795,8 @@ extern void sbss_section PARAMS ((void)); || 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) @@ -781,6 +825,17 @@ extern void sbss_section PARAMS ((void)); #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 @@ -908,7 +963,7 @@ while (0) /* 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; @@ -917,8 +972,43 @@ 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 @@ -966,7 +1056,11 @@ extern int mips_abi; #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 "\ @@ -975,7 +1069,9 @@ extern int mips_abi; %(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)" @@ -1038,16 +1134,6 @@ extern int mips_abi; #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 @@ -1056,19 +1142,9 @@ extern int mips_abi; #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. */ @@ -1093,16 +1169,15 @@ extern int mips_abi; #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 @@ -1343,21 +1418,21 @@ do { \ #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 @@ -1367,9 +1442,9 @@ do { \ 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 */ @@ -2253,17 +2328,24 @@ extern enum reg_class mips_char_to_class[256]; /* 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. */ @@ -2346,31 +2428,6 @@ extern enum reg_class mips_char_to_class[256]; #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 @@ -2442,47 +2499,8 @@ extern struct mips_frame_info current_frame_info; && (! 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. @@ -2631,11 +2649,10 @@ extern struct mips_frame_info current_frame_info; /* 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 @@ -2820,8 +2837,8 @@ typedef struct mips_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) \ @@ -3040,15 +3057,18 @@ typedef struct mips_args { 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. */ @@ -3139,9 +3159,9 @@ typedef struct mips_args { 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); \ @@ -3511,11 +3531,11 @@ typedef struct mips_args { 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); \ @@ -3523,23 +3543,23 @@ typedef struct mips_args { \ 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); \ @@ -3551,10 +3571,10 @@ typedef struct mips_args { 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); \ @@ -3562,10 +3582,10 @@ typedef struct mips_args { \ 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); \ @@ -3575,12 +3595,12 @@ typedef struct mips_args { \ 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); \ @@ -3749,7 +3769,6 @@ typedef struct mips_args { {"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 }}, \ @@ -4332,11 +4351,12 @@ do { \ /* 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. */ @@ -4418,9 +4438,6 @@ do { \ #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) \