From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16798 invoked by alias); 22 Jul 2002 10:41:39 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 16743 invoked from network); 22 Jul 2002 10:41:36 -0000 Received: from unknown (HELO executor.cambridge.redhat.com) (195.224.55.237) by sources.redhat.com with SMTP; 22 Jul 2002 10:41:36 -0000 Received: from talisman.cambridge.redhat.com (talisman.cambridge.redhat.com [172.16.18.81]) by executor.cambridge.redhat.com (Postfix) with ESMTP id 1E336ABB1B; Mon, 22 Jul 2002 11:41:35 +0100 (BST) Received: (from rsandifo@localhost) by talisman.cambridge.redhat.com (8.11.6/8.11.0) id g6MAfBJ21283; Mon, 22 Jul 2002 11:41:11 +0100 X-Authentication-Warning: talisman.cambridge.redhat.com: rsandifo set sender to rsandifo@redhat.com using -f To: cgd@broadcom.com Cc: gcc-patches@gcc.gnu.org, binutils@sources.redhat.com, "Thiemo Seufer" , "Maciej W. Rozycki" , "Eric Christopher" , "Mark D. Baushke" , "Gerald Pfeifer" Subject: Re: [Revised patch] Rework MIPS command-line handling References: From: Richard Sandiford Date: Mon, 22 Jul 2002 03:47:00 -0000 In-Reply-To: Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-SW-Source: 2002-07/txt/msg00541.txt.bz2 --=-=-= Content-length: 5839 cgd@broadcom.com writes: > > If that idea really doesn't fly, I'd rather have _MIPS_ARCH > > be a string and define _MIPS_ARCH_FOO when compiling for FOO. > > You know, now that you mention it, i think that might actually be the > best solution. (kind of a "back to the future" thing, but with the > addition of a string for _MIPS_ARCH. 8-) New version below. Also includes the suggested gas config changes (infer processor name from mipsisa32foo, base MIPS_DEFAULT_64BIT on full target triple). As Gerald pointed out, the changes ought to be mentioned on the 3.3 pages, so I've attached a patch for that too. GAS patch tested on a fairly random selection of targets: mips-ecoff, mips-elf, mips-sgi-irix6.5m mips64-elf, mips64orion-elf, mips64vr4100el-elf, mipsel-ecoff, mipsel-linux-gnu, mipsisa32-elf, mipsisa32-linux-gnu, mipsisa64-elf and mipstx39-elf. GCC patch tested by bootstrapping on mips-sgi-irix6.5. Also tested mips-elf and mips64-elf (in the latter case, both with and without the GAS changes). OK to install? [include/] * opcode/mips.h (CPU_R2000): Remove. [gas/] * doc/c-mips.texi: Remove -mcpu. Document -mabi. * configure.in (MIPS_CPU_STRING_DEFAULT): New configuration macro. (USE_E_MIPS_ABI_O32, MIPS_DEFAULT_64BIT): New configuration macros. * configure, config.in: Regenerate. * config/tc-mips.c (file_mips_abi): Rename to mips_abi. (mips_set_options): Remove "abi" field. (mips_opts): Update accordingly. Replace all uses of mips_opts.abi with mips_abi. (mips_cpu): Remove. (mips_arch_string, mips_arch_info): New vars. (mips_tune_string, mips_tune_info): New vars. (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New macros. (HAVE_32BIT_GPRS, HAVE_32BIT_FPRS): Don't check the ABI. (mips_isa_to_str, mips_cpu_to_str): Remove. (mips_ip): If the selected architecture is a generic ISA rather than a processor, only mention the ISA level in error messages. (OPTION_MCPU): Remove. (OPTION_FP64): New. (md_longopts): Add -mfp64, remove -mcpu. (mips_set_option_string): New fn. (md_parse_option): Make -mipsN update file_mips_isa rather than mips_opts.isa. Use mips_set_option_string to set -march or -mtune. Don't let -mgp32 and -mfp32 change the ABI. (show): Move to end of file. Constify string argument. (md_show_usage): Move to the end of the file. Read available architectures from mips_cpu_info_table. (mips_set_architecture): New fn. (mips_after_parse_args): Rework. Remove -mcpu handling. -mipsN is an alias for -march=mipsN. Don't change the ABI based on other flags. Infer the register size from the ABI as well as the architecture. Complain about more conflicting arguments. [Logic unified with gcc 3.2.] (s_mipsset): Don't change the ABI. (mips_elf_final_processing): Check USE_E_MIPS_ABI_O32. (mips_cpu_info_table): Remove Generic-MIPS* entries, keeping just "mipsN"-type entries. Remove entries that vary only in the manufacturer's prefix, or that have "000" replaced by "k". Remove TARGET_CPU entries. Make r2000 entry use CPU_R3000. (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns. (mips_parse_cpu): New fn. (mips_cpu_info_from_name, mips_cpu_info_from_cpu): Remove. (mips_cpu_info_from_isa): Minor formatting tweak. [gas/testsuite] * gas/mips/mips-gp32-fp64.d, * gas/mips/mips-gp32-fp64-pic.d: Add -mfp64. [gcc/] * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI description. Document -mips32, -mips64, and the associated -march values. Describe the "mipsN" arguments to -march. Say that the -mipsN options are equivalent to -march. Reword the description of default type sizes. * toplev.h (target_flags_explicit): Declare. * toplev.c (target_flags_explicit): New var. (set_target_switch): Update target_flags_explicit. * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine. * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine. * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3. * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine. * config/mips/mips.h (mips_cpu_info): New struct. (mips_cpu_string, mips_explicit_type_size_string): Remove. (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare. (MIPS_CPP_SET_PROCESSOR): New macro. (TARGET_CPP_BUILTINS): Declare a macro for each supported processor. Define _MIPS_ARCH and _MIPS_TUNE. (MIPS_ISA_DEFAULT): Don't provide a default value. Instead... (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor MIPS_ISA_DEFAULT were already defined. (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT. (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size. (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New. (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules. (ABI_GAS_ASM_SPEC): Remove. (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros. (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64. Invoke %(asm_abi_default_spec) if no ABI was specified. (CC1_SPEC): Remove ISA -> register-size rules. (EXTRA_SPECS): Remove abi_gas_asm_spec. Add asm_abi_default_spec. * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars. (mips_cpu_string, mips_explicit_type_size_string): Remove. (mips_cpu_info_table): New array. (mips_set_architecture, mips_set_tune): New fns. (override_options): Rework to make -mipsN equivalent to -march. Detect more erroneous cases, including those removed from CC1_SPEC. Don't change the ABI based on architecture, or vice versa. Unify logic with GAS 2.14. (mips_asm_file_start): Get architecture name from mips_arch_info. (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns. (mips_parse_cpu): Take the name of the option as argument. Handle 'from-abi'. Raise an error if the option is wrong. (mips_cpu_info_from_isa): New fn. [gcc/testsuite] * gcc.dg/mips-args-[123].c: New tests. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=mips-config-gas-3.diff Content-Description: GAS patch Content-length: 61421 Index: include/opcode/mips.h =================================================================== RCS file: /cvs/src/src/include/opcode/mips.h,v retrieving revision 1.27 diff -c -d -p -r1.27 mips.h *** include/opcode/mips.h 9 Jul 2002 14:21:40 -0000 1.27 --- include/opcode/mips.h 19 Jul 2002 18:37:29 -0000 *************** struct mips_opcode *** 377,383 **** /* CPU defines, use instead of hardcoding processor number. Keep this in sync with bfd/archures.c in order for machine selection to work. */ #define CPU_UNKNOWN 0 /* Gas internal use. */ - #define CPU_R2000 2000 #define CPU_R3000 3000 #define CPU_R3900 3900 #define CPU_R4000 4000 --- 377,382 ---- Index: gas/doc/c-mips.texi =================================================================== RCS file: /cvs/src/src/gas/doc/c-mips.texi,v retrieving revision 1.22 diff -c -d -p -r1.22 c-mips.texi *** gas/doc/c-mips.texi 31 May 2002 01:17:15 -0000 1.22 --- gas/doc/c-mips.texi 19 Jul 2002 18:37:30 -0000 *************** sb1 *** 175,186 **** Schedule and tune for a particular MIPS cpu. Valid @var{cpu} values are identical to @samp{-march=@var{cpu}}. ! @item -mcpu=@var{cpu} ! Generate code and schedule for a particular MIPS cpu. This is exactly ! equivalent to @samp{-march=@var{cpu}} and @samp{-mtune=@var{cpu}}. Valid ! @var{cpu} values are identical to @samp{-march=@var{cpu}}. ! Use of this option is discouraged. ! @cindex @code{-nocpp} ignored (MIPS) @item -nocpp --- 175,183 ---- Schedule and tune for a particular MIPS cpu. Valid @var{cpu} values are identical to @samp{-march=@var{cpu}}. ! @item -mabi=@var{abi} ! Record which ABI the source code uses. The recognized arguments ! are: @samp{32}, @samp{n32}, @samp{o64}, @samp{64} and @samp{eabi}. @cindex @code{-nocpp} ignored (MIPS) @item -nocpp Index: gas/configure.in =================================================================== RCS file: /cvs/src/src/gas/configure.in,v retrieving revision 1.110 diff -c -d -p -r1.110 configure.in *** gas/configure.in 9 Jul 2002 02:41:16 -0000 1.110 --- gas/configure.in 19 Jul 2002 18:37:30 -0000 *************** changequote([,])dnl *** 555,560 **** --- 555,615 ---- # Other random stuff. + case ${cpu_type} in + mips) + # Set mips_cpu to the name of the default CPU. + case ${target_cpu} in + mips | mipsbe | mipseb | mipsle | mipsel | mips64 | mips64el) + mips_cpu=from-abi + ;; + mipsisa32 | mipsisa32el) + mips_cpu=mips32 + ;; + mipsisa64 | mipsisa64el) + mips_cpu=mips64 + ;; + mipstx39 | mipstx39el) + mips_cpu=r3900 + ;; + mips64* | mipsisa64* | mipsisa32*) + changequote(,)dnl + mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*..//' -e 's/el$//'` + changequote([,])dnl + ;; + *) + AC_ERROR($target_cpu isn't a supported MIPS CPU name) + ;; + esac + # See whether it's appropriate to set E_MIPS_ABI_O32 for o32 + # binaries. It's a GNU extension that some OSes don't understand. + # The value only matters on ELF targets. + case ${target} in + *-*-irix*) + use_e_mips_abi_o32=0 + ;; + *) + use_e_mips_abi_o32=1 + ;; + esac + # Decide whether to generate 32-bit or 64-bit code by default. + # Used to resolve -march=from-abi when an embedded ABI is selected. + case ${target} in + mips64*-*-* | mipsisa64*-*-*) + mips_default_64bit=1 + ;; + *) + mips_default_64bit=0 + ;; + esac + AC_DEFINE_UNQUOTED(MIPS_CPU_STRING_DEFAULT, "$mips_cpu", + [Default CPU for MIPS targets. ]) + AC_DEFINE_UNQUOTED(USE_E_MIPS_ABI_O32, $use_e_mips_abi_o32, + [Allow use of E_MIPS_ABI_O32 on MIPS targets. ]) + AC_DEFINE_UNQUOTED(MIPS_DEFAULT_64BIT, $mips_default_64bit, + [Generate 64-bit code by default on MIPS targets. ]) + ;; + esac + # Do we need the opcodes library? case ${cpu_type} in vax | i386 | tic30) Index: gas/config/tc-mips.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.c,v retrieving revision 1.147 diff -c -d -p -r1.147 tc-mips.c *** gas/config/tc-mips.c 9 Jul 2002 14:21:40 -0000 1.147 --- gas/config/tc-mips.c 19 Jul 2002 18:37:30 -0000 *************** enum mips_abi_level *** 129,135 **** }; /* MIPS ABI we are using for this output file. */ ! static enum mips_abi_level file_mips_abi = NO_ABI; /* This is the set of options which may be modified by the .set pseudo-op. We use a struct so that .set push and .set pop are more --- 129,135 ---- }; /* MIPS ABI we are using for this output file. */ ! static enum mips_abi_level mips_abi = NO_ABI; /* This is the set of options which may be modified by the .set pseudo-op. We use a struct so that .set push and .set pop are more *************** struct mips_set_options *** 177,185 **** is passed but can changed if the assembler code uses .set mipsN. */ int gp32; int fp32; - /* The ABI currently in use. This is changed by .set mipsN to loosen - restrictions and doesn't affect the whole file. */ - enum mips_abi_level abi; }; /* True if -mgp32 was passed. */ --- 177,182 ---- *************** static int file_mips_fp32 = -1; *** 194,200 **** static struct mips_set_options mips_opts = { ! ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, NO_ABI }; /* These variables are filled in with the masks of registers used. --- 191,197 ---- static struct mips_set_options mips_opts = { ! ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }; /* These variables are filled in with the masks of registers used. *************** static int file_ase_mips3d; *** 218,235 **** command line (e.g., by -march). */ static int file_ase_mdmx; - /* The argument of the -mcpu= flag. Historical for code generation. */ - static int mips_cpu = CPU_UNKNOWN; - /* The argument of the -march= flag. The architecture we are assembling. */ static int mips_arch = CPU_UNKNOWN; /* The argument of the -mtune= flag. The architecture for which we are optimizing. */ static int mips_tune = CPU_UNKNOWN; ! /* If they asked for mips1 or mips2 and a cpu that is ! mips3 or greater, then mark the object file 32BITMODE. */ static int mips_32bitmode = 0; /* Some ISA's have delay slots for instructions which read or write --- 215,232 ---- command line (e.g., by -march). */ static int file_ase_mdmx; /* The argument of the -march= flag. The architecture we are assembling. */ static int mips_arch = CPU_UNKNOWN; + static const char *mips_arch_string; + static const struct mips_cpu_info *mips_arch_info; /* The argument of the -mtune= flag. The architecture for which we are optimizing. */ static int mips_tune = CPU_UNKNOWN; + static const char *mips_tune_string; + static const struct mips_cpu_info *mips_tune_info; ! /* True when generating 32-bit code for a 64-bit processor. */ static int mips_32bitmode = 0; /* Some ISA's have delay slots for instructions which read or write *************** static int mips_32bitmode = 0; *** 246,251 **** --- 243,257 ---- || (ISA) == ISA_MIPS3 \ ) + /* True if the given ABI requires 32-bit registers. */ + #define ABI_NEEDS_32BIT_REGS(ABI) ((ABI) == O32_ABI) + + /* Likewise 64-bit registers. */ + #define ABI_NEEDS_64BIT_REGS(ABI) \ + ((ABI) == N32_ABI \ + || (ABI) == N64_ABI \ + || (ABI) == O64_ABI) + /* Return true if ISA supports 64 bit gp register instructions. */ #define ISA_HAS_64BIT_REGS(ISA) ( \ (ISA) == ISA_MIPS3 \ *************** static int mips_32bitmode = 0; *** 255,275 **** ) #define HAVE_32BIT_GPRS \ ! (mips_opts.gp32 \ ! || mips_opts.abi == O32_ABI \ ! || ! ISA_HAS_64BIT_REGS (mips_opts.isa)) #define HAVE_32BIT_FPRS \ ! (mips_opts.fp32 \ ! || mips_opts.abi == O32_ABI \ ! || ! ISA_HAS_64BIT_REGS (mips_opts.isa)) #define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS) #define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS) ! #define HAVE_NEWABI (mips_opts.abi == N32_ABI || mips_opts.abi == N64_ABI) ! #define HAVE_64BIT_OBJECTS (mips_opts.abi == N64_ABI) /* We can only have 64bit addresses if the object file format supports it. */ --- 261,277 ---- ) #define HAVE_32BIT_GPRS \ ! (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa)) #define HAVE_32BIT_FPRS \ ! (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa)) #define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS) #define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS) ! #define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI) ! #define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI) /* We can only have 64bit addresses if the object file format supports it. */ *************** static void my_getExpression PARAMS ((ex *** 741,746 **** --- 743,749 ---- #ifdef OBJ_ELF static int support_64bit_objects PARAMS((void)); #endif + static void mips_set_option_string PARAMS ((const char **, const char *)); static symbolS *get_symbol PARAMS ((void)); static void mips_align PARAMS ((int to, int fill, symbolS *label)); static void s_align PARAMS ((int)); *************** static void s_mips_weakext PARAMS ((int) *** 772,781 **** static void s_mips_file PARAMS ((int)); static void s_mips_loc PARAMS ((int)); static int mips16_extended_frag PARAMS ((fragS *, asection *, long)); - static const char *mips_isa_to_str PARAMS ((int)); - static const char *mips_cpu_to_str PARAMS ((int)); static int validate_mips_insn PARAMS ((const struct mips_opcode *)); ! static void show PARAMS ((FILE *, char *, int *, int *)); #ifdef OBJ_ELF static int mips_need_elf_addend_fixup PARAMS ((fixS *)); #endif --- 775,782 ---- static void s_mips_file PARAMS ((int)); static void s_mips_loc PARAMS ((int)); static int mips16_extended_frag PARAMS ((fragS *, asection *, long)); static int validate_mips_insn PARAMS ((const struct mips_opcode *)); ! static void show PARAMS ((FILE *, const char *, int *, int *)); #ifdef OBJ_ELF static int mips_need_elf_addend_fixup PARAMS ((fixS *)); #endif *************** struct mips_cpu_info *** 817,825 **** int cpu; /* CPU number (default CPU if ISA). */ }; ! static const struct mips_cpu_info *mips_cpu_info_from_name PARAMS ((const char *)); static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int)); - static const struct mips_cpu_info *mips_cpu_info_from_cpu PARAMS ((int)); /* Pseudo-op table. --- 818,831 ---- int cpu; /* CPU number (default CPU if ISA). */ }; ! static void mips_set_architecture PARAMS ((const struct mips_cpu_info *)); ! static void mips_set_tune PARAMS ((const struct mips_cpu_info *)); ! static boolean mips_strict_matching_cpu_name_p PARAMS ((const char *, ! const char *)); ! static boolean mips_matching_cpu_name_p PARAMS ((const char *, const char *)); ! static const struct mips_cpu_info *mips_parse_cpu PARAMS ((const char *, ! const char *)); static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int)); /* Pseudo-op table. *************** static boolean mips16_small, mips16_ext; *** 972,1007 **** static segT pdr_seg; - static const char * - mips_isa_to_str (isa) - int isa; - { - const struct mips_cpu_info *ci; - static char s[20]; - - ci = mips_cpu_info_from_isa (isa); - if (ci != NULL) - return (ci->name); - - sprintf (s, "ISA#%d", isa); - return s; - } - - static const char * - mips_cpu_to_str (cpu) - int cpu; - { - const struct mips_cpu_info *ci; - static char s[16]; - - ci = mips_cpu_info_from_cpu (cpu); - if (ci != NULL) - return (ci->name); - - sprintf (s, "CPU#%d", cpu); - return s; - } - /* The default target format to use. */ const char * --- 978,983 ---- *************** md_begin () *** 1177,1183 **** if (strcmp (TARGET_OS, "elf") != 0) flags |= SEC_ALLOC | SEC_LOAD; ! if (file_mips_abi != N64_ABI) { sec = subseg_new (".reginfo", (subsegT) 0); --- 1153,1159 ---- if (strcmp (TARGET_OS, "elf") != 0) flags |= SEC_ALLOC | SEC_LOAD; ! if (mips_abi != N64_ABI) { sec = subseg_new (".reginfo", (subsegT) 0); *************** mips_ip (str, ip) *** 7763,7773 **** if (!insn_error) { static char buf[100]; ! sprintf (buf, ! _("opcode not supported on this processor: %s (%s)"), ! mips_cpu_to_str (mips_arch), ! mips_isa_to_str (mips_opts.isa)); ! insn_error = buf; } if (save_c) --- 7739,7753 ---- if (!insn_error) { static char buf[100]; ! if (mips_arch_info->is_isa) ! sprintf (buf, ! _("opcode not supported at this ISA level (%s)"), ! mips_cpu_info_from_isa (mips_opts.isa)->name); ! else ! sprintf (buf, ! _("opcode not supported on this processor: %s (%s)"), ! mips_arch_info->name, ! mips_cpu_info_from_isa (mips_opts.isa)->name); insn_error = buf; } if (save_c) *************** struct option md_longopts[] = *** 9892,9899 **** {"march", required_argument, NULL, OPTION_MARCH}, #define OPTION_MTUNE (OPTION_MD_BASE + 22) {"mtune", required_argument, NULL, OPTION_MTUNE}, ! #define OPTION_MCPU (OPTION_MD_BASE + 23) ! {"mcpu", required_argument, NULL, OPTION_MCPU}, #define OPTION_M4650 (OPTION_MD_BASE + 24) {"m4650", no_argument, NULL, OPTION_M4650}, #define OPTION_NO_M4650 (OPTION_MD_BASE + 25) --- 9872,9879 ---- {"march", required_argument, NULL, OPTION_MARCH}, #define OPTION_MTUNE (OPTION_MD_BASE + 22) {"mtune", required_argument, NULL, OPTION_MTUNE}, ! #define OPTION_FP64 (OPTION_MD_BASE + 23) ! {"mfp64", no_argument, NULL, OPTION_FP64}, #define OPTION_M4650 (OPTION_MD_BASE + 24) {"m4650", no_argument, NULL, OPTION_M4650}, #define OPTION_NO_M4650 (OPTION_MD_BASE + 25) *************** struct option md_longopts[] = *** 9946,9951 **** --- 9926,9949 ---- }; size_t md_longopts_size = sizeof (md_longopts); + /* Set STRING_PTR (either &mips_arch_string or &mips_tune_string) to + NEW_VALUE. Warn if another value was already specified. Note: + we have to defer parsing the -march and -mtune arguments in order + to handle 'from-abi' correctly, since the ABI might be specified + in a later argument. */ + + static void + mips_set_option_string (string_ptr, new_value) + const char **string_ptr, *new_value; + { + if (*string_ptr != 0 && strcasecmp (*string_ptr, new_value) != 0) + as_warn (_("A different %s was already specified, is now %s"), + string_ptr == &mips_arch_string ? "-march" : "-mtune", + new_value); + + *string_ptr = new_value; + } + int md_parse_option (c, arg) int c; *************** md_parse_option (c, arg) *** 10001,10130 **** break; case OPTION_MIPS1: ! mips_opts.isa = ISA_MIPS1; break; case OPTION_MIPS2: ! mips_opts.isa = ISA_MIPS2; break; case OPTION_MIPS3: ! mips_opts.isa = ISA_MIPS3; break; case OPTION_MIPS4: ! mips_opts.isa = ISA_MIPS4; break; case OPTION_MIPS5: ! mips_opts.isa = ISA_MIPS5; break; case OPTION_MIPS32: ! mips_opts.isa = ISA_MIPS32; break; case OPTION_MIPS64: ! mips_opts.isa = ISA_MIPS64; break; case OPTION_MTUNE: ! case OPTION_MARCH: ! case OPTION_MCPU: ! { ! int cpu = CPU_UNKNOWN; ! ! /* Identify the processor type. */ ! if (strcasecmp (arg, "default") != 0) ! { ! const struct mips_cpu_info *ci; ! ! ci = mips_cpu_info_from_name (arg); ! if (ci == NULL || ci->is_isa) ! { ! switch (c) ! { ! case OPTION_MTUNE: ! as_fatal (_("invalid architecture -mtune=%s"), arg); ! break; ! case OPTION_MARCH: ! as_fatal (_("invalid architecture -march=%s"), arg); ! break; ! case OPTION_MCPU: ! as_fatal (_("invalid architecture -mcpu=%s"), arg); ! break; ! } ! } ! else ! cpu = ci->cpu; ! } ! switch (c) ! { ! case OPTION_MTUNE: ! if (mips_tune != CPU_UNKNOWN && mips_tune != cpu) ! as_warn (_("A different -mtune= was already specified, is now " ! "-mtune=%s"), arg); ! mips_tune = cpu; ! break; ! case OPTION_MARCH: ! if (mips_arch != CPU_UNKNOWN && mips_arch != cpu) ! as_warn (_("A different -march= was already specified, is now " ! "-march=%s"), arg); ! mips_arch = cpu; ! break; ! case OPTION_MCPU: ! if (mips_cpu != CPU_UNKNOWN && mips_cpu != cpu) ! as_warn (_("A different -mcpu= was already specified, is now " ! "-mcpu=%s"), arg); ! mips_cpu = cpu; ! } ! } break; case OPTION_M4650: ! if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4650) ! || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4650)) ! as_warn (_("A different -march= or -mtune= was already specified, " ! "is now -m4650")); ! mips_arch = CPU_R4650; ! mips_tune = CPU_R4650; break; case OPTION_NO_M4650: break; case OPTION_M4010: ! if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4010) ! || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4010)) ! as_warn (_("A different -march= or -mtune= was already specified, " ! "is now -m4010")); ! mips_arch = CPU_R4010; ! mips_tune = CPU_R4010; break; case OPTION_NO_M4010: break; case OPTION_M4100: ! if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_VR4100) ! || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_VR4100)) ! as_warn (_("A different -march= or -mtune= was already specified, " ! "is now -m4100")); ! mips_arch = CPU_VR4100; ! mips_tune = CPU_VR4100; break; case OPTION_NO_M4100: break; case OPTION_M3900: ! if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R3900) ! || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R3900)) ! as_warn (_("A different -march= or -mtune= was already specified, " ! "is now -m3900")); ! mips_arch = CPU_R3900; ! mips_tune = CPU_R3900; break; case OPTION_NO_M3900: --- 9999,10066 ---- break; case OPTION_MIPS1: ! file_mips_isa = ISA_MIPS1; break; case OPTION_MIPS2: ! file_mips_isa = ISA_MIPS2; break; case OPTION_MIPS3: ! file_mips_isa = ISA_MIPS3; break; case OPTION_MIPS4: ! file_mips_isa = ISA_MIPS4; break; case OPTION_MIPS5: ! file_mips_isa = ISA_MIPS5; break; case OPTION_MIPS32: ! file_mips_isa = ISA_MIPS32; break; case OPTION_MIPS64: ! file_mips_isa = ISA_MIPS64; break; case OPTION_MTUNE: ! mips_set_option_string (&mips_tune_string, arg); ! break; ! case OPTION_MARCH: ! mips_set_option_string (&mips_arch_string, arg); break; case OPTION_M4650: ! mips_set_option_string (&mips_arch_string, "4650"); ! mips_set_option_string (&mips_tune_string, "4650"); break; case OPTION_NO_M4650: break; case OPTION_M4010: ! mips_set_option_string (&mips_arch_string, "4010"); ! mips_set_option_string (&mips_tune_string, "4010"); break; case OPTION_NO_M4010: break; case OPTION_M4100: ! mips_set_option_string (&mips_arch_string, "4100"); ! mips_set_option_string (&mips_tune_string, "4100"); break; case OPTION_NO_M4100: break; case OPTION_M3900: ! mips_set_option_string (&mips_arch_string, "3900"); ! mips_set_option_string (&mips_tune_string, "3900"); break; case OPTION_NO_M3900: *************** md_parse_option (c, arg) *** 10227,10233 **** as_bad (_("-32 is supported for ELF format only")); return 0; } ! mips_opts.abi = O32_ABI; break; case OPTION_N32: --- 10163,10169 ---- as_bad (_("-32 is supported for ELF format only")); return 0; } ! mips_abi = O32_ABI; break; case OPTION_N32: *************** md_parse_option (c, arg) *** 10236,10242 **** as_bad (_("-n32 is supported for ELF format only")); return 0; } ! mips_opts.abi = N32_ABI; break; case OPTION_64: --- 10172,10178 ---- as_bad (_("-n32 is supported for ELF format only")); return 0; } ! mips_abi = N32_ABI; break; case OPTION_64: *************** md_parse_option (c, arg) *** 10245,10251 **** as_bad (_("-64 is supported for ELF format only")); return 0; } ! mips_opts.abi = N64_ABI; if (! support_64bit_objects()) as_fatal (_("No compiled in support for 64 bit object file format")); break; --- 10181,10187 ---- as_bad (_("-64 is supported for ELF format only")); return 0; } ! mips_abi = N64_ABI; if (! support_64bit_objects()) as_fatal (_("No compiled in support for 64 bit object file format")); break; *************** md_parse_option (c, arg) *** 10253,10272 **** case OPTION_GP32: file_mips_gp32 = 1; - if (mips_opts.abi != O32_ABI) - mips_opts.abi = NO_ABI; break; case OPTION_GP64: file_mips_gp32 = 0; - if (mips_opts.abi == O32_ABI) - mips_opts.abi = NO_ABI; break; case OPTION_FP32: file_mips_fp32 = 1; ! if (mips_opts.abi != O32_ABI) ! mips_opts.abi = NO_ABI; break; #ifdef OBJ_ELF --- 10189,10206 ---- case OPTION_GP32: file_mips_gp32 = 1; break; case OPTION_GP64: file_mips_gp32 = 0; break; case OPTION_FP32: file_mips_fp32 = 1; ! break; ! ! case OPTION_FP64: ! file_mips_fp32 = 0; break; #ifdef OBJ_ELF *************** md_parse_option (c, arg) *** 10277,10296 **** return 0; } if (strcmp (arg, "32") == 0) ! mips_opts.abi = O32_ABI; else if (strcmp (arg, "o64") == 0) ! mips_opts.abi = O64_ABI; else if (strcmp (arg, "n32") == 0) ! mips_opts.abi = N32_ABI; else if (strcmp (arg, "64") == 0) { ! mips_opts.abi = N64_ABI; if (! support_64bit_objects()) as_fatal (_("No compiled in support for 64 bit object file " "format")); } else if (strcmp (arg, "eabi") == 0) ! mips_opts.abi = EABI_ABI; else { as_fatal (_("invalid abi -mabi=%s"), arg); --- 10211,10230 ---- return 0; } if (strcmp (arg, "32") == 0) ! mips_abi = O32_ABI; else if (strcmp (arg, "o64") == 0) ! mips_abi = O64_ABI; else if (strcmp (arg, "n32") == 0) ! mips_abi = N32_ABI; else if (strcmp (arg, "64") == 0) { ! mips_abi = N64_ABI; if (! support_64bit_objects()) as_fatal (_("No compiled in support for 64 bit object file " "format")); } else if (strcmp (arg, "eabi") == 0) ! mips_abi = EABI_ABI; else { as_fatal (_("invalid abi -mabi=%s"), arg); *************** md_parse_option (c, arg) *** 10323,10466 **** return 1; } static void ! show (stream, string, col_p, first_p) ! FILE *stream; ! char *string; ! int *col_p; ! int *first_p; { ! if (*first_p) ! { ! fprintf (stream, "%24s", ""); ! *col_p = 24; ! } ! else ! { ! fprintf (stream, ", "); ! *col_p += 2; ! } ! ! if (*col_p + strlen (string) > 72) { ! fprintf (stream, "\n%24s", ""); ! *col_p = 24; } - - fprintf (stream, "%s", string); - *col_p += strlen (string); - - *first_p = 0; } - void - md_show_usage (stream) - FILE *stream; - { - int column, first; - - fprintf (stream, _("\ - MIPS options:\n\ - -membedded-pic generate embedded position independent code\n\ - -EB generate big endian output\n\ - -EL generate little endian output\n\ - -g, -g2 do not remove unneeded NOPs or swap branches\n\ - -G NUM allow referencing objects up to NUM bytes\n\ - implicitly with the gp register [default 8]\n")); - fprintf (stream, _("\ - -mips1 generate MIPS ISA I instructions\n\ - -mips2 generate MIPS ISA II instructions\n\ - -mips3 generate MIPS ISA III instructions\n\ - -mips4 generate MIPS ISA IV instructions\n\ - -mips5 generate MIPS ISA V instructions\n\ - -mips32 generate MIPS32 ISA instructions\n\ - -mips64 generate MIPS64 ISA instructions\n\ - -march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n")); - - first = 1; - - show (stream, "2000", &column, &first); - show (stream, "3000", &column, &first); - show (stream, "3900", &column, &first); - show (stream, "4000", &column, &first); - show (stream, "4010", &column, &first); - show (stream, "4100", &column, &first); - show (stream, "4111", &column, &first); - show (stream, "4300", &column, &first); - show (stream, "4400", &column, &first); - show (stream, "4600", &column, &first); - show (stream, "4650", &column, &first); - show (stream, "5000", &column, &first); - show (stream, "5200", &column, &first); - show (stream, "5230", &column, &first); - show (stream, "5231", &column, &first); - show (stream, "5261", &column, &first); - show (stream, "5721", &column, &first); - show (stream, "6000", &column, &first); - show (stream, "8000", &column, &first); - show (stream, "10000", &column, &first); - show (stream, "12000", &column, &first); - show (stream, "sb1", &column, &first); - fputc ('\n', stream); - - fprintf (stream, _("\ - -mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\ - -no-mCPU don't generate code specific to CPU.\n\ - For -mCPU and -no-mCPU, CPU must be one of:\n")); - - first = 1; - - show (stream, "3900", &column, &first); - show (stream, "4010", &column, &first); - show (stream, "4100", &column, &first); - show (stream, "4650", &column, &first); - fputc ('\n', stream); - - fprintf (stream, _("\ - -mips16 generate mips16 instructions\n\ - -no-mips16 do not generate mips16 instructions\n")); - fprintf (stream, _("\ - -mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\ - -mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\ - -O0 remove unneeded NOPs, do not swap branches\n\ - -O remove unneeded NOPs and swap branches\n\ - -n warn about NOPs generated from macros\n\ - --[no-]construct-floats [dis]allow floating point values to be constructed\n\ - --trap, --no-break trap exception on div by 0 and mult overflow\n\ - --break, --no-trap break exception on div by 0 and mult overflow\n")); - #ifdef OBJ_ELF - fprintf (stream, _("\ - -KPIC, -call_shared generate SVR4 position independent code\n\ - -non_shared do not generate position independent code\n\ - -xgot assume a 32 bit GOT\n\ - -mabi=ABI create ABI conformant object file for:\n")); ! first = 1; ! show (stream, "32", &column, &first); ! show (stream, "o64", &column, &first); ! show (stream, "n32", &column, &first); ! show (stream, "64", &column, &first); ! show (stream, "eabi", &column, &first); - fputc ('\n', stream); - fprintf (stream, _("\ - -32 create o32 ABI object file (default)\n\ - -n32 create n32 ABI object file\n\ - -64 create 64 ABI object file\n")); - #endif - } - void mips_after_parse_args () { - const char *cpu; - char *a = NULL; - int mips_isa_from_cpu; - const struct mips_cpu_info *ci; - /* GP relative stuff not working for PE */ if (strncmp (TARGET_OS, "pe", 2) == 0 && g_switch_value != 0) --- 10257,10296 ---- return 1; } + + /* Set up globals to generate code for the ISA or processor + described by INFO. */ static void ! mips_set_architecture (info) ! const struct mips_cpu_info *info; { ! if (info != 0) { ! mips_arch_info = info; ! mips_arch = info->cpu; ! mips_opts.isa = info->isa; } } ! /* Likewise for tuning. */ ! static void ! mips_set_tune (info) ! const struct mips_cpu_info *info; ! { ! if (info != 0) ! { ! mips_tune_info = info; ! mips_tune = info->cpu; ! } ! } void mips_after_parse_args () { /* GP relative stuff not working for PE */ if (strncmp (TARGET_OS, "pe", 2) == 0 && g_switch_value != 0) *************** mips_after_parse_args () *** 10470,10653 **** g_switch_value = 0; } ! cpu = TARGET_CPU; ! if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0) ! { ! a = xmalloc (sizeof TARGET_CPU); ! strcpy (a, TARGET_CPU); ! a[(sizeof TARGET_CPU) - 3] = '\0'; ! cpu = a; ! } ! /* Backward compatibility for historic -mcpu= option. Check for ! incompatible options, warn if -mcpu is used. */ ! if (mips_cpu != CPU_UNKNOWN ! && mips_arch != CPU_UNKNOWN ! && mips_cpu != mips_arch) ! { ! as_fatal (_("The -mcpu option can't be used together with -march. " ! "Use -mtune instead of -mcpu.")); ! } ! if (mips_cpu != CPU_UNKNOWN ! && mips_tune != CPU_UNKNOWN ! && mips_cpu != mips_tune) ! { ! as_fatal (_("The -mcpu option can't be used together with -mtune. " ! "Use -march instead of -mcpu.")); ! } ! #if 1 ! /* For backward compatibility, let -mipsN set various defaults. */ ! /* This code should go away, to be replaced with something rather more ! draconian. Until GCC 3.1 has been released for some reasonable ! amount of time, however, we need to support this. */ ! if (mips_opts.isa != ISA_UNKNOWN) { ! /* Translate -mipsN to the appropriate settings of file_mips_gp32 ! and file_mips_fp32. Tag binaries as using the mipsN ISA. */ ! if (file_mips_gp32 < 0) ! { ! if (ISA_HAS_64BIT_REGS (mips_opts.isa)) ! file_mips_gp32 = 0; ! else ! file_mips_gp32 = 1; ! } ! if (file_mips_fp32 < 0) ! { ! if (ISA_HAS_64BIT_REGS (mips_opts.isa)) ! file_mips_fp32 = 0; ! else ! file_mips_fp32 = 1; ! } ! ! ci = mips_cpu_info_from_isa (mips_opts.isa); ! assert (ci != NULL); ! /* -mipsN has higher priority than -mcpu but lower than -march. */ ! if (mips_arch == CPU_UNKNOWN) ! mips_arch = ci->cpu; ! ! /* Default mips_abi. */ ! if (mips_opts.abi == NO_ABI) { ! if (mips_opts.isa == ISA_MIPS1 || mips_opts.isa == ISA_MIPS2) ! mips_opts.abi = O32_ABI; ! else if (mips_opts.isa == ISA_MIPS3 || mips_opts.isa == ISA_MIPS4) ! mips_opts.abi = O64_ABI; } } ! if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN) ! { ! ci = mips_cpu_info_from_cpu (mips_cpu); ! assert (ci != NULL); ! mips_arch = ci->cpu; ! as_warn (_("The -mcpu option is deprecated. Please use -march and " ! "-mtune instead.")); ! } ! ! /* Set tune from -mcpu, not from -mipsN. */ ! if (mips_tune == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN) ! { ! ci = mips_cpu_info_from_cpu (mips_cpu); ! assert (ci != NULL); ! mips_tune = ci->cpu; ! } ! ! /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was ! specified on the command line, or some other value if one was. ! Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on ! the command line, or will be set otherwise if one was. */ ! if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN) ! /* Handled above. */; ! #else ! if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN) ! { ! ci = mips_cpu_info_from_cpu (mips_cpu); ! assert (ci != NULL); ! mips_arch = ci->cpu; ! as_warn (_("The -mcpu option is deprecated. Please use -march and " ! "-mtune instead.")); ! } ! /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was ! specified on the command line, or some other value if one was. ! Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on ! the command line, or will be set otherwise if one was. */ ! if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN) ! { ! /* We have to check if the isa is the default isa of arch. Otherwise ! we'll get invalid object file headers. */ ! ci = mips_cpu_info_from_cpu (mips_arch); ! assert (ci != NULL); ! if (mips_opts.isa != ci->isa) ! { ! /* This really should be an error instead of a warning, but old ! compilers only have -mcpu which sets both arch and tune. For ! now, we discard arch and preserve tune. */ ! as_warn (_("The -march option is incompatible to -mipsN and " ! "therefore ignored.")); ! if (mips_tune == CPU_UNKNOWN) ! mips_tune = mips_arch; ! ci = mips_cpu_info_from_isa (mips_opts.isa); ! assert (ci != NULL); ! mips_arch = ci->cpu; ! } ! } ! #endif ! else if (mips_arch != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN) ! { ! /* We have ARCH, we need ISA. */ ! ci = mips_cpu_info_from_cpu (mips_arch); ! assert (ci != NULL); ! mips_opts.isa = ci->isa; ! } ! else if (mips_arch == CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN) { ! /* We have ISA, we need default ARCH. */ ! ci = mips_cpu_info_from_isa (mips_opts.isa); ! assert (ci != NULL); ! mips_arch = ci->cpu; } else { ! /* We need to set both ISA and ARCH from target cpu. */ ! ci = mips_cpu_info_from_name (cpu); ! if (ci == NULL) ! ci = mips_cpu_info_from_cpu (CPU_R3000); ! assert (ci != NULL); ! mips_opts.isa = ci->isa; ! mips_arch = ci->cpu; } ! if (mips_tune == CPU_UNKNOWN) ! mips_tune = mips_arch; ! ci = mips_cpu_info_from_cpu (mips_arch); ! assert (ci != NULL); ! mips_isa_from_cpu = ci->isa; ! /* End of TARGET_CPU processing, get rid of malloced memory ! if necessary. */ ! cpu = NULL; ! if (a != NULL) ! { ! free (a); ! a = NULL; ! } if (mips_opts.isa == ISA_MIPS1 && mips_trap) as_bad (_("trap exception not supported at ISA 1")); - /* If they asked for mips1 or mips2 and a cpu that is - mips3 or greater, then mark the object file 32BITMODE. */ - if (mips_isa_from_cpu != ISA_UNKNOWN - && ! ISA_HAS_64BIT_REGS (mips_opts.isa) - && ISA_HAS_64BIT_REGS (mips_isa_from_cpu)) - mips_32bitmode = 1; - /* If the selected architecture includes support for ASEs, enable generation of code for them. */ if (mips_opts.mips16 == -1) --- 10300,10387 ---- g_switch_value = 0; } ! /* The following code determines the architecture and register size. ! Similar code was added to GCC 3.2 (see override_options() in ! config/mips/mips.c). The GAS and GCC code should be kept in ! sync as much as possible. */ ! if (mips_arch_string != 0) ! mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string)); ! if (mips_tune_string != 0) ! mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string)); ! if (file_mips_isa != ISA_UNKNOWN) { ! /* Handle -mipsN. At this point, file_mips_isa contains the ! ISA level specified by -mipsN, while mips_opts.isa contains ! the -march selection (if any). */ ! if (mips_arch_info != 0) { ! /* -march takes precedence over -mipsN, since it is more descriptive. ! There's no harm in specifying both as long as the ISA levels ! are the same. */ ! if (file_mips_isa != mips_opts.isa) ! as_bad (_("-%s conflicts with the other architecture options, which imply -%s"), ! mips_cpu_info_from_isa (file_mips_isa)->name, ! mips_cpu_info_from_isa (mips_opts.isa)->name); } + else + mips_set_architecture (mips_cpu_info_from_isa (file_mips_isa)); } ! if (mips_arch_info == 0) ! mips_set_architecture (mips_parse_cpu ("default CPU", ! MIPS_CPU_STRING_DEFAULT)); ! if (ABI_NEEDS_64BIT_REGS (mips_abi) && !ISA_HAS_64BIT_REGS (mips_opts.isa)) ! as_bad ("-march=%s is not compatible with the selected ABI", ! mips_arch_info->name); ! /* Optimize for mips_arch, unless -mtune selects a different processor. */ ! if (mips_tune_info == 0) ! mips_set_tune (mips_arch_info); ! if (file_mips_gp32 >= 0) { ! /* The user specified the size of the integer registers. Make sure ! it agrees with the ABI and ISA. */ ! if (file_mips_gp32 == 0 && !ISA_HAS_64BIT_REGS (mips_opts.isa)) ! as_bad (_("-mgp64 used with a 32-bit processor")); ! else if (file_mips_gp32 == 1 && ABI_NEEDS_64BIT_REGS (mips_abi)) ! as_bad (_("-mgp32 used with a 64-bit ABI")); ! else if (file_mips_gp32 == 0 && ABI_NEEDS_32BIT_REGS (mips_abi)) ! as_bad (_("-mgp64 used with a 32-bit ABI")); } else { ! /* Infer the integer register size from the ABI and processor. ! Restrict ourselves to 32-bit registers if that's all the ! processor has, or if the ABI cannot handle 64-bit registers. */ ! file_mips_gp32 = (ABI_NEEDS_32BIT_REGS (mips_abi) ! || !ISA_HAS_64BIT_REGS (mips_opts.isa)); } ! /* ??? GAS treats single-float processors as though they had 64-bit ! float registers (although it complains when double-precision ! instructions are used). As things stand, saying they have 32-bit ! registers would lead to spurious "register must be even" messages. ! So here we assume float registers are always the same size as ! integer ones, unless the user says otherwise. */ ! if (file_mips_fp32 < 0) ! file_mips_fp32 = file_mips_gp32; ! /* End of GCC-shared inference code. */ ! /* ??? When do we want this flag to be set? Who uses it? */ ! if (file_mips_gp32 == 1 ! && mips_abi == NO_ABI ! && ISA_HAS_64BIT_REGS (mips_opts.isa)) ! mips_32bitmode = 1; if (mips_opts.isa == ISA_MIPS1 && mips_trap) as_bad (_("trap exception not supported at ISA 1")); /* If the selected architecture includes support for ASEs, enable generation of code for them. */ if (mips_opts.mips16 == -1) *************** mips_after_parse_args () *** 10657,10669 **** if (mips_opts.ase_mdmx == -1) mips_opts.ase_mdmx = (CPU_HAS_MDMX (mips_arch)) ? 1 : 0; - if (file_mips_gp32 < 0) - file_mips_gp32 = 0; - if (file_mips_fp32 < 0) - file_mips_fp32 = 0; - file_mips_isa = mips_opts.isa; - file_mips_abi = mips_opts.abi; file_ase_mips16 = mips_opts.mips16; file_ase_mips3d = mips_opts.ase_mips3d; file_ase_mdmx = mips_opts.ase_mdmx; --- 10391,10397 ---- *************** s_mipsset (x) *** 11738,11744 **** case 0: mips_opts.gp32 = file_mips_gp32; mips_opts.fp32 = file_mips_fp32; - mips_opts.abi = file_mips_abi; break; case 1: case 2: --- 11466,11471 ---- *************** s_mipsset (x) *** 11750,11758 **** case 4: case 5: case 64: - /* Loosen ABI register width restriction. */ - if (mips_opts.abi == O32_ABI) - mips_opts.abi = NO_ABI; mips_opts.gp32 = 0; mips_opts.fp32 = 0; break; --- 11477,11482 ---- *************** void *** 13201,13207 **** mips_elf_final_processing () { /* Write out the register information. */ ! if (file_mips_abi != N64_ABI) { Elf32_RegInfo s; --- 12925,12931 ---- mips_elf_final_processing () { /* Write out the register information. */ ! if (mips_abi != N64_ABI) { Elf32_RegInfo s; *************** mips_elf_final_processing () *** 13251,13272 **** elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX; /* Set the MIPS ELF ABI flags. */ ! if (file_mips_abi == NO_ABI) ! ; ! else if (file_mips_abi == O32_ABI) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32; ! else if (file_mips_abi == O64_ABI) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64; ! else if (file_mips_abi == EABI_ABI) { ! /* Set the EABI kind based on the ISA. This isn't really ! the best, but then neither is basing the abi on the isa. */ ! if (ISA_HAS_64BIT_REGS (file_mips_isa)) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64; else elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32; } ! else if (file_mips_abi == N32_ABI) elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2; /* Nothing to do for N64_ABI. */ --- 12975,12992 ---- elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX; /* Set the MIPS ELF ABI flags. */ ! if (mips_abi == O32_ABI && USE_E_MIPS_ABI_O32) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32; ! else if (mips_abi == O64_ABI) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64; ! else if (mips_abi == EABI_ABI) { ! if (!file_mips_gp32) elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64; else elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32; } ! else if (mips_abi == N32_ABI) elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2; /* Nothing to do for N64_ABI. */ *************** s_loc (x) *** 13707,13882 **** } #endif ! /* CPU name/ISA/number mapping table. ! ! Entries are grouped by type. The first matching CPU or ISA entry ! gets chosen by CPU or ISA, so it should be the 'canonical' name ! for that type. Entries after that within the type are sorted ! alphabetically. ! Case is ignored in comparison, so put the canonical entry in the ! appropriate case but everything else in lower case to ease eye pain. */ static const struct mips_cpu_info mips_cpu_info_table[] = { ! /* MIPS1 ISA */ ! { "MIPS1", 1, ISA_MIPS1, CPU_R3000, }, ! { "mips", 1, ISA_MIPS1, CPU_R3000, }, ! /* MIPS2 ISA */ ! { "MIPS2", 1, ISA_MIPS2, CPU_R6000, }, ! /* MIPS3 ISA */ ! { "MIPS3", 1, ISA_MIPS3, CPU_R4000, }, ! /* MIPS4 ISA */ ! { "MIPS4", 1, ISA_MIPS4, CPU_R8000, }, ! /* MIPS5 ISA */ ! { "MIPS5", 1, ISA_MIPS5, CPU_MIPS5, }, ! { "Generic-MIPS5", 0, ISA_MIPS5, CPU_MIPS5, }, ! /* MIPS32 ISA */ ! { "MIPS32", 1, ISA_MIPS32, CPU_MIPS32, }, ! { "mipsisa32", 0, ISA_MIPS32, CPU_MIPS32, }, ! { "Generic-MIPS32", 0, ISA_MIPS32, CPU_MIPS32, }, { "4kc", 0, ISA_MIPS32, CPU_MIPS32, }, ! { "4km", 0, ISA_MIPS32, CPU_MIPS32, }, ! { "4kp", 0, ISA_MIPS32, CPU_MIPS32, }, ! ! /* For historical reasons. */ ! { "MIPS64", 1, ISA_MIPS3, CPU_R4000, }, ! /* MIPS64 ISA */ ! { "mipsisa64", 1, ISA_MIPS64, CPU_MIPS64, }, ! { "Generic-MIPS64", 0, ISA_MIPS64, CPU_MIPS64, }, ! { "5kc", 0, ISA_MIPS64, CPU_MIPS64, }, ! { "20kc", 0, ISA_MIPS64, CPU_MIPS64, }, ! /* R2000 CPU */ ! { "R2000", 0, ISA_MIPS1, CPU_R2000, }, ! { "2000", 0, ISA_MIPS1, CPU_R2000, }, ! { "2k", 0, ISA_MIPS1, CPU_R2000, }, ! { "r2k", 0, ISA_MIPS1, CPU_R2000, }, ! /* R3000 CPU */ ! { "R3000", 0, ISA_MIPS1, CPU_R3000, }, ! { "3000", 0, ISA_MIPS1, CPU_R3000, }, ! { "3k", 0, ISA_MIPS1, CPU_R3000, }, ! { "r3k", 0, ISA_MIPS1, CPU_R3000, }, - /* TX3900 CPU */ - { "R3900", 0, ISA_MIPS1, CPU_R3900, }, - { "3900", 0, ISA_MIPS1, CPU_R3900, }, - { "mipstx39", 0, ISA_MIPS1, CPU_R3900, }, ! /* R4000 CPU */ ! { "R4000", 0, ISA_MIPS3, CPU_R4000, }, ! { "4000", 0, ISA_MIPS3, CPU_R4000, }, ! { "4k", 0, ISA_MIPS3, CPU_R4000, }, /* beware */ ! { "r4k", 0, ISA_MIPS3, CPU_R4000, }, ! /* R4010 CPU */ ! { "R4010", 0, ISA_MIPS2, CPU_R4010, }, ! { "4010", 0, ISA_MIPS2, CPU_R4010, }, ! /* R4400 CPU */ ! { "R4400", 0, ISA_MIPS3, CPU_R4400, }, ! { "4400", 0, ISA_MIPS3, CPU_R4400, }, ! /* R4600 CPU */ ! { "R4600", 0, ISA_MIPS3, CPU_R4600, }, ! { "4600", 0, ISA_MIPS3, CPU_R4600, }, ! { "mips64orion", 0, ISA_MIPS3, CPU_R4600, }, ! { "orion", 0, ISA_MIPS3, CPU_R4600, }, - /* R4650 CPU */ - { "R4650", 0, ISA_MIPS3, CPU_R4650, }, - { "4650", 0, ISA_MIPS3, CPU_R4650, }, ! /* R6000 CPU */ ! { "R6000", 0, ISA_MIPS2, CPU_R6000, }, ! { "6000", 0, ISA_MIPS2, CPU_R6000, }, ! { "6k", 0, ISA_MIPS2, CPU_R6000, }, ! { "r6k", 0, ISA_MIPS2, CPU_R6000, }, ! /* R8000 CPU */ ! { "R8000", 0, ISA_MIPS4, CPU_R8000, }, ! { "8000", 0, ISA_MIPS4, CPU_R8000, }, ! { "8k", 0, ISA_MIPS4, CPU_R8000, }, ! { "r8k", 0, ISA_MIPS4, CPU_R8000, }, ! /* R10000 CPU */ ! { "R10000", 0, ISA_MIPS4, CPU_R10000, }, ! { "10000", 0, ISA_MIPS4, CPU_R10000, }, ! { "10k", 0, ISA_MIPS4, CPU_R10000, }, ! { "r10k", 0, ISA_MIPS4, CPU_R10000, }, ! /* R12000 CPU */ ! { "R12000", 0, ISA_MIPS4, CPU_R12000, }, ! { "12000", 0, ISA_MIPS4, CPU_R12000, }, ! { "12k", 0, ISA_MIPS4, CPU_R12000, }, ! { "r12k", 0, ISA_MIPS4, CPU_R12000, }, ! /* VR4100 CPU */ ! { "VR4100", 0, ISA_MIPS3, CPU_VR4100, }, ! { "4100", 0, ISA_MIPS3, CPU_VR4100, }, ! { "mips64vr4100", 0, ISA_MIPS3, CPU_VR4100, }, ! { "r4100", 0, ISA_MIPS3, CPU_VR4100, }, ! /* VR4111 CPU */ ! { "VR4111", 0, ISA_MIPS3, CPU_R4111, }, ! { "4111", 0, ISA_MIPS3, CPU_R4111, }, ! { "mips64vr4111", 0, ISA_MIPS3, CPU_R4111, }, ! { "r4111", 0, ISA_MIPS3, CPU_R4111, }, - /* VR4300 CPU */ - { "VR4300", 0, ISA_MIPS3, CPU_R4300, }, - { "4300", 0, ISA_MIPS3, CPU_R4300, }, - { "mips64vr4300", 0, ISA_MIPS3, CPU_R4300, }, - { "r4300", 0, ISA_MIPS3, CPU_R4300, }, ! /* VR5000 CPU */ ! { "VR5000", 0, ISA_MIPS4, CPU_R5000, }, ! { "5000", 0, ISA_MIPS4, CPU_R5000, }, ! { "5k", 0, ISA_MIPS4, CPU_R5000, }, ! { "mips64vr5000", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5000", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5200", 0, ISA_MIPS4, CPU_R5000, }, ! { "rm5200", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5230", 0, ISA_MIPS4, CPU_R5000, }, ! { "rm5230", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5231", 0, ISA_MIPS4, CPU_R5000, }, ! { "rm5231", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5261", 0, ISA_MIPS4, CPU_R5000, }, ! { "rm5261", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5721", 0, ISA_MIPS4, CPU_R5000, }, ! { "rm5721", 0, ISA_MIPS4, CPU_R5000, }, ! { "r5k", 0, ISA_MIPS4, CPU_R5000, }, ! { "r7000", 0, ISA_MIPS4, CPU_R5000, }, ! ! /* Broadcom SB-1 CPU */ ! { "SB-1", 0, ISA_MIPS64, CPU_SB1, }, ! { "sb-1250", 0, ISA_MIPS64, CPU_SB1, }, ! { "sb1", 0, ISA_MIPS64, CPU_SB1, }, ! { "sb1250", 0, ISA_MIPS64, CPU_SB1, }, ! /* End marker. */ ! { NULL, 0, 0, 0, }, ! }; static const struct mips_cpu_info * ! mips_cpu_info_from_name (name) ! const char *name; { ! int i; ! for (i = 0; mips_cpu_info_table[i].name != NULL; i++) ! if (strcasecmp (name, mips_cpu_info_table[i].name) == 0) ! return (&mips_cpu_info_table[i]); ! return NULL; } static const struct mips_cpu_info * mips_cpu_info_from_isa (isa) int isa; --- 13427,13604 ---- } #endif ! /* A table describing all the processors gas knows about. Names are ! matched in the order listed. ! To ease comparison, please keep this table in the same order as ! gcc's mips_cpu_info_table[]. */ static const struct mips_cpu_info mips_cpu_info_table[] = { ! /* Entries for generic ISAs */ ! { "mips1", 1, ISA_MIPS1, CPU_R3000 }, ! { "mips2", 1, ISA_MIPS2, CPU_R6000 }, ! { "mips3", 1, ISA_MIPS3, CPU_R4000 }, ! { "mips4", 1, ISA_MIPS4, CPU_R8000 }, ! { "mips5", 1, ISA_MIPS5, CPU_MIPS5 }, ! { "mips32", 1, ISA_MIPS32, CPU_MIPS32 }, ! { "mips64", 1, ISA_MIPS64, CPU_MIPS64 }, ! /* MIPS I */ ! { "r3000", 0, ISA_MIPS1, CPU_R3000 }, ! { "r2000", 0, ISA_MIPS1, CPU_R3000 }, ! { "r3900", 0, ISA_MIPS1, CPU_R3900 }, ! /* MIPS II */ ! { "r6000", 0, ISA_MIPS2, CPU_R6000 }, ! /* MIPS III */ ! { "r4000", 0, ISA_MIPS3, CPU_R4000 }, ! { "r4010", 0, ISA_MIPS2, CPU_R4010 }, ! { "vr4100", 0, ISA_MIPS3, CPU_VR4100 }, ! { "vr4111", 0, ISA_MIPS3, CPU_R4111 }, ! { "vr4300", 0, ISA_MIPS3, CPU_R4300 }, ! { "r4400", 0, ISA_MIPS3, CPU_R4400 }, ! { "r4600", 0, ISA_MIPS3, CPU_R4600 }, ! { "orion", 0, ISA_MIPS3, CPU_R4600 }, ! { "r4650", 0, ISA_MIPS3, CPU_R4650 }, ! /* MIPS IV */ ! { "r8000", 0, ISA_MIPS4, CPU_R8000 }, ! { "r10000", 0, ISA_MIPS4, CPU_R10000 }, ! { "r12000", 0, ISA_MIPS4, CPU_R12000 }, ! { "vr5000", 0, ISA_MIPS4, CPU_R5000 }, ! { "rm5200", 0, ISA_MIPS4, CPU_R5000 }, ! { "rm5230", 0, ISA_MIPS4, CPU_R5000 }, ! { "rm5231", 0, ISA_MIPS4, CPU_R5000 }, ! { "rm5261", 0, ISA_MIPS4, CPU_R5000 }, ! { "rm5721", 0, ISA_MIPS4, CPU_R5000 }, ! { "r7000", 0, ISA_MIPS4, CPU_R5000 }, ! /* MIPS 32 */ { "4kc", 0, ISA_MIPS32, CPU_MIPS32, }, ! { "4km", 0, ISA_MIPS32, CPU_MIPS32 }, ! { "4kp", 0, ISA_MIPS32, CPU_MIPS32 }, ! /* MIPS 64 */ ! { "5kc", 0, ISA_MIPS64, CPU_MIPS64 }, ! { "20kc", 0, ISA_MIPS64, CPU_MIPS64 }, ! /* Broadcom SB-1 CPU */ ! { "SB-1", 0, ISA_MIPS64, CPU_SB1 }, ! { "sb-1250", 0, ISA_MIPS64, CPU_SB1 }, ! { "sb1", 0, ISA_MIPS64, CPU_SB1 }, ! { "sb1250", 0, ISA_MIPS64, CPU_SB1 }, ! /* End marker */ ! { NULL, 0, 0, 0 } ! }; ! /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL ! with a final "000" replaced by "k". Ignore case. ! Note: this function is shared between GCC and GAS. */ ! static boolean ! mips_strict_matching_cpu_name_p (canonical, given) ! const char *canonical, *given; ! { ! while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical)) ! given++, canonical++; ! return ((*given == 0 && *canonical == 0) ! || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0)); ! } ! /* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied ! CPU name. We've traditionally allowed a lot of variation here. ! Note: this function is shared between GCC and GAS. */ ! static boolean ! mips_matching_cpu_name_p (canonical, given) ! const char *canonical, *given; ! { ! /* First see if the name matches exactly, or with a final "000" ! turned into "k". */ ! if (mips_strict_matching_cpu_name_p (canonical, given)) ! return true; ! /* If not, try comparing based on numerical designation alone. ! See if GIVEN is an unadorned number, or 'r' followed by a number. */ ! if (TOLOWER (*given) == 'r') ! given++; ! if (!ISDIGIT (*given)) ! return false; ! /* Skip over some well-known prefixes in the canonical name, ! hoping to find a number there too. */ ! if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r') ! canonical += 2; ! else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm') ! canonical += 2; ! else if (TOLOWER (canonical[0]) == 'r') ! canonical += 1; ! return mips_strict_matching_cpu_name_p (canonical, given); ! } ! /* Parse an option that takes the name of a processor as its argument. ! OPTION is the name of the option and CPU_STRING is the argument. ! Return the corresponding processor enumeration if the CPU_STRING is ! recognized, otherwise report an error and return null. ! A similar function exists in GCC. */ static const struct mips_cpu_info * ! mips_parse_cpu (option, cpu_string) ! const char *option, *cpu_string; { ! const struct mips_cpu_info *p; ! /* 'from-abi' selects the most compatible architecture for the given ! ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the ! EABIs, we have to decide whether we're using the 32-bit or 64-bit ! version. Look first at the -mgp options, if given, otherwise base ! the choice on MIPS_DEFAULT_64BIT. ! Treat NO_ABI like the EABIs. One reason to do this is that the ! plain 'mips' and 'mips64' configs have 'from-abi' as their default ! architecture. This code picks MIPS I for 'mips' and MIPS III for ! 'mips64', just as we did in the days before 'from-abi'. */ ! if (strcasecmp (cpu_string, "from-abi") == 0) ! { ! if (ABI_NEEDS_32BIT_REGS (mips_abi)) ! return mips_cpu_info_from_isa (ISA_MIPS1); ! ! if (ABI_NEEDS_64BIT_REGS (mips_abi)) ! return mips_cpu_info_from_isa (ISA_MIPS3); ! ! if (file_mips_gp32 >= 0) ! return mips_cpu_info_from_isa (file_mips_gp32 ? ISA_MIPS1 : ISA_MIPS3); ! ! return mips_cpu_info_from_isa (MIPS_DEFAULT_64BIT ! ? ISA_MIPS3 ! : ISA_MIPS1); ! } ! ! /* 'default' has traditionally been a no-op. Probably not very useful. */ ! if (strcasecmp (cpu_string, "default") == 0) ! return 0; ! ! for (p = mips_cpu_info_table; p->name != 0; p++) ! if (mips_matching_cpu_name_p (p->name, cpu_string)) ! return p; ! ! as_bad ("Bad value (%s) for %s", cpu_string, option); ! return 0; } + /* Return the canonical processor information for ISA (a member of the + ISA_MIPS* enumeration). */ + static const struct mips_cpu_info * mips_cpu_info_from_isa (isa) int isa; *************** mips_cpu_info_from_isa (isa) *** 13885,13906 **** for (i = 0; mips_cpu_info_table[i].name != NULL; i++) if (mips_cpu_info_table[i].is_isa ! && isa == mips_cpu_info_table[i].isa) return (&mips_cpu_info_table[i]); return NULL; } ! static const struct mips_cpu_info * ! mips_cpu_info_from_cpu (cpu) ! int cpu; { ! int i; for (i = 0; mips_cpu_info_table[i].name != NULL; i++) ! if (!mips_cpu_info_table[i].is_isa ! && cpu == mips_cpu_info_table[i].cpu) ! return (&mips_cpu_info_table[i]); ! return NULL; } --- 13607,13725 ---- for (i = 0; mips_cpu_info_table[i].name != NULL; i++) if (mips_cpu_info_table[i].is_isa ! && isa == mips_cpu_info_table[i].isa) return (&mips_cpu_info_table[i]); return NULL; } + + static void + show (stream, string, col_p, first_p) + FILE *stream; + const char *string; + int *col_p; + int *first_p; + { + if (*first_p) + { + fprintf (stream, "%24s", ""); + *col_p = 24; + } + else + { + fprintf (stream, ", "); + *col_p += 2; + } + + if (*col_p + strlen (string) > 72) + { + fprintf (stream, "\n%24s", ""); + *col_p = 24; + } + + fprintf (stream, "%s", string); + *col_p += strlen (string); + + *first_p = 0; + } ! void ! md_show_usage (stream) ! FILE *stream; { ! int column, first; ! size_t i; ! ! fprintf (stream, _("\ ! MIPS options:\n\ ! -membedded-pic generate embedded position independent code\n\ ! -EB generate big endian output\n\ ! -EL generate little endian output\n\ ! -g, -g2 do not remove unneeded NOPs or swap branches\n\ ! -G NUM allow referencing objects up to NUM bytes\n\ ! implicitly with the gp register [default 8]\n")); ! fprintf (stream, _("\ ! -mips1 generate MIPS ISA I instructions\n\ ! -mips2 generate MIPS ISA II instructions\n\ ! -mips3 generate MIPS ISA III instructions\n\ ! -mips4 generate MIPS ISA IV instructions\n\ ! -mips5 generate MIPS ISA V instructions\n\ ! -mips32 generate MIPS32 ISA instructions\n\ ! -mips64 generate MIPS64 ISA instructions\n\ ! -march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n")); ! ! first = 1; for (i = 0; mips_cpu_info_table[i].name != NULL; i++) ! show (stream, mips_cpu_info_table[i].name, &column, &first); ! show (stream, "from-abi", &column, &first); ! fputc ('\n', stream); ! fprintf (stream, _("\ ! -mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\ ! -no-mCPU don't generate code specific to CPU.\n\ ! For -mCPU and -no-mCPU, CPU must be one of:\n")); ! ! first = 1; ! ! show (stream, "3900", &column, &first); ! show (stream, "4010", &column, &first); ! show (stream, "4100", &column, &first); ! show (stream, "4650", &column, &first); ! fputc ('\n', stream); ! ! fprintf (stream, _("\ ! -mips16 generate mips16 instructions\n\ ! -no-mips16 do not generate mips16 instructions\n")); ! fprintf (stream, _("\ ! -mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\ ! -mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\ ! -O0 remove unneeded NOPs, do not swap branches\n\ ! -O remove unneeded NOPs and swap branches\n\ ! -n warn about NOPs generated from macros\n\ ! --[no-]construct-floats [dis]allow floating point values to be constructed\n\ ! --trap, --no-break trap exception on div by 0 and mult overflow\n\ ! --break, --no-trap break exception on div by 0 and mult overflow\n")); ! #ifdef OBJ_ELF ! fprintf (stream, _("\ ! -KPIC, -call_shared generate SVR4 position independent code\n\ ! -non_shared do not generate position independent code\n\ ! -xgot assume a 32 bit GOT\n\ ! -mabi=ABI create ABI conformant object file for:\n")); ! ! first = 1; ! ! show (stream, "32", &column, &first); ! show (stream, "o64", &column, &first); ! show (stream, "n32", &column, &first); ! show (stream, "64", &column, &first); ! show (stream, "eabi", &column, &first); ! ! fputc ('\n', stream); ! ! fprintf (stream, _("\ ! -32 create o32 ABI object file (default)\n\ ! -n32 create n32 ABI object file\n\ ! -64 create 64 ABI object file\n")); ! #endif } Index: gas/testsuite/gas/mips/mips-gp32-fp64.d =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64.d,v retrieving revision 1.3 diff -c -d -p -r1.3 mips-gp32-fp64.d *** gas/testsuite/gas/mips/mips-gp32-fp64.d 10 Aug 2001 16:28:04 -0000 1.3 --- gas/testsuite/gas/mips/mips-gp32-fp64.d 19 Jul 2002 18:37:30 -0000 *************** *** 1,5 **** #objdump: -d -mmips:8000 ! #as: -march=8000 -EB -mgp32 #name: MIPS -mgp32 -mfp64 .*: +file format.* --- 1,5 ---- #objdump: -d -mmips:8000 ! #as: -march=8000 -EB -mgp32 -mfp64 #name: MIPS -mgp32 -mfp64 .*: +file format.* Index: gas/testsuite/gas/mips/mips-gp32-fp64-pic.d =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64-pic.d,v retrieving revision 1.3 diff -c -d -p -r1.3 mips-gp32-fp64-pic.d *** gas/testsuite/gas/mips/mips-gp32-fp64-pic.d 10 Aug 2001 16:28:04 -0000 1.3 --- gas/testsuite/gas/mips/mips-gp32-fp64-pic.d 19 Jul 2002 18:37:30 -0000 *************** *** 1,5 **** #objdump: -d -mmips:8000 ! #as: -march=8000 -EB -mgp32 -KPIC #name: MIPS -mgp32 -mfp64 (SVR4 PIC) .*: +file format.* --- 1,5 ---- #objdump: -d -mmips:8000 ! #as: -march=8000 -EB -mgp32 -mfp64 -KPIC #name: MIPS -mgp32 -mfp64 (SVR4 PIC) .*: +file format.* --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=mips-config-gcc-3.diff Content-Description: GCC patch Content-length: 57622 Index: doc/invoke.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v retrieving revision 1.158 diff -c -d -p -r1.158 invoke.texi *** doc/invoke.texi 16 Jul 2002 17:46:33 -0000 1.158 --- doc/invoke.texi 19 Jul 2002 18:37:49 -0000 *************** These @samp{-m} options are defined for *** 6959,7023 **** @table @gcctabopt ! @item -march=@var{cpu-type} @opindex march ! Assume the defaults for the machine type @var{cpu-type} when generating ! instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, ! @samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, ! @samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, ! and @samp{orion}. Additionally, the @samp{r2000}, @samp{r3000}, ! @samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as ! @samp{r2k} (or @samp{r2K}), @samp{r3k}, etc. ! @item -mtune=@var{cpu-type} @opindex mtune ! Assume the defaults for the machine type @var{cpu-type} when scheduling ! instructions. The choices for @var{cpu-type} are @samp{r2000}, @samp{r3000}, ! @samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300}, @samp{r4400}, ! @samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000}, @samp{r8000}, ! and @samp{orion}. Additionally, the @samp{r2000}, @samp{r3000}, ! @samp{r4000}, @samp{r5000}, and @samp{r6000} can be abbreviated as ! @samp{r2k} (or @samp{r2K}), @samp{r3k}, etc. While picking a specific ! @var{cpu-type} will schedule things appropriately for that particular ! chip, the compiler will not generate any code that does not meet level 1 ! of the MIPS ISA (instruction set architecture) without a @option{-mipsX} ! or @option{-mabi} switch being used. ! @item -mcpu=@var{cpu-type} ! @opindex mcpu ! This is identical to specifying both @option{-march} and @option{-mtune}. @item -mips1 @opindex mips1 ! Issue instructions from level 1 of the MIPS ISA@. This is the default. ! @samp{r3000} is the default @var{cpu-type} at this ISA level. @item -mips2 @opindex mips2 ! Issue instructions from level 2 of the MIPS ISA (branch likely, square ! root instructions). @samp{r6000} is the default @var{cpu-type} at this ! ISA level. @item -mips3 @opindex mips3 ! Issue instructions from level 3 of the MIPS ISA (64-bit instructions). ! @samp{r4000} is the default @var{cpu-type} at this ISA level. @item -mips4 @opindex mips4 ! Issue instructions from level 4 of the MIPS ISA (conditional move, ! prefetch, enhanced FPU instructions). @samp{r8000} is the default ! @var{cpu-type} at this ISA level. ! @item -mfp32 ! @opindex mfp32 ! Assume that 32 32-bit floating point registers are available. This is ! the default. ! @item -mfp64 ! @opindex mfp64 ! Assume that 32 64-bit floating point registers are available. This is ! the default when the @option{-mips3} option is used. @item -mfused-madd @itemx -mno-fused-madd --- 6959,7035 ---- @table @gcctabopt ! @item -march=@var{arch} @opindex march ! Generate code that will run on @var{arch}, which can be the name of a ! generic MIPS ISA, or the name of a particular processor. The ISA names ! are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, @samp{mips32} ! and @samp{mips64}. The processor names are: @samp{r2000}, ! @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{vr4100}, @samp{vr4300}, ! @samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{vr5000}, @samp{r6000}, ! @samp{r8000}, @samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc} ! and @samp{orion}. The special value @samp{from-abi} selects the ! most compatible architecture for the selected ABI (that is, ! @samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@. ! In processor names, a final @samp{000} can be abbreviated as @samp{k} ! (for example, @samp{-march=r2k}). Prefixes are optional, and ! @samp{vr} may be written @samp{r}. ! ! GCC defines two macros based on the value of this option. The first ! is @samp{_MIPS_ARCH}, which gives the name of target architecture, as ! a string. The second has the form @samp{_MIPS_ARCH_@var{foo}}, ! where @var{foo} is the capitialized value of @samp{_MIPS_ARCH}@. ! For example, @samp{-march=r2000} will set @samp{_MIPS_ARCH} ! to @samp{"r2000"} and define the macro @samp{_MIPS_ARCH_R2000}. ! ! Note that the @samp{_MIPS_ARCH} uses processor names given above. In ! other words, it will have the full prefix, and will not abbreviate ! @samp{000} as @samp{k}. In the case of @samp{from-abi}, the macro ! names the resolved architecture (either @samp{"mips1"} or ! @samp{"mips3"}). It names the default architecture when no ! @option{-march} option is given. ! ! @item -mtune=@var{arch} @opindex mtune ! Optimize for @var{arch}. Among other things, this option controls ! the way instructions are scheduled, and the perceived cost of arithmetic ! operations. The list of @var{arch} values is the same as for ! @option{-march}. ! When this option is not used, GCC will optimize for the processor ! specified by @option{-march}, or (failing that) for the default ! processor. By using @option{-march} and @option{-mtune} together, it is ! possible to generate code that will run on a family of processors, but ! optimize the code for one particular member of that family. ! ! @samp{-mtune} defines the macros @samp{_MIPS_TUNE} and ! @samp{_MIPS_TUNE_@var{foo}}, which work in the same way as the ! @samp{-march} ones described above. @item -mips1 @opindex mips1 ! Equivalent to @samp{-march=mips1}. @item -mips2 @opindex mips2 ! Equivalent to @samp{-march=mips2}. @item -mips3 @opindex mips3 ! Equivalent to @samp{-march=mips3}. @item -mips4 @opindex mips4 ! Equivalent to @samp{-march=mips4}. ! @item -mips32 ! @opindex mips32 ! Equivalent to @samp{-march=mips32}. ! @item -mips64 ! @opindex mips64 ! Equivalent to @samp{-march=mips64}. @item -mfused-madd @itemx -mno-fused-madd *************** in the mode where denormals are rounded *** 7031,7045 **** generated by multiply and accumulate instructions cause exceptions anyway. @item -mgp32 @opindex mgp32 ! Assume that 32 32-bit general purpose registers are available. This is ! the default. @item -mgp64 @opindex mgp64 ! Assume that 32 64-bit general purpose registers are available. This is ! the default when the @option{-mips3} option is used. @item -mint64 @opindex mint64 --- 7043,7063 ---- generated by multiply and accumulate instructions cause exceptions anyway. + @item -mfp32 + @opindex mfp32 + Assume that floating point registers are 32 bits wide. + + @item -mfp64 + @opindex mfp64 + Assume that floating point registers are 64 bits wide. + @item -mgp32 @opindex mgp32 ! Assume that general purpose registers are 32 bits wide. @item -mgp64 @opindex mgp64 ! Assume that general purpose registers are 64 bits wide. @item -mint64 @opindex mint64 *************** explanation of the default, and the widt *** 7055,7085 **** @opindex mlong32 Force long, int, and pointer types to be 32 bits wide. ! If none of @option{-mlong32}, @option{-mlong64}, or @option{-mint64} are set, ! the size of ints, longs, and pointers depends on the ABI and ISA chosen. ! For @option{-mabi=32}, and @option{-mabi=n32}, ints and longs are 32 bits ! wide. For @option{-mabi=64}, ints are 32 bits, and longs are 64 bits wide. ! For @option{-mabi=eabi} and either @option{-mips1} or @option{-mips2}, ints ! and longs are 32 bits wide. For @option{-mabi=eabi} and higher ISAs, ints ! are 32 bits, and longs are 64 bits wide. The width of pointer types is ! the smaller of the width of longs or the width of general purpose ! registers (which in turn depends on the ISA)@. @item -mabi=32 @itemx -mabi=o64 @itemx -mabi=n32 @itemx -mabi=64 @itemx -mabi=eabi @opindex mabi=32 @opindex mabi=o64 @opindex mabi=n32 @opindex mabi=64 @opindex mabi=eabi ! Generate code for the indicated ABI@. The default instruction level is ! @option{-mips1} for @samp{32}, @option{-mips3} for @samp{n32}, and ! @option{-mips4} otherwise. Conversely, with @option{-mips1} or ! @option{-mips2}, the default ABI is @samp{32}; otherwise, the default ABI ! is @samp{64}. @item -mmips-as @opindex mmips-as --- 7073,7104 ---- @opindex mlong32 Force long, int, and pointer types to be 32 bits wide. ! The default size of ints, longs and pointers depends on the ABI@. ! All the supported ABIs use 32-bit ints. n64 uses 64-bit longs, as does ! the 64-bit Cygnus EABI; the others use 32-bit longs. Pointers are ! the same size as longs, or the same size as integer registers, ! whichever is smaller. @item -mabi=32 @itemx -mabi=o64 @itemx -mabi=n32 @itemx -mabi=64 @itemx -mabi=eabi + @itemx -mabi=meabi @opindex mabi=32 @opindex mabi=o64 @opindex mabi=n32 @opindex mabi=64 @opindex mabi=eabi ! @opindex mabi=meabi ! Generate code for the given ABI@. ! ! Note that there are two embedded ABIs: @option{-mabi=eabi} ! selects the one defined by Cygnus while @option{-meabi=meabi} ! selects the one defined by MIPS@. Both these ABIs have ! 32-bit and 64-bit variants. Normally, GCC will generate ! 64-bit code when you select a 64-bit architecture, but you ! can use @option{-mgp32} to get 32-bit code instead. @item -mmips-as @opindex mmips-as Index: toplev.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/toplev.h,v retrieving revision 1.87 diff -c -d -p -r1.87 toplev.h *** toplev.h 5 Jun 2002 19:35:32 -0000 1.87 --- toplev.h 19 Jul 2002 18:37:49 -0000 *************** extern void check_global_declarations *** 108,113 **** --- 108,114 ---- extern const char *progname; extern const char *dump_base_name; + extern int target_flags_explicit; /* The hashtable, so that the C front ends can pass it to cpplib. */ extern struct ht *ident_hash; Index: toplev.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/toplev.c,v retrieving revision 1.658 diff -c -d -p -r1.658 toplev.c *** toplev.c 17 Jul 2002 03:03:40 -0000 1.658 --- toplev.c 19 Jul 2002 18:37:50 -0000 *************** const char *dump_base_name; *** 180,185 **** --- 180,190 ---- extern int target_flags; + /* A mask of target_flags that includes bit X if X was set or cleared + on the command line. */ + + int target_flags_explicit; + /* Debug hooks - dependent upon command line options. */ const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; *************** set_target_switch (name) *** 4409,4414 **** --- 4414,4426 ---- target_flags &= ~-target_switches[j].value; else target_flags |= target_switches[j].value; + if (name[0] != 0) + { + if (target_switches[j].value < 0) + target_flags_explicit |= -target_switches[j].value; + else + target_flags_explicit |= target_switches[j].value; + } valid_target_option = 1; } Index: config/mips/abi64.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/abi64.h,v retrieving revision 1.26 diff -c -d -p -r1.26 abi64.h *** config/mips/abi64.h 16 Apr 2002 03:01:17 -0000 1.26 --- config/mips/abi64.h 19 Jul 2002 18:37:50 -0000 *************** Boston, MA 02111-1307, USA. */ *** 21,31 **** /* Macros to implement the 64 bit ABI. This file is meant to be included after mips.h. */ - #undef SUBTARGET_TARGET_OPTIONS - #define SUBTARGET_TARGET_OPTIONS \ - { "abi=", &mips_abi_string, \ - "Specify ABI to use"}, - #undef STACK_BOUNDARY #define STACK_BOUNDARY \ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \ --- 21,26 ---- Index: config/mips/elf64.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/elf64.h,v retrieving revision 1.43 diff -c -d -p -r1.43 elf64.h *** config/mips/elf64.h 11 Jun 2002 07:26:37 -0000 1.43 --- config/mips/elf64.h 19 Jul 2002 18:37:50 -0000 *************** Boston, MA 02111-1307, USA. */ *** 22,34 **** #define OBJECT_FORMAT_ELF ! /* Default to -mips3. */ #ifndef TARGET_DEFAULT #define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT - #endif - - #ifndef MIPS_ISA_DEFAULT - #define MIPS_ISA_DEFAULT 3 #endif /* This should change to n32 when it is supported in gas. */ --- 22,31 ---- #define OBJECT_FORMAT_ELF ! /* If an embedded ABI is selected, prefer to generate 64-bit code. ! Implies -mips3 in such cases. */ #ifndef TARGET_DEFAULT #define TARGET_DEFAULT MASK_FLOAT64|MASK_64BIT #endif /* This should change to n32 when it is supported in gas. */ Index: config/mips/iris6.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/iris6.h,v retrieving revision 1.50 diff -c -d -p -r1.50 iris6.h *** config/mips/iris6.h 11 Jul 2002 18:56:56 -0000 1.50 --- config/mips/iris6.h 19 Jul 2002 18:37:50 -0000 *************** Boston, MA 02111-1307, USA. */ *** 238,244 **** on the mipsX option. */ /* If no mips[3,4] option given, give the appropriate default for mabi=X */ #undef SUBTARGET_ASM_SPEC ! #define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32:-mips3} %{mabi=64:-mips4}}" /* Must pass -g0 to the assembler, otherwise it may overwrite our debug info with its own debug info. */ --- 238,244 ---- on the mipsX option. */ /* If no mips[3,4] option given, give the appropriate default for mabi=X */ #undef SUBTARGET_ASM_SPEC ! #define SUBTARGET_ASM_SPEC "%{!mabi*:-n32} %{!mips*: %{!mabi*:-mips3} %{mabi=n32|mabi=64:-mips3}}" /* Must pass -g0 to the assembler, otherwise it may overwrite our debug info with its own debug info. */ Index: config/mips/isa3264.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/isa3264.h,v retrieving revision 1.5 diff -c -d -p -r1.5 isa3264.h *** config/mips/isa3264.h 17 Jan 2002 07:53:55 -0000 1.5 --- config/mips/isa3264.h 19 Jul 2002 18:37:50 -0000 *************** Boston, MA 02111-1307, USA. */ *** 27,36 **** #define MIPS_ABI_DEFAULT ABI_MEABI #endif - #ifndef MIPS_ENABLE_EMBEDDED_O32 - #define MIPS_ENABLE_EMBEDDED_O32 1 - #endif - #ifndef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #endif --- 27,32 ---- Index: config/mips/mips.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v retrieving revision 1.200 diff -c -d -p -r1.200 mips.h *** config/mips/mips.h 17 Jul 2002 21:31:39 -0000 1.200 --- config/mips/mips.h 19 Jul 2002 18:37:50 -0000 *************** enum block_move_type { *** 118,123 **** --- 118,140 ---- 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 mips_isa; /* architectural *** 146,159 **** 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 */ --- 163,174 ---- *************** extern GTY(()) rtx mips_load_reg2; /* 2n *** 167,172 **** --- 182,190 ---- 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)); *************** extern void sbss_section PARAMS ((void) *** 342,347 **** --- 360,384 ---- #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 \ *************** extern void sbss_section PARAMS ((void) *** 355,370 **** if (!flag_iso) \ builtin_define ("mips"); \ \ 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"); \ } \ --- 392,407 ---- 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"); \ } \ *************** extern void sbss_section PARAMS ((void) *** 376,381 **** --- 413,422 ---- 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"); \ *************** extern void sbss_section PARAMS ((void) *** 605,612 **** #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN #endif #ifndef MIPS_ISA_DEFAULT ! #define MIPS_ISA_DEFAULT 1 #endif #ifdef IN_LIBGCC2 --- 646,656 ---- #define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN #endif + /* 'from-abi' makes a good default: you get whatever the ABI requires. */ #ifndef MIPS_ISA_DEFAULT ! #ifndef MIPS_CPU_STRING_DEFAULT ! #define MIPS_CPU_STRING_DEFAULT "from-abi" ! #endif #endif #ifdef IN_LIBGCC2 *************** extern void sbss_section PARAMS ((void) *** 656,662 **** #endif #ifndef MULTILIB_DEFAULTS ! #define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT } #endif /* We must pass -EL to the linker by default for little endian embedded --- 700,707 ---- #endif #ifndef MULTILIB_DEFAULTS ! #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 *************** extern void sbss_section PARAMS ((void) *** 675,694 **** #define TARGET_OPTIONS \ { \ SUBTARGET_TARGET_OPTIONS \ - { "cpu=", &mips_cpu_string, \ - N_("Specify CPU for scheduling purposes")}, \ { "tune=", &mips_tune_string, \ N_("Specify CPU for scheduling purposes")}, \ { "arch=", &mips_arch_string, \ N_("Specify CPU for code generation purposes")}, \ { "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, \ --- 720,737 ---- #define TARGET_OPTIONS \ { \ SUBTARGET_TARGET_OPTIONS \ { "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")}, \ { "no-flush-func", &mips_cache_flush_func, \ N_("Don't call any cache flush functions")}, \ { "flush-func=", &mips_cache_flush_func, \ *************** extern void sbss_section PARAMS ((void) *** 716,721 **** --- 759,774 ---- #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 \ *************** while (0) *** 911,917 **** /* 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}}" extern int mips_abi; --- 964,970 ---- /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS assembler. */ ! #define GAS_ASM_SPEC "%{mtune=*} %{v}" extern int mips_abi; *************** extern int mips_abi; *** 920,927 **** #define MIPS_ABI_DEFAULT ABI_32 #endif ! #ifndef ABI_GAS_ASM_SPEC ! #define ABI_GAS_ASM_SPEC "" #endif /* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or --- 973,1015 ---- #define MIPS_ABI_DEFAULT ABI_32 #endif ! /* 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 *************** extern int mips_abi; *** 969,975 **** #define SUBTARGET_ASM_SPEC "" #endif ! /* ASM_SPEC is the set of arguments to pass to the assembler. */ #undef ASM_SPEC #define ASM_SPEC "\ --- 1057,1067 ---- #define SUBTARGET_ASM_SPEC "" #endif ! /* 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 "\ *************** extern int mips_abi; *** 978,984 **** %(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} \ %(target_asm_spec) \ %(subtarget_asm_spec)" --- 1070,1078 ---- %(subtarget_asm_optimizing_spec) \ %(subtarget_asm_debugging_spec) \ %{membedded-pic} \ ! %{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)" *************** extern int mips_abi; *** 1049,1063 **** #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:-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)" --- 1143,1148 ---- *************** extern int mips_abi; *** 1088,1099 **** { "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 }, \ { "endian_spec", ENDIAN_SPEC }, \ SUBTARGET_EXTRA_SPECS --- 1173,1184 ---- { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \ { "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \ { "gas_asm_spec", 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 Index: config/mips/mips.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v retrieving revision 1.217 diff -c -d -p -r1.217 mips.c *** config/mips/mips.c 17 Jul 2002 09:24:08 -0000 1.217 --- config/mips/mips.c 19 Jul 2002 18:37:50 -0000 *************** static int symbolic_expression_p *** 119,125 **** static bool mips_assemble_integer PARAMS ((rtx, unsigned int, int)); static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT)); static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT)); ! static enum processor_type mips_parse_cpu PARAMS ((const char *)); static void copy_file_data PARAMS ((FILE *, FILE *)); #ifdef TARGET_IRIX6 static void iris6_asm_named_section_1 PARAMS ((const char *, --- 119,133 ---- static bool mips_assemble_integer PARAMS ((rtx, unsigned int, int)); static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT)); static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT)); ! static void mips_set_architecture PARAMS ((const struct mips_cpu_info *)); ! static void mips_set_tune PARAMS ((const struct mips_cpu_info *)); ! static bool mips_strict_matching_cpu_name_p PARAMS ((const char *, ! const char *)); ! static bool mips_matching_cpu_name_p PARAMS ((const char *, ! const char *)); ! static const struct mips_cpu_info *mips_parse_cpu PARAMS ((const char *, ! const char *)); ! static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int)); static void copy_file_data PARAMS ((FILE *, FILE *)); #ifdef TARGET_IRIX6 static void iris6_asm_named_section_1 PARAMS ((const char *, *************** enum cmp_type branch_type; *** 294,302 **** --- 302,312 ---- /* The target cpu for code generation. */ enum processor_type mips_arch; + const struct mips_cpu_info *mips_arch_info; /* The target cpu for optimization and scheduling. */ enum processor_type mips_tune; + const struct mips_cpu_info *mips_tune_info; /* which instruction set architecture to use. */ int mips_isa; *************** int mips_isa; *** 305,311 **** int mips_abi; /* Strings to hold which cpu and instruction set architecture to use. */ - const char *mips_cpu_string; /* for -mcpu= */ const char *mips_arch_string; /* for -march= */ const char *mips_tune_string; /* for -mtune= */ const char *mips_isa_string; /* for -mips{1,2,3,4} */ --- 315,320 ---- *************** int mips16; *** 320,330 **** just a way to avoid using up another bit in target_flags. */ const char *mips_no_mips16_string; - /* This is only used to determine if an type size setting option was - explicitly specified (-mlong64, -mint64, -mlong32). The specs - set this option if such an option is used. */ - const char *mips_explicit_type_size_string; - /* Whether we are generating mips16 hard float code. In mips16 mode we always set TARGET_SOFT_FLOAT; this variable is nonzero if -msoft-float was not specified by the user, which means that we --- 329,334 ---- *************** enum reg_class mips_char_to_class[256] = *** 562,567 **** --- 566,619 ---- NO_REGS, NO_REGS, NO_REGS, NO_REGS, }; + /* A table describing all the processors gcc knows about. Names are + matched in the order listed. The first mention of an ISA level is + taken as the canonical name for that ISA. + + To ease comparison, please keep this table in the same order as + gas's mips_cpu_info_table[]. */ + const struct mips_cpu_info mips_cpu_info_table[] = { + /* Entries for generic ISAs */ + { "mips1", PROCESSOR_R3000, 1 }, + { "mips2", PROCESSOR_R6000, 2 }, + { "mips3", PROCESSOR_R4000, 3 }, + { "mips4", PROCESSOR_R8000, 4 }, + { "mips32", PROCESSOR_R4KC, 32 }, + { "mips64", PROCESSOR_R5KC, 64 }, + + /* MIPS I */ + { "r3000", PROCESSOR_R3000, 1 }, + { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */ + { "r3900", PROCESSOR_R3900, 1 }, + + /* MIPS II */ + { "r6000", PROCESSOR_R6000, 2 }, + + /* MIPS III */ + { "r4000", PROCESSOR_R4000, 3 }, + { "vr4100", PROCESSOR_R4100, 3 }, + { "vr4300", PROCESSOR_R4300, 3 }, + { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */ + { "r4600", PROCESSOR_R4600, 3 }, + { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */ + { "r4650", PROCESSOR_R4650, 3 }, + + /* MIPS IV */ + { "r8000", PROCESSOR_R8000, 4 }, + { "vr5000", PROCESSOR_R5000, 4 }, + + /* MIPS 32 */ + { "4kc", PROCESSOR_R4KC, 32 }, + { "4kp", PROCESSOR_R4KC, 32 }, /* = 4kc */ + + /* MIPS 64 */ + { "5kc", PROCESSOR_R5KC, 64 }, + { "20kc", PROCESSOR_R20KC, 64 }, + + /* End marker */ + { 0, 0, 0 } + }; + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" *************** abort_with_insn (insn, reason) *** 4931,4946 **** abort (); } /* Set up the threshold for data to go into the small data area, instead of the normal data area, and detect any conflicts in the switches. */ void override_options () { ! register int i, start; ! register int regno; ! register enum machine_mode mode; ! register enum processor_type mips_cpu; mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE; --- 4983,5026 ---- abort (); } + /* Set up globals to generate code for the ISA or processor + described by INFO. */ + + static void + mips_set_architecture (info) + const struct mips_cpu_info *info; + { + if (info != 0) + { + mips_arch_info = info; + mips_arch = info->cpu; + mips_isa = info->isa; + } + } + + + /* Likewise for tuning. */ + + static void + mips_set_tune (info) + const struct mips_cpu_info *info; + { + if (info != 0) + { + mips_tune_info = info; + mips_tune = info->cpu; + } + } + + /* Set up the threshold for data to go into the small data area, instead of the normal data area, and detect any conflicts in the switches. */ void override_options () { ! int i, start, regno; ! enum machine_mode mode; mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE; *************** override_options () *** 4958,5207 **** target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT)); #endif ! /* Get the architectural level. */ ! if (mips_isa_string == 0) ! mips_isa = MIPS_ISA_DEFAULT; ! else if (mips_isa_string != 0 ! && mips_arch_string != 0) ! warning ("The -march option is incompatible to -mipsN and therefore ignored."); ! else if (ISDIGIT (*mips_isa_string)) { ! mips_isa = atoi (mips_isa_string); ! if (mips_isa == 16) { ! /* -mno-mips16 overrides -mips16. */ if (mips_no_mips16_string == NULL) ! { ! target_flags |= MASK_MIPS16; ! if (TARGET_64BIT) ! mips_isa = 3; ! else ! mips_isa = MIPS_ISA_DEFAULT; ! } ! else ! { ! mips_isa = MIPS_ISA_DEFAULT; ! } } ! else if (mips_isa < 1 ! || (mips_isa > 4 ! && mips_isa != 32 ! && mips_isa != 64)) { ! error ("-mips%d not supported", mips_isa); ! mips_isa = 1; } - } - - else - { - error ("bad value (%s) for -mips switch", mips_isa_string); - mips_isa = 1; - } - - #ifdef MIPS_ABI_DEFAULT - /* Get the ABI to use. */ - if (mips_abi_string == (char *) 0) - mips_abi = MIPS_ABI_DEFAULT; - else if (! strcmp (mips_abi_string, "32")) - mips_abi = ABI_32; - else if (! strcmp (mips_abi_string, "o64")) - mips_abi = ABI_O64; - else if (! strcmp (mips_abi_string, "n32")) - mips_abi = ABI_N32; - else if (! strcmp (mips_abi_string, "64")) - mips_abi = ABI_64; - else if (! strcmp (mips_abi_string, "eabi")) - mips_abi = ABI_EABI; - else if (! strcmp (mips_abi_string, "meabi")) - mips_abi = ABI_MEABI; - else - error ("bad value (%s) for -mabi= switch", mips_abi_string); - - /* A specified ISA defaults the ABI if it was not specified. */ - if (mips_abi_string == 0 && mips_isa_string - && mips_abi != ABI_EABI - && mips_abi != ABI_O64 - && mips_abi != ABI_MEABI) - { - if (mips_isa == 64) - mips_abi = ABI_O64; else { ! if (! ISA_HAS_64BIT_REGS) ! mips_abi = ABI_32; ! else if (mips_abi != ABI_N32) ! mips_abi = ABI_64; } } ! #ifdef MIPS_CPU_STRING_DEFAULT ! /* A specified ABI defaults the ISA if it was not specified. */ ! else if (mips_isa_string == 0 && mips_abi_string ! && mips_abi != ABI_EABI && mips_abi != ABI_O64) ! { ! if (mips_abi == ABI_32) ! mips_isa = 1; ! else if (mips_abi == ABI_N32) ! mips_isa = 3; ! else ! mips_isa = 4; ! } ! #endif ! ! /* If both ABI and ISA were specified, check for conflicts. */ ! else if (mips_isa_string && mips_abi_string) { ! if (! ISA_HAS_64BIT_REGS && (mips_abi == ABI_N32 || mips_abi == ABI_64 ! || mips_abi == ABI_O64)) ! error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa); ! } ! ! /* Override TARGET_DEFAULT if necessary. */ ! if (mips_abi == ABI_32) ! target_flags &= ~ (MASK_FLOAT64|MASK_64BIT); ! ! /* If no type size setting options (-mlong64,-mint64,-mlong32) were used ! then set the type sizes. In the EABI in 64 bit mode, longs and ! pointers are 64 bits. Likewise for the SGI Irix6 N64 ABI. */ ! if (mips_explicit_type_size_string == NULL ! && ((mips_abi == ABI_EABI && TARGET_64BIT) ! || mips_abi == ABI_64)) ! target_flags |= MASK_LONG64; ! ! #else ! if (mips_abi_string) ! error ("this target does not support the -mabi switch"); ! #endif ! #ifdef MIPS_CPU_STRING_DEFAULT ! /* ??? There is a minor inconsistency here. If the user specifies an ISA ! greater than that supported by the default processor, then the user gets ! an error. Normally, the compiler will just default to the base level cpu ! for the indicated isa. */ ! if (mips_arch_string == 0) ! mips_arch_string = MIPS_CPU_STRING_DEFAULT; ! if (mips_tune_string == 0) ! mips_tune_string = MIPS_CPU_STRING_DEFAULT; #endif ! /* Identify the processor type. */ ! if (mips_cpu_string != 0) ! { ! mips_cpu = mips_parse_cpu (mips_cpu_string); ! if (mips_cpu == PROCESSOR_DEFAULT) ! { ! error ("bad value (%s) for -mcpu= switch", mips_cpu_string); ! mips_cpu_string = "default"; ! } ! mips_arch = mips_cpu; ! mips_tune = mips_cpu; ! } ! if (mips_arch_string == 0 ! || ! strcmp (mips_arch_string, "default") ! || ! strcmp (mips_arch_string, "DEFAULT")) { ! switch (mips_isa) ! { ! default: ! mips_arch_string = "3000"; ! mips_arch = PROCESSOR_R3000; ! break; ! case 2: ! mips_arch_string = "6000"; ! mips_arch = PROCESSOR_R6000; ! break; ! case 3: ! mips_arch_string = "4000"; ! mips_arch = PROCESSOR_R4000; ! break; ! case 4: ! mips_arch_string = "8000"; ! mips_arch = PROCESSOR_R8000; ! break; ! case 32: ! mips_arch_string = "4kc"; ! mips_arch = PROCESSOR_R4KC; ! break; ! case 64: ! mips_arch_string = "5kc"; ! mips_arch = PROCESSOR_R5KC; ! break; ! } } else { ! mips_arch = mips_parse_cpu (mips_arch_string); ! if (mips_arch == PROCESSOR_DEFAULT) ! { ! error ("bad value (%s) for -march= switch", mips_arch_string); ! mips_arch_string = "default"; ! } ! } ! if (mips_tune_string == 0 ! || ! strcmp (mips_tune_string, "default") ! || ! strcmp (mips_tune_string, "DEFAULT")) ! { ! if (mips_arch != PROCESSOR_DEFAULT) ! mips_tune = mips_arch; else ! switch (mips_isa) ! { ! default: ! mips_tune_string = "3000"; ! mips_tune = PROCESSOR_R3000; ! break; ! case 2: ! mips_tune_string = "6000"; ! mips_tune = PROCESSOR_R6000; ! break; ! case 3: ! mips_tune_string = "4000"; ! mips_tune = PROCESSOR_R4000; ! break; ! case 4: ! mips_tune_string = "8000"; ! mips_tune = PROCESSOR_R8000; ! break; ! case 32: ! mips_tune_string = "4kc"; ! mips_tune = PROCESSOR_R4KC; ! break; ! case 64: ! mips_tune_string = "5kc"; ! mips_tune = PROCESSOR_R5KC; ! break; ! } } else { ! mips_tune = mips_parse_cpu (mips_tune_string); ! if (mips_tune == PROCESSOR_DEFAULT) ! { ! error ("bad value (%s) for -mtune= switch", mips_tune_string); ! mips_tune_string = "default"; ! } } ! /* make sure sizes of ints/longs/etc. are ok */ ! if (! ISA_HAS_64BIT_REGS) ! { ! if (TARGET_FLOAT64) ! { ! error ("-mips%d does not support 64 bit fp registers", mips_isa); ! target_flags &= ~ MASK_FLOAT64; ! } ! else if (TARGET_64BIT) ! { ! error ("-mips%d does not support 64 bit gp registers", mips_isa); ! target_flags &= ~MASK_64BIT; ! } } if (mips_abi != ABI_32 && mips_abi != ABI_O64) --- 5038,5175 ---- target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT)); #endif ! /* Interpret -mabi. */ ! mips_abi = MIPS_ABI_DEFAULT; ! if (mips_abi_string != 0) ! { ! if (strcmp (mips_abi_string, "32") == 0) ! mips_abi = ABI_32; ! else if (strcmp (mips_abi_string, "o64") == 0) ! mips_abi = ABI_O64; ! else if (strcmp (mips_abi_string, "n32") == 0) ! mips_abi = ABI_N32; ! else if (strcmp (mips_abi_string, "64") == 0) ! mips_abi = ABI_64; ! else if (strcmp (mips_abi_string, "eabi") == 0) ! mips_abi = ABI_EABI; ! else if (strcmp (mips_abi_string, "meabi") == 0) ! mips_abi = ABI_MEABI; ! else ! fatal_error ("bad value (%s) for -mabi= switch", mips_abi_string); ! } ! /* The following code determines the architecture and register size. ! Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()). ! The GAS and GCC code should be kept in sync as much as possible. */ ! if (mips_arch_string != 0) ! mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string)); ! ! if (mips_tune_string != 0) ! mips_set_tune (mips_parse_cpu ("-mtune", mips_tune_string)); ! ! if (mips_isa_string != 0) { ! /* Handle -mipsN. */ ! int level = atoi (mips_isa_string); ! if (level == 16) { ! /* -mips16 specifies an ASE rather than a processor, so don't ! change mips_arch here. -mno-mips16 overrides -mips16. */ if (mips_no_mips16_string == NULL) ! target_flags |= MASK_MIPS16; } ! else if (mips_arch_info != 0) { ! /* -march takes precedence over -mipsN, since it is more descriptive. ! There's no harm in specifying both as long as the ISA levels ! are the same. */ ! if (mips_isa != level) ! error ("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor", ! level, mips_isa); } else { ! mips_set_architecture (mips_cpu_info_from_isa (level)); ! if (mips_arch_info == 0) ! error ("bad value (%s) for -mips switch", mips_isa_string); } } ! if (mips_arch_info == 0) { ! /* Provisionally select the default processor or ISA level. */ #ifdef MIPS_CPU_STRING_DEFAULT ! mips_set_architecture (mips_parse_cpu ("default CPU", ! MIPS_CPU_STRING_DEFAULT)); ! #else ! mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT)); #endif + } ! if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS) ! error ("-march=%s is not compatible with the selected ABI", ! mips_arch_info->name); ! /* Optimize for mips_arch, unless -mtune selects a different processor. */ ! if (mips_tune_info == 0) ! mips_set_tune (mips_arch_info); ! if ((target_flags_explicit & MASK_64BIT) != 0) { ! /* The user specified the size of the integer registers. Make sure ! it agrees with the ABI and ISA. */ ! if (TARGET_64BIT && !ISA_HAS_64BIT_REGS) ! error ("-mgp64 used with a 32-bit processor"); ! else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS) ! error ("-mgp32 used with a 64-bit ABI"); ! else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS) ! error ("-mgp64 used with a 32-bit ABI"); } else { ! /* Infer the integer register size from the ABI and processor. ! Restrict ourselves to 32-bit registers if that's all the ! processor has, or if the ABI cannot handle 64-bit registers. */ ! if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS) ! target_flags &= ~MASK_64BIT; else ! target_flags |= MASK_64BIT; ! } + if ((target_flags_explicit & MASK_FLOAT64) != 0) + { + /* Really, -mfp32 and -mfp64 are ornamental options. There's + only one right answer here. */ + if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64) + error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float"); + else if (!TARGET_64BIT && TARGET_FLOAT64) + error ("unsupported combination: %s", "-mgp32 -mfp64"); + else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) + error ("unsupported combination: %s", "-mfp64 -msingle-float"); } else { ! /* -msingle-float selects 32-bit float registers. Otherwise the ! float registers should be the same size as the integer ones. */ ! if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) ! target_flags |= MASK_FLOAT64; ! else ! target_flags &= ~MASK_FLOAT64; } ! /* End of code shared with GAS. */ ! if ((target_flags_explicit & MASK_LONG64) == 0) ! { ! /* If no type size setting options (-mlong64,-mint64,-mlong32) ! were used, then set the type sizes. In the EABI in 64 bit mode, ! longs and pointers are 64 bits. Likewise for the SGI Irix6 N64 ! ABI. */ ! if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64) ! target_flags |= MASK_LONG64; ! else ! target_flags &= ~MASK_LONG64; } if (mips_abi != ABI_32 && mips_abi != ABI_O64) *************** mips_asm_file_start (stream) *** 6361,6367 **** if (flag_verbose_asm) fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n", ASM_COMMENT_START, ! mips_section_threshold, mips_arch_string, mips_isa); } /* If we are optimizing the global pointer, emit the text section now and any --- 6329,6335 ---- if (flag_verbose_asm) fprintf (stream, "\n%s -G value = %d, Arch = %s, ISA = %d\n", ASM_COMMENT_START, ! mips_section_threshold, mips_arch_info->name, mips_isa); } /* If we are optimizing the global pointer, emit the text section now and any *************** mips_output_conditional_branch (insn, *** 10166,10280 **** /* NOTREACHED */ return 0; } ! static enum processor_type ! mips_parse_cpu (cpu_string) ! const char *cpu_string; { ! const char *p = cpu_string; ! int seen_v = 0; ! enum processor_type cpu; ! int warn_upper_case = 0; ! /* We need to cope with the various "vr" prefixes for the NEC 4300 ! and 4100 processors. */ ! if (*p == 'v' || *p == 'V') ! { ! if (*p == 'V') ! warn_upper_case = 1; ! seen_v = 1, p++; ! } - if (*p == 'r' || *p == 'R') - { - if (*p == 'R') - warn_upper_case = 1; - p++; - } ! if (warn_upper_case) ! warning ("the cpu name must be lower case"); ! /* Since there is no difference between a R2000 and R3000 in ! terms of the scheduler, we collapse them into just an R3000. */ ! cpu = PROCESSOR_DEFAULT; ! switch (*p) ! { ! case '2': ! if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K")) ! cpu = PROCESSOR_R3000; ! else if (!strcmp (p, "20kc") || !strcmp (p, "20Kc") ) ! cpu = PROCESSOR_R20KC; ! break; ! case '3': ! if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K")) ! cpu = PROCESSOR_R3000; ! else if (!strcmp (p, "3900")) ! cpu = PROCESSOR_R3900; ! break; ! case '4': ! if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K")) ! cpu = PROCESSOR_R4000; ! /* The vr4100 is a non-FP ISA III processor with some extra ! instructions. */ ! else if (!strcmp (p, "4100")) ! cpu = PROCESSOR_R4100; ! /* The vr4300 is a standard ISA III processor, but with a different ! pipeline. */ ! else if (!strcmp (p, "4300")) ! cpu = PROCESSOR_R4300; ! /* The r4400 is exactly the same as the r4000 from the compiler's ! viewpoint. */ ! else if (!strcmp (p, "4400")) ! cpu = PROCESSOR_R4000; ! else if (!strcmp (p, "4600")) ! cpu = PROCESSOR_R4600; ! else if (!strcmp (p, "4650")) ! cpu = PROCESSOR_R4650; ! /* The 4kc and 4kp processor cores are the same for ! scheduling purposes; they both implement the MIPS32 ! ISA and only differ in their memory management ! methods. */ ! else if (!strcmp (p, "4kc") || !strcmp (p, "4Kc") ! || !strcmp (p, "4kp") || !strcmp (p, "4Kp") ) ! cpu = PROCESSOR_R4KC; ! break; ! case '5': ! if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K")) ! cpu = PROCESSOR_R5000; ! else if (!strcmp (p, "5kc") || !strcmp (p, "5Kc") ) ! cpu = PROCESSOR_R5KC; ! break; - case '6': - if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K")) - cpu = PROCESSOR_R6000; - break; ! case '8': ! if (!strcmp (p, "8000")) ! cpu = PROCESSOR_R8000; ! break; ! case 'o': ! if (!strcmp (p, "orion")) ! cpu = PROCESSOR_R4600; ! break; ! } ! if (seen_v ! && cpu != PROCESSOR_R4300 ! && cpu != PROCESSOR_R4100 ! && cpu != PROCESSOR_R5000) ! cpu = PROCESSOR_DEFAULT; ! return cpu; } /* Adjust the cost of INSN based on the relationship between INSN that is dependent on DEP_INSN through the dependence LINK. The default is to make no adjustment to COST. --- 10134,10253 ---- /* NOTREACHED */ return 0; } + + /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL + with a final "000" replaced by "k". Ignore case. ! Note: this function is shared between GCC and GAS. */ ! ! static bool ! mips_strict_matching_cpu_name_p (canonical, given) ! const char *canonical, *given; { ! while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical)) ! given++, canonical++; ! return ((*given == 0 && *canonical == 0) ! || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0)); ! } ! /* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied ! CPU name. We've traditionally allowed a lot of variation here. ! Note: this function is shared between GCC and GAS. */ ! static bool ! mips_matching_cpu_name_p (canonical, given) ! const char *canonical, *given; ! { ! /* First see if the name matches exactly, or with a final "000" ! turned into "k". */ ! if (mips_strict_matching_cpu_name_p (canonical, given)) ! return true; ! /* If not, try comparing based on numerical designation alone. ! See if GIVEN is an unadorned number, or 'r' followed by a number. */ ! if (TOLOWER (*given) == 'r') ! given++; ! if (!ISDIGIT (*given)) ! return false; ! /* Skip over some well-known prefixes in the canonical name, ! hoping to find a number there too. */ ! if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r') ! canonical += 2; ! else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm') ! canonical += 2; ! else if (TOLOWER (canonical[0]) == 'r') ! canonical += 1; ! return mips_strict_matching_cpu_name_p (canonical, given); ! } ! /* Parse an option that takes the name of a processor as its argument. ! OPTION is the name of the option and CPU_STRING is the argument. ! Return the corresponding processor enumeration if the CPU_STRING is ! recognized, otherwise report an error and return null. ! A similar function exists in GAS. */ ! static const struct mips_cpu_info * ! mips_parse_cpu (option, cpu_string) ! const char *option, *cpu_string; ! { ! const struct mips_cpu_info *p; ! const char *s; ! /* In the past, we allowed upper-case CPU names, but it doesn't ! work well with the multilib machinery. */ ! for (s = cpu_string; *s != 0; s++) ! if (ISUPPER (*s)) ! { ! warning ("the cpu name must be lower case"); ! break; ! } ! ! /* 'from-abi' selects the most compatible architecture for the given ! ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs. For the ! EABIs, we have to decide whether we're using the 32-bit or 64-bit ! version. Look first at the -mgp options, if given, otherwise base ! the choice on MASK_64BIT in TARGET_DEFAULT. */ ! if (strcasecmp (cpu_string, "from-abi") == 0) ! return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1 ! : ABI_NEEDS_64BIT_REGS ? 3 ! : (TARGET_64BIT ? 3 : 1)); ! ! /* 'default' has traditionally been a no-op. Probably not very useful. */ ! if (strcasecmp (cpu_string, "default") == 0) ! return 0; ! ! for (p = mips_cpu_info_table; p->name != 0; p++) ! if (mips_matching_cpu_name_p (p->name, cpu_string)) ! return p; ! ! error ("bad value (%s) for %s", cpu_string, option); ! return 0; } + + /* Return the processor associated with the given ISA level, or null + if the ISA isn't valid. */ + + static const struct mips_cpu_info * + mips_cpu_info_from_isa (isa) + int isa; + { + const struct mips_cpu_info *p; + + for (p = mips_cpu_info_table; p->name != 0; p++) + if (p->isa == isa) + return p; + + return 0; + } + /* Adjust the cost of INSN based on the relationship between INSN that is dependent on DEP_INSN through the dependence LINK. The default is to make no adjustment to COST. *** /dev/null Tue Nov 14 21:44:43 2000 --- testsuite/gcc.dg/mips-args-1.c Fri Jul 19 18:24:45 2002 *************** *** 0 **** --- 1,35 ---- + /* Check that certain preprocessor macros are defined, and do some + consistency checks. */ + /* { dg-do compile { target mips*-*-* } } */ + + const char *compiled_for = _MIPS_ARCH; + const char *optimized_for = _MIPS_TUNE; + + #if __mips_fpr != 32 && __mips_fpr != 64 + #error Bad __mips_fpr + #endif + + /* Test complementary macro pairs: exactly one of each pair + must be defined. */ + + #if defined (_R3000) == defined (_R4000) + #error _R3000 / _R4000 mismatch + #endif + + #if defined (__mips_hard_float) == defined (__mips_soft_float) + #error __mips_hard_float / __mips_soft_float mismatch + #endif + + #if defined (_MIPSEL) == defined (_MIPSEB) + #error _MIPSEL / _MIPSEB mismatch + #endif + + /* Check for __mips64 consistency. */ + + #if defined (__mips64) != defined (_R4000) + #error __mips64 / _R4000 mismatch + #endif + + #if defined (__mips64) && __mips != 3 && __mips != 4 && __mips != 64 + #error __mips64 / __mips mismatch + #endif *** /dev/null Tue Nov 14 21:44:43 2000 --- testsuite/gcc.dg/mips-args-2.c Thu Jul 18 14:24:43 2002 *************** *** 0 **** --- 1,15 ---- + /* Check the _MIPSEB and _MIPSEL macros are accurate. */ + /* { dg-do run { target mips*-*-* } } */ + short foo = 1; + int main () + { + char *p = (char *) &foo; + + #ifdef _MIPSEB + if (p[0] != 0 || p[1] != 1) + #else + if (p[0] != 1 || p[1] != 0) + #endif + abort (); + exit (0); + } *** /dev/null Tue Nov 14 21:44:43 2000 --- testsuite/gcc.dg/mips-args-3.c Thu Jul 18 14:31:42 2002 *************** *** 0 **** --- 1,35 ---- + /* __mips, and related defines, guarantee that certain assembly + instructions can be used. Check a few examples. */ + /* { dg-do run { target mips*-*-* } } */ + typedef int int32 __attribute__ ((mode (SI))); + typedef int int64 __attribute__ ((mode (DI))); + int foo (float inf, int64 in64, int32 in32) + { + int64 res64; + int32 res32; + + #if __mips != 1 && defined (__mips_hard_float) + __asm__ ("trunc.w.s %0, %1" : "=f" (res32) : "f" (inf)); + if (res32 != 11) + abort (); + #endif + + #if defined (__mips64) + __asm__ ("daddu %0, %1, %1" : "=r" (res64) : "r" (in64)); + if (res64 != 50) + abort (); + #endif + + #if (__mips == 4 || __mips == 32 || __mips == 64) && !defined (__mips16) + __asm__ ("move %0,%.\n\tmovn %0,%1,%2" + : "=&r" (res32) : "r" (in32), "r" (in64 != 0)); + if (res32 != 60) + abort (); + #endif + } + + int main () + { + foo (11.4f, 25, 60); + exit (0); + } --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=mips-config-gcc-doc.diff Content-Description: Patch to changes.html Content-length: 1677 Index: htdocs/gcc-3.3/changes.html =================================================================== RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.3/changes.html,v retrieving revision 1.1 diff -c -d -p -r1.1 changes.html *** htdocs/gcc-3.3/changes.html 17 Jul 2002 15:37:12 -0000 1.1 --- htdocs/gcc-3.3/changes.html 22 Jul 2002 09:54:56 -0000 *************** *** 148,153 **** --- 148,174 ----
  • SH5, SHmedia, little-endian, 64-bit default, sh64le-*-netbsd*
  • +
  • The following changes have been made to the MIPS port: +
      +
    • All configurations now accept the -mabi + switch. Note that you will need appropriate multilibs + for this option to work properly.
    • +
    • ELF configurations will always pass an ABI flag to + the assembler.
    • +
    • -mabi=64 no longer selects MIPS IV code.
    • +
    • The -mcpu option, which was deprecated + in 3.1 and 3.2, has been removed from this release.
    • +
    • -march now changes the core ISA level. + In previous releases, it would change the use of + processor-specific extensions, but would leave the core + ISA unchanged. For example, mips64-elf + -march=r8000 will now generate MIPS IV code.
    • +
    • Under most configurations, -mipsN now acts as a + synonym for -march.
    • +
    • There are some new preprocessor macros to describe the + -march and -mtune settings. + See the documentation of those options for details.
    • +
  • --=-=-=--