This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Revised patch] Rework MIPS command-line handling


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.

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.*
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=<xxx> */
  extern const char *mips_arch_string;    /* for -march=<xxx> */
  extern const char *mips_tune_string;    /* for -mtune=<xxx> */
  extern const char *mips_isa_string;	/* for -mips{1,2,3,4} */
  extern const char *mips_abi_string;	/* for -mabi={32,n32,64} */
  extern const char *mips_entry_string;	/* for -mentry */
  extern const char *mips_no_mips16_string;/* for -mno-mips16 */
- extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
  extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
  extern int mips_split_addresses;	/* perform high/lo_sum support */
  extern int dslots_load_total;		/* total # load related delay slots */
--- 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=<xxx> */
  const char *mips_arch_string;   /* for -march=<xxx> */
  const char *mips_tune_string;   /* for -mtune=<xxx> */
  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);
+ }
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 ----
  	  <li>SH5, SHmedia, little-endian, 64-bit default,
  	      <code>sh64le-*-netbsd*</code></li>
  	</ul></li>
+     <li>The following changes have been made to the MIPS port:
+ 	<ul>
+ 	  <li>All configurations now accept the <code>-mabi</code>
+ 	      switch.  Note that you will need appropriate multilibs
+ 	      for this option to work properly.</li>
+ 	  <li>ELF configurations will always pass an ABI flag to
+ 	      the assembler.</li>
+ 	  <li><code>-mabi=64</code> no longer selects MIPS IV code.</li>
+ 	  <li>The <code>-mcpu</code> option, which was deprecated
+ 	      in 3.1 and 3.2, has been removed from this release.</li>
+ 	  <li><code>-march</code> 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, <code>mips64-elf
+ 	      -march=r8000</code> will now generate MIPS IV code.</li>
+ 	  <li>Under most configurations, <code>-mipsN</code> now acts as a
+ 	      synonym for <code>-march</code>.</li>
+ 	  <li>There are some new preprocessor macros to describe the
+ 	      <code>-march</code> and <code>-mtune</code> settings.
+ 	      See the documentation of those options for details.</li>
+ 	</ul></li>
    </ul>
  
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]