public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC & patch: Rework MIPS command-line handling
@ 2002-07-12 10:16 Richard Sandiford
  2002-07-12 11:39 ` Maciej W. Rozycki
                   ` (4 more replies)
  0 siblings, 5 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-12 10:16 UTC (permalink / raw)
  To: gcc-patches, binutils

[-- Attachment #1: Type: text/plain, Size: 11667 bytes --]

[cross-posted to binutils & gcc]

The patch below tries to make MIPS GCC and GAS more consistent in
the way they handle command-line options.  This message is really a
RFC on whether it's the right way to go, although the patch has
been tested in the usual way.

I'll use numbers to break things up...

(1) The main discrepancy I see with the current set-up is in the handling
    of -march.  In GAS, it fully controls the ISA, much like -mipsN does,
    but in GCC it only controls the use of processor-specific extensions.
    So, for example,

	mips-elf-as -march=r8000

    selects MIPS IV code but

	mips-elf-gcc -march=r8000

    selects MIPS I code.  I'd like to make it so that both cc1 and gas treat
    -march like a more descriptive version of -mipsN.  -march=r8000 would
    be equivalent to -mips4, -march=r4000 would be equivalent to -mips3,
    and so on.

(2) Traditionally, GCC has tried to infer sensible things from a sparse
    command line.  Passing -mipsN would select a suitable ABI for ISA N,
    passing -mabi=FOO would select a suitable ISA for ABI FOO, and so on.
    Lately, gas has done the same thing, although the assumptions are
    slightly different (more later).

    If -march is going to act like -mipsN, then it ought to choose the
    ABI as well.  For example, if "mips64-elf-gcc -mips1" chooses o32 code
    (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.

(3) The GCC code to infer an ABI from an ISA looks like this:

	/* 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
		  mips_abi = ABI_64;
	      }
	  }

    Some problems here:

    (a) The o64 exclusion seems strange.  Passing -mips1 or -mips2 to
	an o64-configured GCC will generate "32-bit o64" code (we get
	the 32-bit register size from CC1_SPEC).  It turns out to be
	almost the same as O32 code, except you get an .mdebug.abiO64
	section instead of an .mdebug.abi32 section.

    (b) Passing -mips3 to an n32 MIPS III config (e.g. mips-sgi-irix6)
	will select n64, which seems counter-intuitive.

    (c) The code takes no account of the -mgp32 option.  "-mips4 -mgp32"
	will set the ABI to n64 without complaint, but generate odd code.
	o32 would be a more sensible choice, especially in cases where
	o32 is the default anyway.

    (d) GAS 2.12 selects o64 (not n64) for -mips3 and -mips4.

    The proposed new rule is:

    (i) If the default ABI requires 32-bit registers [o32 only] then
	switch to o64 when generating 64-bit code.

    (ii) If the default ABI requires 64-bit registers [o64, n32 and 64]
	 then switch to o32 when generating 32-bit code.

    Here, "generating X-bit code" takes into account the ISA and
    -mgp32 option.

    For (i), o64 seems a better choice than n64.  Historical precedent
    might be one reason to keep n64, but GAS prior to 2.12 didn't support
    it and (like (d) says) gas 2.12 would assume you meant o64 instead
    of n64.  So I can't see the n64 choice would ever have worked
    well when using GAS.

    Choosing o64 shouldn't hurt mips-sgi-irix6.  Since its default ABI
    is n32, (i) would mean you still get n32 code after passing -mips3
    or -mips4.  You can switch to n64 using -mabi=64 in the usual way.

(4) The code to infer an ISA from an ABI is:

	/* 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;
	  }

    Problems here:

    (a) It seems counter-intuitive for -mabi to override the default
        architecture even when that default was compatible.  For
        example, "mipsisa32-elf-gcc -mabi=o32" would generate
	MIPS I code rather than MIPS 32 code.

    (b) MIPS III and MIPS IV processors can run o32 too, and you can
	sometimes get the benefit of extra instructions	(like
	conditional moves, and sometimes multiply-add).  It seems
	more appropriate to generate 32-bit code for the default
	architecture when passed -mabi=o32, rather than blindly
	switching to MIPS I.

    (b) There seems no good reason why we should choose MIPS IV over
	MIPS III for n64.  People have complained: see PR #5938.

    Proposed rule in this case:

    (i) If the default architecture is 64-bit, -mabi=32 selects
	32-bit registers, but keeps the current architecture.

    (ii) If the default architecture is MIPS I or MIPS II, selecting
	 a 64-bit ABI will switch to MIPS III.

    (iii) If the default architecture is MIPS 32, selecting a 64-bit
	  ABI will switch to MIPS 64.

(5) GCC has some code to infer register size from the architecture
    and ABI, but it's spread over specs and override_options.  I've
    moved it all to override_options so that the register size can
    depend on -march too.

A few other sundry things:

- -mcpu was deprecated in the last GCC and GAS releases.  This
  patch removes it.

- Both GCC and GAS could be better at detecting meaningless
  combinations.  I've tried to catch a few more.

- include/opcode/mips.h defines CPU_R2000, but there's no associated
  BFD arch, so -march=r2000 doesn't work.  It seems daft to add a 2000
  entry at this stage, so I've just mapped it to CPU_R3000 (like GCC).

- There's interim code in TARGET_CPP_BUILTINS that defines _R4000
  for 64-bit code and _R3000 for 32-bit code.  The patch tries to
  fix it.

- GAS and GCC didn't have quite the same -march arguments.  For
  example, GCC accepts -march=r4kc, but GAS insists on -march=4kc.
  To avoid that sort of thing in future, I've written a function
  that tries all the variations, using a table of just the
  "canonical" names.


I've tried to give the same structure to the GAS and GCC code,
so it's easy to compare and update.  A lot of the code is shared
outright.


A few other notes about the GAS changes:

With (5), it's no longer necessary for GAS to check the ABI in
the HAVE_32BIT_* macros, since the register size is always set.
That means we can remove the ABI field from mips_opts.  Also, the
new error checking means we can get rid of the ABI-killing code
for -mgp32, -mgp64 and -mfp32:

    case OPTION_GP32:
      file_mips_gp32 = 1;
      if (mips_opts.abi != O32_ABI)
	mips_opts.abi = NO_ABI;
      break;

This code seems suspect anyway: it's order-dependent, it silently
ignores incompatible options, and it means we ignore "-mabi=eabi" if
followed by "-mgp32" (despite it being a valid combination).

I'd prefer to choose the default CPU in configure: that way, we'd
get a compile-time error over missing entries, plus we can use globs.

Before 2.12, we only set EF_MIPS_ABI when -mabi was given on
the command line.  Since EF_MIPS_ABI is a GNU extension, the
onus seems to be on proving that it's safe to use it by default,
rather than the other way about.  So the patch uses NO_ABI as
the default for all configurations, but leaves open the possibility
of setting the default to something else on a per-configuration
basis.

And if you read all that, thanks for your patience.

The GAS part was tested on: mips-ecoff, mipsel-ecoff, mips-elf,
mipstx39-elf, mips64-elf, mips64orion-elf, mipsisa32-elf,
mipsisa64-elf, mipsel-linux-gnu and mips-sgi-irix6.5.  No
regressions.

GCC part was bootstrapped on mips-sgi-irix6.5, no regressions.
Also tested on mips64-elf, both with and without the GAS part
applied.

One part needs the other, really.  If the GCC patch is OK, I was
hoping to apply it before 3.2.  The GAS stuff is probably too
invasive for 2.13, though.

Thoughts?

Richard



[include/]
	* opcode/mips.h (CPU_R2000): Remove.

[gas/]
	* doc/c-mips.texi: Remove -mcpu.  Document -mabi.
	* configure.in: Work out the default MIPS ABI and architecture.
	* configure, config.in: Regenerate.
	* config/tc-mips.c (UNSET_ABI): New mips_abi_level.
	(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_arch_string, user_selected_mips_arch_p): New vars.
	(ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New macros.
	(HAVE_32BIT_GPRS, HAVE_32BIT_FPRS): Don't check the ABI.
	(mips_cpu_info): Remove "is_isa" field.
	(mips_isa_to_str, mips_cpu_to_str): Remove.
	(mips_ip): Read the processor name from mips_arch_string.  Use
	mips_isa_level to get the current ISA level.
	(OPTION_MCPU): Remove.
	(OPTION_FP64): New.
	(md_longopts): Add -mfp64, remove -mcpu.
	(md_parse_option): Make -mipsN update file_mips_isa rather than
	mips_opts.isa.  Use mips_parse_cpu.  Don't let -mgp32 and -mfp32
	change the ABI here.
	(show): 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.  Treat
	-march and -mipsN equally when inferring an ABI or register size.
	Look at the register size when inferring the ABI, and vice versa.
	Complain about more conflicting arguments.  (Logic unified
	with gcc 3.2.)
	(s_mipsset): Don't change the ABI.
	(mips_cpu_info_table): Remove is_isa field.  Remove ISA-level
	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_cpu_info_from_name): Remove.
	(mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
	(mips_parse_cpu, mips_isa_level): New fns.

[gas/testsuite]
	* gas/mips-gp32-fp64.d,
	* gas/mips-gp32-fp64-pic.d: Add -mfp64.


[gcc/]
	* doc/invoke.texi: Document -mabi=meabi.  Document -mips32, -mips64,
	and the associated -march values.  Be more careful about what the
	default is.  Mention the side-effects of -march and -mabi.  Say
	that the -mipsN options are equivalent to -march.
	* toplev.h (target_flags_explicit): Declare.
	* toplev.c (target_flags_explicit): New var.
	(set_target_switch): Update target_flags_explicit.
	* config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine.
	* config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies
	-mips3 instead of -mips4.
	* config/mips/elforion.h, config/mips/r3900.h: Define
	MIPS_CPU_DEFAULT instead of MIPS_CPU_STRING_DEFAULT.
	* config/mips/mips.h (mips_cpu_string): Remove.
	(mips_explicit_type_size_string): Remove.
	(mips_cpp_processor_macro): Declare.
	(TARGET_CPP_BUILTINS): Use mips_cpp_processor_macro.
	(TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size.
	(ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New.
	(GAS_ASM_SPEC): Remove -mabi=32 -> -mipsN rule.
	(CC1_SPEC): Remove ISA -> register-size rules.
	* config/mips/mips.c (user_selected_mips_arch_p): New var.
	(mips_cpu_string, mips_explicit_type_size_string): Remove.
	(mips_cpp_processor_macro): New var.
	(struct mips_processor): New.
	(mips_processors): New array.
	(mips_set_architecture): New fn.
	(override_options): Rework to make -mipsN equivalent to -march.
	Detect more erroneous cases, including those removed from CC1_SPEC.
	Make o64 the default 64-bit ABI when selecting a 64-bit processor
	for a 32-bit config.  Make -mips3 the default for -mabi=64.
	Unify logic with GAS 2.14.
	(mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
	(mips_parse_cpu): Take the name of the option as argument.  Raise
	an error if the option is wrong.
	(mips_cpu_from_isa_level): New fn.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: GAS patch --]
[-- Type: text/x-patch, Size: 59549 bytes --]

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	12 Jul 2002 15:19:07 -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	12 Jul 2002 15:19:07 -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	12 Jul 2002 15:19:07 -0000
*************** changequote([,])dnl
*** 555,560 ****
--- 555,626 ----
  
  # Other random stuff.
  
+     case ${cpu_type} in
+       mips)
+ 	# Translate the full CPU name, setting mips_cpu if it's associated
+ 	# with a particular processor model, or mips_isa if it's more
+ 	# generic.
+ 	case ${target_cpu} in
+ 	  mips | mipsbe | mipseb | mipsle | mipsel)
+ 	    mips_isa=ISA_MIPS1
+ 	    ;;
+ 	  mipstx39 | mipstx39el)
+ 	    mips_cpu=CPU_R3900
+ 	    ;;
+ 	  mips64 | mips64el)
+ 	    mips_isa=ISA_MIPS3
+ 	    ;;
+ 	  mips64vr4100 | mips64vr4100el)
+ 	    mips_cpu=CPU_VR4100
+ 	    ;;
+ 	  mips64vr4300 | mips64vr4300el)
+ 	    mips_cpu=CPU_R4300
+ 	    ;;
+ 	  mips64orion | mips64orionel)
+ 	    mips_cpu=CPU_R4600
+ 	    ;;
+ 	  mips64vr5000 | mips64vr5000el)
+ 	    mips_cpu=CPU_R5000
+ 	    ;;
+ 	  mipsisa32 | mipsisa32el)
+ 	    mips_isa=ISA_MIPS32
+ 	    ;;
+ 	  mipsisa64 | mipsisa64el)
+ 	    mips_isa=ISA_MIPS64
+ 	    ;;
+ 	esac
+ 	# Try to figure out the default ABI.  As far as GAS is concerned,
+ 	# this logic just selects the default setting of the EF_MIPS_ABI
+ 	# and EF_MIPS_ABI2 bits.
+ 
+ 	# Traditionally, we have only used EF_MIPS_ABI when the user gave
+ 	# -mabi on the command line.  We certainly don't want to use it
+ 	# ubiquitously because it's a GNU extension that many OSes and
+ 	# tools don't recognize.  Thus NO_ABI makes a sensible default.
+ 
+ 	# If a configuration does want a particular ABI to be the default,
+ 	# both GAS and GCC must agree on what that default is.  GAS tries
+ 	# to use the same logic as GCC when changing the ABI based on
+ 	# command line flags.
+ 	case ${target} in
+ 	  *)
+ 	    mips_abi=NO_ABI
+ 	    ;;
+ 	esac
+ 	if test -n "$mips_cpu"; then
+ 	  AC_DEFINE_UNQUOTED(TARGET_CPU_DEFAULT, $mips_cpu,
+ 			     [Default CPU (MIPS only)])
+ 	elif test -n "$mips_isa"; then
+ 	  AC_DEFINE_UNQUOTED(TARGET_ISA_DEFAULT, $mips_isa,
+ 			     [Default ISA (MIPS only)])
+ 	else
+ 	  AC_ERROR($target_cpu isn't a supported MIPS CPU name)
+ 	fi
+ 	AC_DEFINE_UNQUOTED(TARGET_ABI_DEFAULT, $mips_abi,
+ 			   [Default ABI (MIPS only)])
+ 	;;
+     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	12 Jul 2002 15:19:07 -0000
*************** extern int target_big_endian;
*** 120,126 ****
  /* The ABI to use.  */
  enum mips_abi_level
  {
!   NO_ABI = 0,
    O32_ABI,
    O64_ABI,
    N32_ABI,
--- 120,127 ----
  /* The ABI to use.  */
  enum mips_abi_level
  {
!   UNSET_ABI = 0,
!   NO_ABI,
    O32_ABI,
    O64_ABI,
    N32_ABI,
*************** 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
--- 130,136 ----
  };
  
  /* MIPS ABI we are using for this output file.  */
! static enum mips_abi_level mips_abi = UNSET_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.  */
--- 178,183 ----
*************** 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.
--- 192,198 ----
  
  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
--- 216,235 ----
     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;
  
+ /* The same, as a string.  Always non-null after argument processing.  */
+ static const char *mips_arch_string;
+ 
+ /* True if mips_arch was set on the command line.  */
+ static boolean user_selected_mips_arch_p;
+ 
  /* The argument of the -mtune= flag.  The architecture for which we
     are optimizing.  */
  static int mips_tune = CPU_UNKNOWN;
  
! /* 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 ****
--- 246,260 ----
     || (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.  */
--- 264,280 ----
     )
  
  #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 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
--- 777,784 ----
  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
*************** enum small_ex_type
*** 812,825 ****
  struct mips_cpu_info
  {
    const char *name;           /* CPU or ISA name.  */
-   int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
    int isa;                    /* ISA level.  */
    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));
  \f
  /* Pseudo-op table.
  
--- 815,832 ----
  struct mips_cpu_info
  {
    const char *name;           /* CPU or ISA name.  */
    int isa;                    /* ISA level.  */
    int cpu;                    /* CPU number (default CPU if ISA).  */
  };
  
! static void mips_set_architecture PARAMS ((const struct mips_cpu_info *, int));
! 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 void mips_parse_cpu PARAMS ((const char *, const char *, int *));
  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));
+ static int mips_isa_level PARAMS ((int));
  \f
  /* 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 *
--- 979,984 ----
*************** 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);
  
--- 1154,1160 ----
  	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)
*** 7764,7772 ****
  		{
  		  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;
  		}
--- 7741,7748 ----
  		{
  		  static char buf[100];
  		  sprintf (buf,
! 			   _("opcode not supported on this processor: %s (MIPS%d)"),
! 			   mips_arch_string, mips_isa_level (mips_opts.isa));
  
  		  insn_error = buf;
  		}
*************** 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)
--- 9868,9875 ----
    {"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)
*************** md_parse_option (c, arg)
*** 10001,10085 ****
        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:
--- 9977,10017 ----
        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_parse_cpu ("-mtune", arg, &mips_tune);
!       break;
  
!     case OPTION_MARCH:
!       mips_parse_cpu ("-march", arg, &mips_arch);
!       if (mips_arch != CPU_UNKNOWN)
! 	mips_arch_string = arg;
        break;
  
      case OPTION_M4650:
*************** 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:
--- 10159,10165 ----
  	  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:
--- 10168,10174 ----
  	  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;
--- 10177,10183 ----
  	  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
--- 10185,10202 ----
  
      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);
--- 10207,10226 ----
  	  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)
*** 10327,10333 ****
  static void
  show (stream, string, col_p, first_p)
       FILE *stream;
!      char *string;
       int *col_p;
       int *first_p;
  {
--- 10257,10263 ----
  static void
  show (stream, string, col_p, first_p)
       FILE *stream;
!      const char *string;
       int *col_p;
       int *first_p;
  {
*************** show (stream, string, col_p, first_p)
*** 10353,10466 ****
  
    *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
- }
- \f
  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)
--- 10283,10306 ----
  
    *first_p = 0;
  }
+ \f
+ /* Set up globals to generate code for ARCH.  USER_SELECTED_P is true
+    if the user selected this architecture explicitly.  */
  
! static void
! mips_set_architecture (info, user_selected_p)
!      const struct mips_cpu_info *info;
!      int user_selected_p;
  {
!   mips_arch = info->cpu;
!   mips_opts.isa = info->isa;
!   user_selected_mips_arch_p = user_selected_p;
! }
  
  
  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)
--- 10310,10450 ----
        g_switch_value = 0;
      }
  
!   /* The following code determines the architecture, ABI and register size.
!      Much of the complexity is in infering complete information when some
!      flags are not given.  Some of the details are historical.
  
!      Similar code was added to GCC 3.2 (see config/mips/mips.c:
!      override_options()).  The GAS and GCC code should be kept in sync
!      as much as possible.  */
  
  
!   /* -march is more descriptive than -mipsN, so check it first.  */
!   if (mips_arch != CPU_UNKNOWN)
      {
!       mips_set_architecture (mips_cpu_info_from_cpu (mips_arch), true);
!       if (file_mips_isa != ISA_UNKNOWN)
  	{
! 	  /* The user specified both -mipsN and -march.  There's no
! 	     harm in it if the two arguments agree, just as there's
! 	     no harm in giving redundant register size options.  Only
! 	     complain if the arguments contradict one another.  */
! 	  if (file_mips_isa != mips_opts.isa)
! 	    as_bad (_("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor"),
! 		    mips_isa_level (file_mips_isa),
! 		    mips_isa_level (mips_opts.isa));
  	}
+     }
+   else if (file_mips_isa != ISA_UNKNOWN)
+     mips_set_architecture (mips_cpu_info_from_isa (file_mips_isa), true);
+   else
+ #ifdef TARGET_CPU_DEFAULT
+     mips_set_architecture (mips_cpu_info_from_cpu (TARGET_CPU_DEFAULT), false);
+ #else
+     mips_set_architecture (mips_cpu_info_from_isa (TARGET_ISA_DEFAULT), false);
+ #endif
  
  
!   if (mips_abi != UNSET_ABI)
!     {
!       if (!ISA_HAS_64BIT_REGS (mips_opts.isa)
! 	  && ABI_NEEDS_64BIT_REGS (mips_abi))
  	{
! 	  if (user_selected_mips_arch_p)
! 	    as_bad (_("Command line selects a 64-bit ABI and a 32-bit processor"));
! 	  else
! 	    {
! 	      /* The user specified an ABI but not an ISA.  The ABI needs
! 		 64-bit registers, but the default architecture is 32-bit.
! 		 GCC has historically "upgraded" to a 64-bit ISA.  */
! 	      int level = (mips_opts.isa == 32 ? 64 : 3);
! 	      mips_set_architecture (mips_cpu_info_from_isa (level), false);
! 	    }
  	}
      }
!   else if (file_mips_gp32 == 1)
      {
!       /* The user didn't specify an ABI, but used -mgp32.
! 	 Force a 32-bit ABI.  */
!       if (ABI_NEEDS_64BIT_REGS (TARGET_ABI_DEFAULT))
! 	mips_abi = O32_ABI;
      }
!   else if (user_selected_mips_arch_p)
      {
!       /* The user specified a processor but not an ABI.  We've already
! 	 handled the -mgp32 case, so either the register size was not
! 	 specified explicitly, or it is expected to match the processor's.
! 	 If the processor's register size doesn't match the ABI, switch
! 	 to another ABI.  */
!       if (!ISA_HAS_64BIT_REGS (mips_opts.isa)
! 	  && ABI_NEEDS_64BIT_REGS (TARGET_ABI_DEFAULT))
! 	mips_abi = O32_ABI;
!       else if (ISA_HAS_64BIT_REGS (mips_opts.isa)
! 	       && ABI_NEEDS_32BIT_REGS (TARGET_ABI_DEFAULT))
! 	mips_abi = O64_ABI;
      }
  
!   if (mips_abi == UNSET_ABI)
      {
!       /* The user took no action that implied an ABI change.  */
!       mips_abi = TARGET_ABI_DEFAULT;
      }
  
!   /* At this point, we know the architecture and ABI.  We've also
!      avoided the case that ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS,
!      unless the user selected it explicitly, in which case we've
!      complained.  */
  
!   /* Make sure we have an architecture name.  Prefer to use the
!      argument to -march, if given, since it's what the user might
!      expect to see in error messages.  Otherwise use the canonical
!      name for this architecture.  */
!   if (mips_arch_string == 0)
!     mips_arch_string = mips_cpu_info_from_cpu (mips_arch)->name;
! 
!   /* Optimize for mips_arch, unless -mtune selects a different processor.  */
!   if (mips_tune == CPU_UNKNOWN)
!     mips_tune = mips_arch;
! 
!   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.  */
  
!   /* ??? Under what conditions do we want this flag to be set?
!      Who uses it?  */
!   if (file_mips_gp32 == 1 && 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;
--- 10454,10460 ----
*************** 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:
--- 11529,11534 ----
*************** 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;
--- 11540,11545 ----
*************** void
*** 13201,13207 ****
  mips_elf_final_processing ()
  {
    /* Write out the register information.  */
!   if (file_mips_abi != N64_ABI)
      {
        Elf32_RegInfo s;
  
--- 12988,12994 ----
  mips_elf_final_processing ()
  {
    /* Write out the register information.  */
!   if (mips_abi != N64_ABI)
      {
        Elf32_RegInfo s;
  
*************** mips_elf_final_processing ()
*** 13251,13263 ****
      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.  */
--- 13038,13050 ----
      elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_MDMX;
  
    /* Set the MIPS ELF ABI flags.  */
!   if (mips_abi == NO_ABI)
      ;
!   else if (mips_abi == O32_ABI)
      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)
      {
        /* Set the EABI kind based on the ISA.  This isn't really
  	 the best, but then neither is basing the abi on the isa.  */
*************** mips_elf_final_processing ()
*** 13266,13272 ****
        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.  */
--- 13053,13059 ----
        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)
*** 13709,13882 ****
  
  /* 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;
--- 13496,13644 ----
  
  /* CPU name/ISA/number mapping table.
  
!    Entries are grouped by type.  The first mention of a CPU_* value
!    is taken to be the canonical entry for that CPU.  */
  static const struct mips_cpu_info mips_cpu_info_table[] =
  {
!   { "Generic-MIPS5",  ISA_MIPS5,      CPU_MIPS5, },
!   { "Generic-MIPS32", ISA_MIPS32,     CPU_MIPS32, },
!   { "Generic-MIPS64", ISA_MIPS64,     CPU_MIPS64, },
  
!   /* We also accept the names of specific MIPS 32 processors, although
!      the differences between them don't matter to us.  */
!   { "R4KC",           ISA_MIPS32,     CPU_MIPS32, },
!   { "R4KM",           ISA_MIPS32,     CPU_MIPS32, },
!   { "R4KP",           ISA_MIPS32,     CPU_MIPS32, },
  
!   /* Likewise for some MIPS 64 processors...  */
!   { "R5KC",           ISA_MIPS64,     CPU_MIPS64, },
!   { "R20KC",          ISA_MIPS64,     CPU_MIPS64, },
  
!   /* Various names for the Broadcom SB-1.  */
!   { "SB-1",           ISA_MIPS64,     CPU_SB1, },
!   { "sb-1250",        ISA_MIPS64,     CPU_SB1, },
!   { "sb1",            ISA_MIPS64,     CPU_SB1, },
!   { "sb1250",         ISA_MIPS64,     CPU_SB1, },
  
!   /* The canonical entries for the other ISA levels.  */
!   { "R3000",          ISA_MIPS1,      CPU_R3000, },
!   { "R6000",          ISA_MIPS2,      CPU_R6000, },
!   { "R4000",          ISA_MIPS3,      CPU_R4000, },
!   { "R8000",          ISA_MIPS4,      CPU_R8000, },
  
!   /* ??? Use the r3000 bfd arch for r2000.  */
!   { "R2000",          ISA_MIPS1,      CPU_R3000, },
!   { "R3900",          ISA_MIPS1,      CPU_R3900, },
!   { "R4010",          ISA_MIPS2,      CPU_R4010, },
!   { "R4400",          ISA_MIPS3,      CPU_R4400, },
!   { "R4600",          ISA_MIPS3,      CPU_R4600, },
!   { "orion",          ISA_MIPS3,      CPU_R4600, },
!   { "R4650",          ISA_MIPS3,      CPU_R4650, },
!   { "R10000",         ISA_MIPS4,      CPU_R10000, },
!   { "R12000",         ISA_MIPS4,      CPU_R12000, },
!   { "VR4100",         ISA_MIPS3,      CPU_VR4100, },
!   { "VR4111",         ISA_MIPS3,      CPU_R4111, },
!   { "VR4300",         ISA_MIPS3,      CPU_R4300, },
!   { "VR5000",         ISA_MIPS4,      CPU_R5000, },
!   { "RM5200",         ISA_MIPS4,      CPU_R5000, },
!   { "RM5230",         ISA_MIPS4,      CPU_R5000, },
!   { "RM5231",         ISA_MIPS4,      CPU_R5000, },
!   { "RM5261",         ISA_MIPS4,      CPU_R5000, },
!   { "RM5721",         ISA_MIPS4,      CPU_R5000, },
!   { "R7000",          ISA_MIPS4,      CPU_R5000, },
  
!   /* End marker.  */
!   { NULL, 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.
!    If CPU_STRING is a recognized processor, store its CPU_* enumeration
!    in *CPU_PTR, otherwise report an error.  Warn if the same option
!    is used twice.  */
  
! static void
! mips_parse_cpu (option, cpu_string, cpu_ptr)
!      const char *option, *cpu_string;
!      int *cpu_ptr;
  {
    int i;
  
+   if (*cpu_ptr != CPU_UNKNOWN)
+     as_warn (_("Duplicate %s options: using %s"), option, cpu_string);
+ 
    for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
!     if (mips_matching_cpu_name_p (mips_cpu_info_table[i].name, cpu_string))
!       {
! 	*cpu_ptr = mips_cpu_info_table[i].cpu;
! 	return;
!       }
  
!   if (strcasecmp (cpu_string, "default") == 0)
!     {
!       *cpu_ptr = CPU_UNKNOWN;
!       return;
!     }
! 
!   as_bad (_("Unrecognised argument (%s) to %s"), cpu_string, option);
  }
  
+ 
+ /* 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)
*** 13884,13896 ****
    int i;
  
    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;
--- 13646,13660 ----
    int i;
  
    for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
!     if (isa == mips_cpu_info_table[i].isa)
        return (&mips_cpu_info_table[i]);
  
    return NULL;
  }
  
+ 
+ /* Likewise CPU (a member of the CPU_* enumeration).  */
+ 
  static const struct mips_cpu_info *
  mips_cpu_info_from_cpu (cpu)
       int cpu;
*************** mips_cpu_info_from_cpu (cpu)
*** 13898,13906 ****
    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;
  }
--- 13662,13770 ----
    int i;
  
    for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
!     if (cpu == mips_cpu_info_table[i].cpu)
        return (&mips_cpu_info_table[i]);
  
    return NULL;
+ }
+ 
+ 
+ /* Convert one of the internal ISA_MIPS* values into an integer ISA level.
+    Used mainly for diagnostics.  */
+ 
+ static int
+ mips_isa_level (bfd_encoding)
+      int bfd_encoding;
+ {
+   switch (bfd_encoding)
+     {
+     case ISA_MIPS1: return 1;
+     case ISA_MIPS2: return 2;
+     case ISA_MIPS3: return 3;
+     case ISA_MIPS4: return 4;
+     case ISA_MIPS5: return 5;
+     case ISA_MIPS32: return 32;
+     case ISA_MIPS64: return 64;
+     default: abort ();
+     }
+ }
+ \f
+ 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);
+   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	12 Jul 2002 15:19:07 -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	12 Jul 2002 15:19:07 -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.*

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: GCC patch --]
[-- Type: text/x-patch, Size: 48102 bytes --]

Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.155
diff -c -d -p -r1.155 invoke.texi
*** doc/invoke.texi	10 Jul 2002 19:17:51 -0000	1.155
--- doc/invoke.texi	12 Jul 2002 15:47:52 -0000
*************** These @samp{-m} options are defined for 
*** 6956,7018 ****
  
  @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
--- 6956,7015 ----
  
  @item -march=@var{cpu-type}
  @opindex march
! Generate code that will run on @var{cpu-type}.  GCC might use
! any instruction that the processor understands, subject to the
! options described below.  @var{cpu-type} can be @samp{r2000},
! @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4100}, @samp{r4300},
! @samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{r5000}, @samp{r6000},
! @samp{r8000}, @samp{r4kc}, @samp{r4kp}, @samp{r5kc}, @samp{r20kc}
! or @samp{orion}.  @samp{r@var{x}000} can be abbreviated as
! @samp{r@var{x}k} (for example, @samp{-march=r2k}).  The initial
! @samp{r} is optional.
! 
! If your configuration uses the o32 ABI by default, selecting a 64-bit
! processor will implicitly select the o64 ABI@.  You can continue to use
! the o32 ABI by adding @samp{-mgp32} to the command line (for example,
! @samp{-march=r4000 -mgp32}).
! 
! If your configuration uses a 64-bit ABI by default, selecting a 32-bit
! processor will implicitly select the o32 ABI@.
  
  @item -mtune=@var{cpu-type}
  @opindex mtune
! Optimize for @var{cpu-type}.  Among other things, this option controls
! the way instructions are scheduled, and the perceived cost of arithmetic
! operations.  The list of @var{cpu-type} values is the same as for
! @samp{-march}.
  
! When this option is not used, GCC will optimize for the processor
! specified by @samp{-march}, or (failing that) for the default
! processor.  By using @samp{-march} and @samp{-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.
  
  @item -mips1
  @opindex mips1
! Equivalent to @samp{-march=r2000}.
  
  @item -mips2
  @opindex mips2
! Equivalent to @samp{-march=r6000}.
  
  @item -mips3
  @opindex mips3
! Equivalent to @samp{-march=r4000}.
  
  @item -mips4
  @opindex mips4
! Equivalent to @samp{-march=r8000}.
  
! @item -mips32
! @opindex mips32
! Equivalent to @samp{-march=r4kc}.
  
! @item -mips64
! @opindex mips64
! Equivalent to @samp{-march=r5kc}.
  
  @item -mfused-madd
  @itemx -mno-fused-madd
*************** in the mode where denormals are rounded 
*** 7026,7040 ****
  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
--- 7023,7043 ----
  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
*************** registers (which in turn depends on the 
*** 7065,7080 ****
  @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
--- 7068,7092 ----
  @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 indicated ABI@.  Not all configurations support
! this option.
! 
! If your configuration generates MIPS I or MIPS II code by default,
! selecting @samp{o64}, @samp{n32} or @samp{64} will switch to
! MIPS III code.  If it generates MIPS 32 code by default, the same
! options will switch to MIPS 64 code.  You can override this behavior
! using the options @samp{-mips@var{N}} or @samp{-march}.
! 
! Note that there are two embedded ABIs: @samp{-mabi=eabi}
! selects the one defined by Cygnus while @samp{-meabi=meabi}
! selects the one defined by MIPS@.
  
  @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	12 Jul 2002 15:47:52 -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.656
diff -c -d -p -r1.656 toplev.c
*** toplev.c	7 Jul 2002 22:10:17 -0000	1.656
--- toplev.c	12 Jul 2002 15:47:52 -0000
*************** const char *dump_base_name;
*** 178,183 ****
--- 178,188 ----
  
  extern int target_flags;
  
+ /* A mask of target_flags that includes bit X if X was specified
+    explicitly 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)
*** 4361,4366 ****
--- 4366,4378 ----
  	  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/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	12 Jul 2002 15:47:52 -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/elforion.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/elforion.h,v
retrieving revision 1.2
diff -c -d -p -r1.2 elforion.h
*** config/mips/elforion.h	16 Dec 1998 21:09:02 -0000	1.2
--- config/mips/elforion.h	12 Jul 2002 15:47:52 -0000
*************** along with GNU CC; see the file COPYING.
*** 19,22 ****
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #define MIPS_CPU_STRING_DEFAULT "orion"
--- 19,22 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #define MIPS_CPU_DEFAULT PROCESSOR_4600
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	12 Jul 2002 15:47:52 -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/r3900.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/r3900.h,v
retrieving revision 1.14
diff -c -d -p -r1.14 r3900.h
*** config/mips/r3900.h	13 Jun 2002 10:14:12 -0000	1.14
--- config/mips/r3900.h	12 Jul 2002 15:47:52 -0000
*************** along with GNU CC; see the file COPYING.
*** 22,28 ****
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #define MIPS_CPU_STRING_DEFAULT "r3900"
  #define MIPS_ISA_DEFAULT 1
  
  #define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, "msoft-float" }
--- 22,28 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #define MIPS_CPU_DEFAULT PROCESSOR_R3900
  #define MIPS_ISA_DEFAULT 1
  
  #define MULTILIB_DEFAULTS { MULTILIB_ENDIAN_DEFAULT, "msoft-float" }
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.197
diff -c -d -p -r1.197 mips.h
*** config/mips/mips.h	11 Jul 2002 18:56:56 -0000	1.197
--- config/mips/mips.h	12 Jul 2002 15:47:52 -0000
*************** enum delay_type {
*** 54,60 ****
  /* Which processor to schedule for.  Since there is no difference between
     a R2000 and R3000 in terms of the scheduler, we collapse them into
     just an R3000.  The elements of the enumeration must match exactly
!    the cpu attribute in the mips.md machine description.  */
  
  enum processor_type {
    PROCESSOR_DEFAULT,
--- 54,61 ----
  /* Which processor to schedule for.  Since there is no difference between
     a R2000 and R3000 in terms of the scheduler, we collapse them into
     just an R3000.  The elements of the enumeration must match exactly
!    the cpu attribute in the mips.md machine description and mips_processors[]
!    in mips.c.  */
  
  enum processor_type {
    PROCESSOR_DEFAULT,
*************** extern int mips_isa;			/* architectural 
*** 146,160 ****
  extern int mips16;			/* whether generating mips16 code */
  extern int mips16_hard_float;		/* mips16 without -msoft-float */
  extern int mips_entry;			/* generate entry/exit for mips16 */
- extern const char *mips_cpu_string;	/* for -mcpu=<xxx> */
  extern const char *mips_arch_string;    /* for -march=<xxx> */
  extern const char *mips_tune_string;    /* for -mtune=<xxx> */
  extern const char *mips_isa_string;	/* for -mips{1,2,3,4} */
  extern const char *mips_abi_string;	/* for -mabi={32,n32,64} */
  extern const char *mips_entry_string;	/* for -mentry */
  extern const char *mips_no_mips16_string;/* for -mno-mips16 */
- extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
  extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
  extern int mips_split_addresses;	/* perform high/lo_sum support */
  extern int dslots_load_total;		/* total # load related delay slots */
  extern int dslots_load_filled;		/* # filled load delay slots */
--- 147,160 ----
  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_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_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
+ extern const char *mips_cpp_processor_macro;
  extern int mips_split_addresses;	/* perform high/lo_sum support */
  extern int dslots_load_total;		/* total # load related delay slots */
  extern int dslots_load_filled;		/* # filled load delay slots */
*************** extern void		sbss_section PARAMS ((void)
*** 358,375 ****
  	  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");				\
! 	}							\
        if (TARGET_FLOAT64)					\
  	  builtin_define ("__mips_fpr=64");			\
        else							\
--- 358,365 ----
  	  builtin_define ("mips");				\
  								\
        if (TARGET_64BIT)						\
! 	builtin_define ("__mips64");     			\
! 								\
        if (TARGET_FLOAT64)					\
  	  builtin_define ("__mips_fpr=64");			\
        else							\
*************** extern void		sbss_section PARAMS ((void)
*** 378,383 ****
--- 368,376 ----
        if (TARGET_MIPS16)					\
  	  builtin_define ("__mips16");				\
  								\
+       builtin_define_std (&mips_cpp_processor_macro[1]);	\
+       builtin_define (mips_cpp_processor_macro);		\
+ 								\
        if (ISA_MIPS1)						\
  	{							\
  	  builtin_define ("__mips=1");				\
*************** extern void		sbss_section PARAMS ((void)
*** 679,686 ****
  #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,                                      \
--- 672,677 ----
*************** extern void		sbss_section PARAMS ((void)
*** 691,698 ****
        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,				\
--- 682,687 ----
*************** extern void		sbss_section PARAMS ((void)
*** 720,725 ****
--- 709,724 ----
  #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)
*** 910,916 ****
  /* 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;
--- 909,915 ----
  /* 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)"
  
  
  extern int mips_abi;
*************** extern int mips_abi;
*** 1048,1062 ****
  #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)"
--- 1047,1052 ----
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.214
diff -c -d -p -r1.214 mips.c
*** config/mips/mips.c	11 Jul 2002 18:56:56 -0000	1.214
--- config/mips/mips.c	12 Jul 2002 15:47:53 -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 ((enum processor_type,
! 							 int));
! 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 enum processor_type mips_parse_cpu       PARAMS ((const char *,
! 							 const char *));
! static enum processor_type mips_cpu_from_isa_level 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;
*** 295,300 ****
--- 303,311 ----
  /* The target cpu for code generation.  */
  enum processor_type mips_arch;
  
+ /* True if the user selected the architecture on the command line.  */
+ static bool user_selected_mips_arch_p;
+ 
  /* The target cpu for optimization and scheduling.  */
  enum processor_type mips_tune;
  
*************** int mips_isa;
*** 305,316 ****
  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} */
  const char *mips_abi_string;	/* for -mabi={32,n32,64,eabi} */
  
  /* Whether we are generating mips16 code.  This is a synonym for
     TARGET_MIPS16, and exists for use as an attribute.  */
  int mips16;
--- 316,329 ----
  int mips_abi;
  
  /* Strings to hold which cpu and instruction set architecture to use.  */
  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} */
  const char *mips_abi_string;	/* for -mabi={32,n32,64,eabi} */
  
+ /* The name of target processor, with a leading underscore.  */
+ const char *mips_cpp_processor_macro;
+ 
  /* Whether we are generating mips16 code.  This is a synonym for
     TARGET_MIPS16, and exists for use as an attribute.  */
  int mips16;
*************** 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
--- 333,338 ----
*************** enum reg_class mips_char_to_class[256] =
*** 562,567 ****
--- 570,613 ----
    NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  };
  \f
+ /* Information about one member of enum processor_type.  */
+ struct mips_processor {
+   /* The name of the processor, in lower case.  If the processor is
+      a recognised member of the NEC VR range, the name should start
+      with 'vr', otherwise it typically starts with 'r'.  */
+   const char *name;
+ 
+   /* The preprocessor macro that should be defined when generating
+      code for this processor.  It typically starts with "_R", followed
+      by the numerical designation.  We also define the macro with two
+      leading underscores, and sometimes with none.  */
+   const char *cpp_macro;
+ 
+   /* The ISA level most closely associated with the processor.
+      Sometimes the processor has extra instructions that aren't
+      defined at this ISA level.  Sometimes the ISA level defines
+      instructions that the processor doesn't implement.  */
+   int isa_level;
+ };
+ 
+ /* This array must have the same order as enum processor_type.  */
+ static const struct mips_processor mips_processors[] = {
+   { "default", 0, 1 },
+   { "r3000", "_R3000", 1 },
+   { "r3900", "_R3900", 1 },
+   { "r6000", "_R6000", 2 },
+   { "r4000", "_R4000", 3 },
+   { "vr4100", "_R4100", 3 },
+   { "vr4300", "_R4300", 3 },
+   { "r4600", "_R4600", 3 },
+   { "r4650", "_R4650", 3 },
+   { "vr5000", "_R5000", 4 },
+   { "r8000", "_R8000", 4 },
+   { "r4kc", "_R4KC", 32 },
+   { "r5kc", "_R5KC", 64 },
+   { "r20kc", "_R20KC", 64 }
+ };
+ \f
  /* 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)
*** 4976,4991 ****
    abort ();
  }
  \f
  /* 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;
  
--- 5022,5053 ----
    abort ();
  }
  \f
+ /* Set up globals to generate code for ARCH.  USER_SELECTED_P is true
+    if the user selected this architecture explicitly.  */
+ 
+ static void
+ mips_set_architecture (arch, user_selected_p)
+      enum processor_type arch;
+      int user_selected_p;
+ {
+   if (arch != PROCESSOR_DEFAULT)
+     {
+       mips_arch = arch;
+       mips_isa = mips_processors[arch].isa_level;
+       mips_cpp_processor_macro = mips_processors[arch].cpp_macro;
+       user_selected_mips_arch_p = user_selected_p;
+     }
+ }
+ 
+ 
  /* 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 ()
*** 5003,5252 ****
      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)
--- 5065,5246 ----
      target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
  #endif
  
!   /* The following code determines the architecture, ABI and register size.
!      Much of the complexity is in infering complete information when some
!      flags are not given.  Some of the details are historical.
  
!      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.  */
  
!   /* First select the default architecture.  */
! #ifdef MIPS_CPU_DEFAULT
!   mips_set_architecture (MIPS_CPU_DEFAULT, false);
! #else
!   mips_set_architecture (mips_cpu_from_isa_level (MIPS_ISA_DEFAULT), false);
! #endif
! 
!   /* -march is more descriptive than -mipsN, so check it first.  */
!   if (mips_arch_string != 0)
!     mips_set_architecture (mips_parse_cpu ("-march", mips_arch_string), true);
! 
!   if (mips_isa_string != 0)
      {
!       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 (user_selected_mips_arch_p)
  	{
! 	  /* The user specified both -mipsN and -march.  There's no
! 	     harm in it if the two arguments agree, just as there's
! 	     no harm in giving redundant register size options.  Only
! 	     complain if the arguments contradict one another.  */
! 	  if (mips_isa != level)
! 	    error ("-mips%d conflicts with the other architecture options, which specify a MIPS%d processor",
! 		   level, mips_isa);
! 	}
!       else
! 	{
! 	  /* -mipsN selects the base-line processor for ISA level N.  */
! 	  mips_set_architecture (mips_cpu_from_isa_level (level), true);
! 	  if (!user_selected_mips_arch_p)
! 	    error ("bad value (%s) for -mips switch", mips_isa_string);
  	}
      }
  
!   mips_abi = MIPS_ABI_DEFAULT;
!   if (mips_abi_string != 0)
      {
!       /* Interpret -mabi.  */
!       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
+ 	error ("bad value (%s) for -mabi= switch", mips_abi_string);
+ 
+       if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
  	{
! 	  if (user_selected_mips_arch_p)
! 	    error ("-mabi=%s used with a 32-bit processor", mips_abi_string);
! 	  else
! 	    {
! 	      /* The user specified an ABI but not an ISA.  The ABI needs
! 		 64-bit registers, but the default architecture is 32-bit.
! 		 GCC has historically "upgraded" to a 64-bit ISA.  */
! 	      int level = (mips_isa == 32 ? 64 : 3);
! 	      mips_set_architecture (mips_cpu_from_isa_level (level), false);
! 	    }
  	}
      }
!   else if ((target_flags_explicit & MASK_64BIT) != 0 && !TARGET_64BIT)
      {
!       /* The user didn't specify an ABI, but used -mgp32.
! 	 Force a 32-bit ABI.  */
!       if (ABI_NEEDS_64BIT_REGS)
! 	mips_abi = ABI_32;
      }
!   else if (user_selected_mips_arch_p)
      {
!       /* The user specified a processor but not an ABI.  We've already
! 	 handled the -mgp32 case, so either the register size was not
! 	 specified explicitly, or it is expected to match the processor's.
! 	 If the processor's register size doesn't match the ABI, switch
! 	 to another ABI.  */
!       if (!ISA_HAS_64BIT_REGS && ABI_NEEDS_64BIT_REGS)
! 	mips_abi = ABI_32;
!       else if (ISA_HAS_64BIT_REGS && ABI_NEEDS_32BIT_REGS)
! 	mips_abi = ABI_O64;
      }
  
!   /* At this point, we know the architecture and ABI.  We've also
!      avoided the case that ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS,
!      unless the user selected it explicitly, in which case we've
!      complained.  */
  
!   /* Make sure we have an architecture name.  Prefer to use the
!      argument to -march, if given, since it's what the user might
!      expect to see in error messages.  Otherwise use the canonical
!      name for this architecture.  */
    if (mips_arch_string == 0)
!     mips_arch_string = mips_processors[mips_arch].name;
  
!   /* Optimize for mips_arch, unless -mtune selects a different processor.  */
!   if (mips_tune_string == 0)
      {
!       mips_tune = mips_arch;
!       mips_tune_string = mips_arch_string;
      }
+   else
+     mips_tune = mips_parse_cpu ("-mtune", mips_tune_string);
  
!   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_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.
--- 10160,10286 ----
    /* NOTREACHED */
    return 0;
  }
+ \f
+ /* 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 PROCESSOR_DEFAULT.  */
  
! static enum processor_type
! mips_parse_cpu (option, cpu_string)
!      const char *option;
!      const char *cpu_string;
! {
!   static const struct {
!     const char *name;
!     enum processor_type processor;
!   } aliases[] = {
!     { "r2000", PROCESSOR_R3000 },
!     { "r4400", PROCESSOR_R4000 },
!     { "orion", PROCESSOR_R4600 },
!     /* 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.  */
!     { "r4kp", PROCESSOR_R4KC }
!   };
  
!   const char *p;
!   size_t i;
  
!   /* In the past, we allowed upper-case CPU names, but it doesn't
!      work well with the multilib machinery.  */
!   for (p = cpu_string; *p != 0; p++)
!     if (ISUPPER (*p))
!       {
! 	warning ("the cpu name must be lower case");
! 	break;
!       }
! 
!   /* First search the processor array for a matching name.  */
!   for (i = 0; i < ARRAY_SIZE (mips_processors); i++)
!     if (mips_matching_cpu_name_p (mips_processors[i].name, cpu_string))
!       return (enum processor_type) i;
! 
!   /* If that doesn't work, check for a few well-known aliases.  */
!   for (i = 0; i < ARRAY_SIZE (aliases); i++)
!     if (mips_matching_cpu_name_p (aliases[i].name, cpu_string))
!       return aliases[i].processor;
! 
!   error ("bad value (%s) for %s", cpu_string, option);
!   return PROCESSOR_DEFAULT;
  }
  
+ 
+ /* Return the processor associated with the given ISA level, or
+    PROCESSOR_DEFAULT if the level is invalid.  */
+ 
+ static enum processor_type
+ mips_cpu_from_isa_level (isa_level)
+      int isa_level;
+ {
+   switch (isa_level)
+     {
+     case 1: return PROCESSOR_R3000;
+     case 2: return PROCESSOR_R6000;
+     case 3: return PROCESSOR_R4000;
+     case 4: return PROCESSOR_R8000;
+     case 32: return PROCESSOR_R4KC;
+     case 64: return PROCESSOR_R5KC;
+     default: return PROCESSOR_DEFAULT;
+     }
+ }
+ \f
  /* 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.

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 10:16 RFC & patch: Rework MIPS command-line handling Richard Sandiford
@ 2002-07-12 11:39 ` Maciej W. Rozycki
  2002-07-12 12:28   ` Paul Koning
  2002-07-15  4:50   ` Richard Sandiford
  2002-07-12 11:46 ` Eric Christopher
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-12 11:39 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

On 12 Jul 2002, Richard Sandiford wrote:

> (1) The main discrepancy I see with the current set-up is in the handling
>     of -march.  In GAS, it fully controls the ISA, much like -mipsN does,
>     but in GCC it only controls the use of processor-specific extensions.
>     So, for example,
> 
> 	mips-elf-as -march=r8000
> 
>     selects MIPS IV code but
> 
> 	mips-elf-gcc -march=r8000
> 
>     selects MIPS I code.  I'd like to make it so that both cc1 and gas treat
>     -march like a more descriptive version of -mipsN.  -march=r8000 would
>     be equivalent to -mips4, -march=r4000 would be equivalent to -mips3,
>     and so on.

 Agreed, except that "-mips" options are deprecated, I'm told.  But
conceptually OK. 

> (2) Traditionally, GCC has tried to infer sensible things from a sparse
>     command line.  Passing -mipsN would select a suitable ABI for ISA N,
>     passing -mabi=FOO would select a suitable ISA for ABI FOO, and so on.
>     Lately, gas has done the same thing, although the assumptions are
>     slightly different (more later).
> 
>     If -march is going to act like -mipsN, then it ought to choose the
>     ABI as well.  For example, if "mips64-elf-gcc -mips1" chooses o32 code
>     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.

 I'd prefer to select the default ABI at the configure time, from the
target triplet ideally.  E.g. I use a local patch that select the 64 ABI
as the default for binutils if configuring for mips64*-*-linux*.  The same
is set in the specs file for gcc for this target.

> (3) The GCC code to infer an ABI from an ISA looks like this:
> 
> 	/* 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
> 		  mips_abi = ABI_64;
> 	      }
> 	  }
> 
>     Some problems here:
> 
>     (a) The o64 exclusion seems strange.  Passing -mips1 or -mips2 to
> 	an o64-configured GCC will generate "32-bit o64" code (we get
> 	the 32-bit register size from CC1_SPEC).  It turns out to be
> 	almost the same as O32 code, except you get an .mdebug.abiO64
> 	section instead of an .mdebug.abi32 section.

 Hmm, what is "o64"?

>     (b) Passing -mips3 to an n32 MIPS III config (e.g. mips-sgi-irix6)
> 	will select n64, which seems counter-intuitive.

 Agreed, I think nothing beside the "-mabi=" and the "-32", "-n32" and
"-64" options should change the default ABI. 

>     (c) The code takes no account of the -mgp32 option.  "-mips4 -mgp32"
> 	will set the ABI to n64 without complaint, but generate odd code.
> 	o32 would be a more sensible choice, especially in cases where
> 	o32 is the default anyway.

 As above -- "-mips4" shouldn't change the ABI.  The "-mgp32" option seems
redundant, but it may equally well be an alias for "-mabi=o32".

>     (d) GAS 2.12 selects o64 (not n64) for -mips3 and -mips4.
> 
>     The proposed new rule is:
> 
>     (i) If the default ABI requires 32-bit registers [o32 only] then
> 	switch to o64 when generating 64-bit code.

 Hmm, how can you enable generating 64-bit code differently from selecting
the "n32" or the "64" ABI? 

>     (ii) If the default ABI requires 64-bit registers [o64, n32 and 64]
> 	 then switch to o32 when generating 32-bit code.
> 
>     Here, "generating X-bit code" takes into account the ISA and
>     -mgp32 option.

 For "-mgp32" -- see above.  And the "-mabi=o32" case is obvious.

>     For (i), o64 seems a better choice than n64.  Historical precedent
>     might be one reason to keep n64, but GAS prior to 2.12 didn't support
>     it and (like (d) says) gas 2.12 would assume you meant o64 instead
>     of n64.  So I can't see the n64 choice would ever have worked
>     well when using GAS.
> 
>     Choosing o64 shouldn't hurt mips-sgi-irix6.  Since its default ABI
>     is n32, (i) would mean you still get n32 code after passing -mips3
>     or -mips4.  You can switch to n64 using -mabi=64 in the usual way.

 As I stated, the best approach I can see is not to switch the ABI
implicitly. 

> (4) The code to infer an ISA from an ABI is:
[...]
>     Proposed rule in this case:
> 
>     (i) If the default architecture is 64-bit, -mabi=32 selects
> 	32-bit registers, but keeps the current architecture.
> 
>     (ii) If the default architecture is MIPS I or MIPS II, selecting
> 	 a 64-bit ABI will switch to MIPS III.
> 
>     (iii) If the default architecture is MIPS 32, selecting a 64-bit
> 	  ABI will switch to MIPS 64.

 Agreed.

> With (5), it's no longer necessary for GAS to check the ABI in
> the HAVE_32BIT_* macros, since the register size is always set.
> That means we can remove the ABI field from mips_opts.  Also, the
> new error checking means we can get rid of the ABI-killing code
> for -mgp32, -mgp64 and -mfp32:
> 
>     case OPTION_GP32:
>       file_mips_gp32 = 1;
>       if (mips_opts.abi != O32_ABI)
> 	mips_opts.abi = NO_ABI;
>       break;
> 
> This code seems suspect anyway: it's order-dependent, it silently
> ignores incompatible options, and it means we ignore "-mabi=eabi" if
> followed by "-mgp32" (despite it being a valid combination).

 Well, the intent seems valid (certain sets of options make non-conforming
files to be generated), but the check is incomplete.  Note the ABI setting
gets propagated to the ELF header of a generated file, so both the ABI
field and the ABI invalidation code like above should probably remain in
place.

> I'd prefer to choose the default CPU in configure: that way, we'd
> get a compile-time error over missing entries, plus we can use globs.

 Definitely.

 Everything else, I basically agree.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 10:16 RFC & patch: Rework MIPS command-line handling Richard Sandiford
  2002-07-12 11:39 ` Maciej W. Rozycki
@ 2002-07-12 11:46 ` Eric Christopher
  2002-07-12 12:46   ` Maciej W. Rozycki
                     ` (2 more replies)
       [not found] ` <mailpost.1026493441.14222@news-sj1-1>
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-12 11:46 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils, macro


> One part needs the other, really.  If the GCC patch is OK, I was
> hoping to apply it before 3.2.  The GAS stuff is probably too
> invasive for 2.13, though.
> 
> Thoughts?
> 

I obviously approve of the patch since we've had a lot of long
conversations about it :)

I'd like to see the gas bits in 2.13 so that it can coincide with the
next gcc release as well since we're trying to keep things as close as
possible.

Macej said the following:

>I'd prefer to select the default ABI at the configure time, from the
>target triplet ideally.  E.g. I use a local patch that select the 64
>ABI as the default for binutils if configuring for mips64*-*-linux*. 
>The same is set in the specs file for gcc for this target.

This is only particularly convenient for the hosted toolchains, and I
don't think I want to get into the habit of splitting things between
OSes and embedded toolchains.

> Hmm, what is "o64"?

A 64-bit extension of o32 for use with 64-bit processors. It has been
around for a long time now. Originally designed by Jim Wilson afaik.

>As I stated, the best approach I can see is not to switch the ABI
>implicitly. 

This is probably only convenient with hosted toolchains. Also, many
people are accustomed to the toolchain deciding ABI for them. Also, the
historical precedent (not always something to look at, but...) of the
SGI compiler switches ABI based on -mipsX switch as well.

>Well, the intent seems valid (certain sets of options make
>non-conforming files to be generated), but the check is incomplete. 
>Note the ABI setting gets propagated to the ELF header of a generated
>file, so both the ABI field and the ABI invalidation code like above
>should probably remain in place.

Some sort of error checking should be there, that's part of what we get
with Richard's new patch. The old error checking was well.. error prone
and not in any way marginally complete.


-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 11:39 ` Maciej W. Rozycki
@ 2002-07-12 12:28   ` Paul Koning
  2002-07-15  4:50   ` Richard Sandiford
  1 sibling, 0 replies; 97+ messages in thread
From: Paul Koning @ 2002-07-12 12:28 UTC (permalink / raw)
  To: macro; +Cc: rsandifo, gcc-patches, binutils

>>>>> "Maciej" == Maciej W Rozycki <macro@ds2.pg.gda.pl> writes:

 Maciej> Hmm, what is "o64"?

That's the (unofficial?) name for "like o32 but with 64 bit
registers".  In other words, argument passing as with o32, but
registers are 64 bits and long long data goes in one register rather
than in a register pair.  mips3 opcodes for 64-bit operations are
used. 

This is an important case for embedded systems, which often need the
performance benefits of 64 bit operations.  N32 would be a good answer
except that it hasn't been available in the past, while o64 has been.

       paul

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 11:46 ` Eric Christopher
@ 2002-07-12 12:46   ` Maciej W. Rozycki
  2002-07-12 18:16     ` Eric Christopher
                       ` (2 more replies)
       [not found]   ` <mailpost.1026499181.16972@news-sj1-1>
  2002-07-14 10:53   ` Thiemo Seufer
  2 siblings, 3 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-12 12:46 UTC (permalink / raw)
  To: Eric Christopher; +Cc: Richard Sandiford, gcc-patches, binutils

On 12 Jul 2002, Eric Christopher wrote:

> I obviously approve of the patch since we've had a lot of long
> conversations about it :)
> 
> I'd like to see the gas bits in 2.13 so that it can coincide with the
> next gcc release as well since we're trying to keep things as close as
> possible.

 For me it's obviously OK -- if any problems arise we still have some time
before 2.13 to fix them.

> >I'd prefer to select the default ABI at the configure time, from the
> >target triplet ideally.  E.g. I use a local patch that select the 64
> >ABI as the default for binutils if configuring for mips64*-*-linux*. 
> >The same is set in the specs file for gcc for this target.
> 
> This is only particularly convenient for the hosted toolchains, and I
> don't think I want to get into the habit of splitting things between
> OSes and embedded toolchains.

 Still I believe that would be more convenient.  It would be simply more
intuitive to have binutils default to the ABI that gcc uses by default,
even though direct invoking of `as' is generally considered unsafe and the
gcc driver may select the desired default ABI explicitly like it does e.g.
for the endianness. 

 I don't think how settings for e.g. mips64*-*-linux* would affect any
embedded target if implemented correctly -- each interested party might
set the default as desired. 

> > Hmm, what is "o64"?
> 
> A 64-bit extension of o32 for use with 64-bit processors. It has been
> around for a long time now. Originally designed by Jim Wilson afaik.

 With 32-bit addresses, I assume, as relocations used for o32 don't fit
64-bit addressing well, right?  If so, that's the same as o32 from the
binutils' point of view -- only gcc would generate different code. 

> >As I stated, the best approach I can see is not to switch the ABI
> >implicitly. 
> 
> This is probably only convenient with hosted toolchains. Also, many
> people are accustomed to the toolchain deciding ABI for them. Also, the
> historical precedent (not always something to look at, but...) of the
> SGI compiler switches ABI based on -mipsX switch as well.

 How can you guess an ABI from anything else?  If I pass the "-march=4000"
option, then which ABI do I mean?  If I pass "-mips4" for conditional
moves, then why should I add "-32" to keep the ABI unchanged?  OK, if done
carefully, the guess may probably be made harmless to uninterested parties
-- I'll have to study the proposed changes thorougly to decide if the new
code does it in an acceptable way.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 12:46   ` Maciej W. Rozycki
@ 2002-07-12 18:16     ` Eric Christopher
       [not found]       ` <mailpost.1026512166.22848@news-sj1-1>
                         ` (2 more replies)
       [not found]     ` <mailpost.1026503036.18648@news-sj1-1>
  2002-07-14 11:22     ` Thiemo Seufer
  2 siblings, 3 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-12 18:16 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Richard Sandiford, gcc-patches, binutils


>  Still I believe that would be more convenient.  It would be simply more
> intuitive to have binutils default to the ABI that gcc uses by default,
> even though direct invoking of `as' is generally considered unsafe and the
> gcc driver may select the desired default ABI explicitly like it does e.g.
> for the endianness. 
> 
>  I don't think how settings for e.g. mips64*-*-linux* would affect any
> embedded target if implemented correctly -- each interested party might
> set the default as desired. 
> 

I think you should give an example of what you mean. I don't see how
this is being affected by what's going in. I _think_ what you talking
about is having gas be absolutely dumb. Have gcc pass whatever options
it believes that it needs and let users of gas need to pass _everything_
they want on the command line - otherwise default to the configured
values?


>  With 32-bit addresses, I assume, as relocations used for o32 don't fit
> 64-bit addressing well, right?  If so, that's the same as o32 from the
> binutils' point of view -- only gcc would generate different code. 
> 

You'll notice that both gcc and binutils are in this discussion ;)


>  How can you guess an ABI from anything else?  If I pass the "-march=4000"
> option, then which ABI do I mean?  If I pass "-mips4" for conditional
> moves, then why should I add "-32" to keep the ABI unchanged?  OK, if done
> carefully, the guess may probably be made harmless to uninterested parties
> -- I'll have to study the proposed changes thorougly to decide if the new
> code does it in an acceptable way.

1) -march=4000
  This will be a) ABI by default if it was configured with a compatible
abi. The "next compatible" abi if not. An idea was to warn if we had to
change the ABI. I don't know what people think about this - I do know
that many people get testy if new warnings are produced.

2) -mips4 -32
  This won't work anyhow. This will produce an error.

I'll accept any feedback. Other than conceivably making gas
non-intuitive (which is something i've also heard from Daniel), I can't
see any other way for a reasonable set of command line options.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found] ` <mailpost.1026493441.14222@news-sj1-1>
@ 2002-07-13  0:40   ` cgd
  2002-07-15  5:07     ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-13  0:40 UTC (permalink / raw)
  To: rsandifo; +Cc: gcc-patches, binutils

At Fri, 12 Jul 2002 17:04:01 +0000 (UTC), "Richard Sandiford" wrote:
> - GAS and GCC didn't have quite the same -march arguments.  For
>   example, GCC accepts -march=r4kc, but GAS insists on -march=4kc.
>   To avoid that sort of thing in future, I've written a function
>   that tries all the variations, using a table of just the
>   "canonical" names.

accepting "r4kc" etc., would appear to be a bug w/ with GCC
implementation.  I wouldn't suggest propagating it, since it does
cause confusion with "r4000" (which people think of as 'r4k').


> I'd prefer to choose the default CPU in configure: that way, we'd
> get a compile-time error over missing entries, plus we can use globs.

yay.


> Before 2.12, we only set EF_MIPS_ABI when -mabi was given on
> the command line.  Since EF_MIPS_ABI is a GNU extension, the
> onus seems to be on proving that it's safe to use it by default,
> rather than the other way about.  So the patch uses NO_ABI as
> the default for all configurations, but leaves open the possibility
> of setting the default to something else on a per-configuration
> basis.

So, in the absence of EF_MIPS_ABI, what is a sane, compact code
fragment which will reliably determine which ABI is in use?  It's
important to have such a thing.

There's still an argument to be had which says "nobody else is doing
the right thing here, if we need binary ABI marking we should do it
and encourage others to follow suit," e.g. has happened w/ the arch
markings.


some specific comments about the patch:

i didn't really look carefully at the gas changes.  I suspect that
they'll break our firmware like the last set of ABI-related changes
did, but, well, assuming they pass all of the existing test cases (w/
the one changed as you did), it shouldn't be too bad.  8-)


> ! @item -mips32
> ! @opindex mips32
> ! Equivalent to @samp{-march=r4kc}.
>   
> ! @item -mips64
> ! @opindex mips64
> ! Equivalent to @samp{-march=r5kc}.

again, the proper names of these cores as far as i'm aware (see MIPS
web pages) are MIPS32 4Kc and MIPS64 5Kc.  I.e., the 'r' is really
truly incorrect here, unlike for the R4000 which was really called the
R4000.

(same for 20kc, btw.)


> + /* This array must have the same order as enum processor_type.  */
> + static const struct mips_processor mips_processors[] = {
> +   { "default", 0, 1 },
> +   { "r3000", "_R3000", 1 },
> +   { "r3900", "_R3900", 1 },
> +   { "r6000", "_R6000", 2 },
> +   { "r4000", "_R4000", 3 },
> +   { "vr4100", "_R4100", 3 },
> +   { "vr4300", "_R4300", 3 },
> +   { "r4600", "_R4600", 3 },
> +   { "r4650", "_R4650", 3 },
> +   { "vr5000", "_R5000", 4 },
> +   { "r8000", "_R8000", 4 },
> +   { "r4kc", "_R4KC", 32 },
> +   { "r5kc", "_R5KC", 64 },
> +   { "r20kc", "_R20KC", 64 }
> + };

OK, assuming that i'm seeing all of the uses of these, disagree on a
couple of grounds:

* some of these are things which implementations (i.e., existing
  systems) may have already come to define.  IMO they need more
  letters.

* we should also be providing a predefine for tune.  Ideally what i'd
  like to see is something like:

	_MIPS_ARCH=_PROCESSOR_FOO
	_MIPS_TUNE=_PROCESSOR_BAR

  then internally define _PROCESSOR_FOO and _PROCESSOR_BAR to have
  unique numbers internally and only add as defines the ones which are
  used.


So long as you avoid 0, this allows you to do useful, sane things,
e.g.:

	#if ((_MIPS_ISA == 4) || (_MIPS_ARCH == _PROCESSOR_SPECIAL)) && \
	    (_MIPS_TUNE != _PROCESSOR_BROKEN)

and:

	switch (_MIPS_TUNE) {
#ifdef _PROCESSOR_X
	case _PROCESSOR_X:
		asm(...);
		break;
#endif
#ifdef _PROCESSOR_Y
	case _PROCESSOR_Y:
		asm(...);
		break;
#endif
	default:
		unoptimized_code();
		break;
	}

Personally, I find that to be a prettier and _much much more useful_
idiom than something _MIPS_ARCH_FOO, _MIPS_TUNE_FOO.

Finally, for the 'print a number but don't necessarily say what it is'
crowd, it lets you encode the arch/tune values in the program in a
fail-safe way that a code builder w/ the compiler source can later use
(e.g. after a bug report) to figure out which arch/tune was used.
(can't do that with _MIPS_ARCH_FOO, since what if the one that's
define is one you don't know about.  with something like described
above, it's always an integer.)

In any case, you really do need longer names for most of those IMO.


> + /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
> +    with a final "000" replaced by "k".  Ignore case.

Oi, this is really going to exacerbate 4kc vs r4k problems if you
allow the 4kc to be called the r4kc!


I may have missed some things, too.  8-)



chris

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]   ` <mailpost.1026499181.16972@news-sj1-1>
@ 2002-07-13  0:42     ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-13  0:42 UTC (permalink / raw)
  To: echristo; +Cc: Richard Sandiford, gcc-patches, binutils, macro

At Fri, 12 Jul 2002 18:39:41 +0000 (UTC), "Eric Christopher" wrote:
> Macej said the following:
> 
> >I'd prefer to select the default ABI at the configure time, from the
> >target triplet ideally.  E.g. I use a local patch that select the 64
> >ABI as the default for binutils if configuring for mips64*-*-linux*. 
> >The same is set in the specs file for gcc for this target.
> 
> This is only particularly convenient for the hosted toolchains, and I
> don't think I want to get into the habit of splitting things between
> OSes and embedded toolchains.

it may only be particularly convenient for them but:

a) it really is quite lame to have to name a specific ABI on the
command line when that's the default used for the platform.

b) i believe that is a fair fraction of the users...

Personally, I think the target triple should be able to select "the
rest" of the ABI, just as it currently selects part of the default ABI
(e.g. soft-float).




cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]     ` <mailpost.1026503036.18648@news-sj1-1>
@ 2002-07-13  0:52       ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-13  0:52 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Eric Christopher, Richard Sandiford, gcc-patches, binutils

At Fri, 12 Jul 2002 19:43:56 +0000 (UTC), "Maciej W. Rozycki" wrote:
>  With 32-bit addresses, I assume, as relocations used for o32 don't fit
> 64-bit addressing well, right?  If so, that's the same as o32 from the
> binutils' point of view -- only gcc would generate different code. 

32-bit or 64-bit addresses (-mlong64 or not).

obviously you only get 32-bit addresses (sign extended to 64) in your
object files, but e.g. you might strongly want 64-bit addresse
constants for e.g. accessing devices in xkphys.


cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]       ` <mailpost.1026512166.22848@news-sj1-1>
@ 2002-07-13 19:56         ` cgd
  2002-07-15  5:39           ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-13 19:56 UTC (permalink / raw)
  To: echristo; +Cc: Maciej W. Rozycki, Richard Sandiford, gcc-patches, binutils

At Fri, 12 Jul 2002 22:16:06 +0000 (UTC), "Eric Christopher" wrote:
> >  How can you guess an ABI from anything else?  If I pass the "-march=4000"
> > option, then which ABI do I mean?  If I pass "-mips4" for conditional
> > moves, then why should I add "-32" to keep the ABI unchanged?  OK, if done
> > carefully, the guess may probably be made harmless to uninterested parties
> > -- I'll have to study the proposed changes thorougly to decide if the new
> > code does it in an acceptable way.
> 
> 1) -march=4000
>   This will be a) ABI by default if it was configured with a compatible
> abi. The "next compatible" abi if not. An idea was to warn if we had to
> change the ABI. I don't know what people think about this - I do know
> that many people get testy if new warnings are produced.
>
> 2) -mips4 -32
>   This won't work anyhow. This will produce an error.
> 
> I'll accept any feedback. Other than conceivably making gas
> non-intuitive (which is something i've also heard from Daniel), I can't
> see any other way for a reasonable set of command line options.

So, i don't know how much of a problem it would be, but at least
erroring with various ABI specs might play havoc with multilibs.  (in
particular, you'd then need all sorts of excludes...)

actually, given that there are now multiple ways to specify everything
(arch, cpu, etc.), it would seem that you need to have code, rather
than option string matching, determine which multilib you're currently
building or should be using, eh?

i.e.:

say mips-elf builds multilibs for -mips1/-mips3...

you want -march=r4000 if specified on the command line to get -mips3.
actually, you also want -march=r5000 to get -mips3, if -mips1 and
-mips3 are your only choices...

You can do some of this with MULTILIB_MATCHES, but you can't do
"fall back" at all can you.  So i guess MULTILIB_MATCHES has to learn
all of the arch and ISA names?  oi.

and if somebody wants to make that better, or wants to allow "fall
back" to best available lib, they have to hack the insides of the
multilib selection code so that it uses something other than specs...


(BTW, i think the compiler shouldn't _have_ to pass the assembler the
correct default ABI flag, i.e. so that code built with 'as' w/o flags
works right by default...  but I think it should be passing the
default or non-default ABI-related flags at all times "just to be
safe" from a badly-built as.  But that goes into the rabbit hole of
killing specs for invocation of as, doesn't it...)


OK, tally a few more points for "specs must die."  8-)



chris

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 10:16 RFC & patch: Rework MIPS command-line handling Richard Sandiford
                   ` (2 preceding siblings ...)
       [not found] ` <mailpost.1026493441.14222@news-sj1-1>
@ 2002-07-14 10:43 ` Thiemo Seufer
  2002-07-15  3:40   ` Richard Sandiford
  2002-07-18 12:44 ` [Revised patch] " Richard Sandiford
  4 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-14 10:43 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

Richard Sandiford wrote:
> [cross-posted to binutils & gcc]
> 
> The patch below tries to make MIPS GCC and GAS more consistent in
> the way they handle command-line options. This message is really a
> RFC on whether it's the right way to go, although the patch has
> been tested in the usual way.
> 
> I'll use numbers to break things up...
> 
> (1) The main discrepancy I see with the current set-up is in the handling
>     of -march.  In GAS, it fully controls the ISA, much like -mipsN does,
>     but in GCC it only controls the use of processor-specific extensions.
>     So, for example,
> 
> 	mips-elf-as -march=r8000
> 
>     selects MIPS IV code but
> 
> 	mips-elf-gcc -march=r8000
> 
>     selects MIPS I code.  I'd like to make it so that both cc1 and gas treat
>     -march like a more descriptive version of -mipsN.  -march=r8000 would
>     be equivalent to -mips4, -march=r4000 would be equivalent to -mips3,
>     and so on.

I agree, -mipsN should be an alias for the equivalent -march=FOO.
Please note that the -mipsN options should IMHO be obsoleted:

	- They are asymmetric because all of them can be replaced by
	  -march=FOO, but there are -march=FOO without -mipsN equivalents
	  
	- They are confusing because it's often guessed they do ISA
	  selection, but they actually do CPU selection, which is quite
	  a difference for GAS. (For current GCC they attempt to do ABI
	  selection, too)
	
	- As CPU aliases they can allow opcodes which aren't available
	  on other ISA-conforming CPUs.

> (2) Traditionally, GCC has tried to infer sensible things from a sparse
>     command line.  Passing -mipsN would select a suitable ABI for ISA N,
>     passing -mabi=FOO would select a suitable ISA for ABI FOO, and so on.
>     Lately, gas has done the same thing, although the assumptions are
>     slightly different (more later).
> 
>     If -march is going to act like -mipsN, then it ought to choose the
>     ABI as well.

I don't see a good reason to mix ISA and ABI selection. AFAICS it's
enough to

	- choose the lowest ISA required for a selected ABI

	- use the 'highest' ABI for any selected ISA

GCC and GAS have different requirements: For GCC it's sensible to guess
ISA from ABI and vice versa because it usually handles ABI-conforming
code. For GAS, the ABI selection is not that useful because assembly
normally isn't ABI-conformant (which would be limited to opcodes covered
in the respective ISA).

>     For example, if "mips64-elf-gcc -mips1" chooses o32 code
>     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.

This may break the 'No ABI' case which means default ABI plus e.g.
-mlong64 as it is used in the embedded world. OTOH, basing this usage
on o32/o64 in future is probably a good idea.

[snip]
>     The proposed new rule is:
> 
>     (i) If the default ABI requires 32-bit registers [o32 only] then
> 	switch to o64 when generating 64-bit code.
> 
>     (ii) If the default ABI requires 64-bit registers [o64, n32 and 64]
> 	 then switch to o32 when generating 32-bit code.
> 
>     Here, "generating X-bit code" takes into account the ISA and
>     -mgp32 option.
> 
>     For (i), o64 seems a better choice than n64.  Historical precedent
>     might be one reason to keep n64,

AFAICS n64 isn't a good idea anyway because it's less performant than
n32 and only needed for large memory applications. n32 still needs some
work to get usable, so o64 is the best choice for now.

>     but GAS prior to 2.12 didn't support
>     it and (like (d) says) gas 2.12 would assume you meant o64 instead
>     of n64.  So I can't see the n64 choice would ever have worked
>     well when using GAS.

Currently it works only for non-PIC and has little testing.

>     Choosing o64 shouldn't hurt mips-sgi-irix6.  Since its default ABI
>     is n32, (i) would mean you still get n32 code after passing -mips3
>     or -mips4.  You can switch to n64 using -mabi=64 in the usual way.
> 
> (4) The code to infer an ISA from an ABI is:
> 
> 	/* 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;
> 	  }
> 
>     Problems here:
> 
>     (a) It seems counter-intuitive for -mabi to override the default
>         architecture even when that default was compatible.  For
>         example, "mipsisa32-elf-gcc -mabi=o32" would generate
> 	MIPS I code rather than MIPS 32 code.

Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
The same should be true for MIPS IV opcodes in n32 code.

>     (b) MIPS III and MIPS IV processors can run o32 too, and you can
> 	sometimes get the benefit of extra instructions	(like
> 	conditional moves, and sometimes multiply-add).  It seems
> 	more appropriate to generate 32-bit code for the default
> 	architecture when passed -mabi=o32, rather than blindly
> 	switching to MIPS I.

Same problem as above.

>     (b) There seems no good reason why we should choose MIPS IV over
> 	MIPS III for n64.  People have complained: see PR #5938.

SGI's n64 ABI is IIRC only available on MIPS IV machines, so they
have no problem to generally prefer MIPS IV for it. Maybe GNU should
do different.

>     Proposed rule in this case:
> 
>     (i) If the default architecture is 64-bit, -mabi=32 selects
> 	32-bit registers, but keeps the current architecture.

This would mean the User can use

	gcc -mabi=32

and then he gets code which might _not_ run on o32 conformant
Systems. This defeats the idea of having an ABI.

[snip]
> 	(OPTION_FP64): New.
> 	(md_longopts): Add -mfp64, remove -mcpu.

There's little reason to have -m[gf]p64, see
http://sources.redhat.com/ml/binutils/2001-07/msg00417.html


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 11:46 ` Eric Christopher
  2002-07-12 12:46   ` Maciej W. Rozycki
       [not found]   ` <mailpost.1026499181.16972@news-sj1-1>
@ 2002-07-14 10:53   ` Thiemo Seufer
  2002-07-14 23:13     ` Maciej W. Rozycki
  2 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-14 10:53 UTC (permalink / raw)
  To: Eric Christopher; +Cc: Richard Sandiford, gcc-patches, binutils, macro

Eric Christopher wrote:
[snip]
> >I'd prefer to select the default ABI at the configure time, from the
> >target triplet ideally.  E.g. I use a local patch that select the 64
> >ABI as the default for binutils if configuring for mips64*-*-linux*. 
> >The same is set in the specs file for gcc for this target.

I'd prefer this, too. My local patch for mips64*-*-linux* uses n32
as default because n64 is only useful for OS kernels and WRT userland
for large memory machines.

> This is only particularly convenient for the hosted toolchains, and I
> don't think I want to get into the habit of splitting things between
> OSes and embedded toolchains.

AFAICS this is done in the target specific code, so it is already
splitted.

[snip]
> This is probably only convenient with hosted toolchains. Also, many
> people are accustomed to the toolchain deciding ABI for them. Also, the
> historical precedent (not always something to look at, but...) of the
> SGI compiler switches ABI based on -mipsX switch as well.

And then they invented the (undocumented) -mabi switch, I assume
because automatic switching didn't work particularily well.

> >Well, the intent seems valid (certain sets of options make
> >non-conforming files to be generated), but the check is incomplete. 
> >Note the ABI setting gets propagated to the ELF header of a generated
> >file, so both the ABI field and the ABI invalidation code like above
> >should probably remain in place.
> 
> Some sort of error checking should be there, that's part of what we get
> with Richard's new patch. The old error checking was well.. error prone
> and not in any way marginally complete.

It was simply a hack to make things a little bit better without breaking
backward compatibility.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 12:46   ` Maciej W. Rozycki
  2002-07-12 18:16     ` Eric Christopher
       [not found]     ` <mailpost.1026503036.18648@news-sj1-1>
@ 2002-07-14 11:22     ` Thiemo Seufer
  2 siblings, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-14 11:22 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Eric Christopher, Richard Sandiford, gcc-patches, binutils

Maciej W. Rozycki wrote:
[snip]
> > A 64-bit extension of o32 for use with 64-bit processors. It has been
> > around for a long time now. Originally designed by Jim Wilson afaik.
> 
>  With 32-bit addresses, I assume, as relocations used for o32 don't fit
> 64-bit addressing well, right?  If so, that's the same as o32 from the
> binutils' point of view -- only gcc would generate different code. 

GAS sets the o64 ELF header flag, that's all. Everything else is done
by GCC.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 18:16     ` Eric Christopher
       [not found]       ` <mailpost.1026512166.22848@news-sj1-1>
@ 2002-07-14 11:38       ` Thiemo Seufer
  2002-07-15  1:03       ` Maciej W. Rozycki
  2 siblings, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-14 11:38 UTC (permalink / raw)
  To: Eric Christopher
  Cc: Maciej W. Rozycki, Richard Sandiford, gcc-patches, binutils

Eric Christopher wrote:
[snip]
> >  How can you guess an ABI from anything else?  If I pass the "-march=4000"
> > option, then which ABI do I mean?  If I pass "-mips4" for conditional
> > moves, then why should I add "-32" to keep the ABI unchanged?  OK, if done
> > carefully, the guess may probably be made harmless to uninterested parties
> > -- I'll have to study the proposed changes thorougly to decide if the new
> > code does it in an acceptable way.
> 
> 1) -march=4000
>   This will be a) ABI by default if it was configured with a compatible
> abi.

Parse error. Which ABI would this mean for e.g.

	mips-linux-gcc -march=4000

> The "next compatible" abi if not. An idea was to warn if we had to
> change the ABI. I don't know what people think about this - I do know
> that many people get testy if new warnings are produced.
> 
> 2) -mips4 -32
>   This won't work anyhow. This will produce an error.

Allowing MIPS IV opcodes in otherwise o32 conformant code is useful.

> I'll accept any feedback. Other than conceivably making gas
> non-intuitive (which is something i've also heard from Daniel), I can't
> see any other way for a reasonable set of command line options.

-mabi=FOO for strictly ABI-conforming code.
-march=BAR to allow processor-specific opcodes, sacrifice ABI conformance.
-mtune=BAZ to schedule for a non-default CPU.
-mgp32/-mfp32 to restrict register sizes. This may issue a warning if an
	user specified ABI is incompatible. Only embedded code should
	need these.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-14 10:53   ` Thiemo Seufer
@ 2002-07-14 23:13     ` Maciej W. Rozycki
  0 siblings, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-14 23:13 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Eric Christopher, Richard Sandiford, gcc-patches, binutils

On Sun, 14 Jul 2002, Thiemo Seufer wrote:

> > >I'd prefer to select the default ABI at the configure time, from the
> > >target triplet ideally.  E.g. I use a local patch that select the 64
> > >ABI as the default for binutils if configuring for mips64*-*-linux*. 
> > >The same is set in the specs file for gcc for this target.
> 
> I'd prefer this, too. My local patch for mips64*-*-linux* uses n32
> as default because n64 is only useful for OS kernels and WRT userland
> for large memory machines.

 Or for testing 64-bit cleanness of software, which usually helps
portability.  I'm particularly fond of running a 64-bit userland with
binaries linked at a base address of 0x120000000 (the default for
Alpha/Linux) or similar.  This way pointer crops manifest immediately. 
The performance hit, I may live with.  Hence my local patch defaults to
64.  It would be nice to be able to select the preference at the configure
time.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 18:16     ` Eric Christopher
       [not found]       ` <mailpost.1026512166.22848@news-sj1-1>
  2002-07-14 11:38       ` Thiemo Seufer
@ 2002-07-15  1:03       ` Maciej W. Rozycki
  2002-07-15  3:13         ` Mark D. Baushke
  2 siblings, 1 reply; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-15  1:03 UTC (permalink / raw)
  To: Eric Christopher; +Cc: Richard Sandiford, gcc-patches, binutils

On 12 Jul 2002, Eric Christopher wrote:

> >  I don't think how settings for e.g. mips64*-*-linux* would affect any
> > embedded target if implemented correctly -- each interested party might
> > set the default as desired. 
> 
> I think you should give an example of what you mean. I don't see how
> this is being affected by what's going in. I _think_ what you talking

 I mean, if I configure for e.g. mips64*-*-linux*, I want e.g. 
"-march=4000 -mabi=64" be the default and with mips*-*-linux*, I want e.g.
"-march=3000 -mabi=32".  Someone else might want to configure for
mips64*-something-else and get "-march=8000 -mabi=n32" or configure for
mips*-something-else and get "-march=4000 -mabi=32".  The defaults
shouldn't affect one another. 

> about is having gas be absolutely dumb. Have gcc pass whatever options
> it believes that it needs and let users of gas need to pass _everything_
> they want on the command line - otherwise default to the configured
> values?

 I'm simply unsure if guessing any non-defaults is good to have.  E.g. 
with the defaults as proposed above I don't think the ABI should be
changed if "-march=R5000" was specified.  For "-march=R3000" it would be
sane to bail out with an error message for the 64-bit ABIs instead of
silently switching to "-mabi=32" which could lead to a bad object file to
be generated (which you'd not notice until after a long period, since the
file is put in an ar archive an not pulled most of the time, for example). 

> >  How can you guess an ABI from anything else?  If I pass the "-march=4000"
> > option, then which ABI do I mean?  If I pass "-mips4" for conditional
> > moves, then why should I add "-32" to keep the ABI unchanged?  OK, if done
> > carefully, the guess may probably be made harmless to uninterested parties
> > -- I'll have to study the proposed changes thorougly to decide if the new
> > code does it in an acceptable way.
> 
> 1) -march=4000
>   This will be a) ABI by default if it was configured with a compatible
> abi. The "next compatible" abi if not. An idea was to warn if we had to
> change the ABI. I don't know what people think about this - I do know
> that many people get testy if new warnings are produced.

 Let's assume I have a 32-bit MIPS system running on the R4000 CPU and the
toolchain is configured to default to "-mabi=32".  And I want to generate
optimal binaries.  So I add "-march=4000 -mtune=4000" to flags for the
toolchain.  Should I have to add "-mabi=32" explicitly?

> 2) -mips4 -32
>   This won't work anyhow. This will produce an error.

 Why?  This is a valid configuration.  I may have a 32-bit R8000 system
which is, again, configured to default to "-mabi=32".  And I want to
generate code optimized for this exact CPU (including the "movn" and
"movz" instructions), not caring about backward compatibility.  Is it
unreasonable?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  1:03       ` Maciej W. Rozycki
@ 2002-07-15  3:13         ` Mark D. Baushke
  2002-07-15  6:40           ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: Mark D. Baushke @ 2002-07-15  3:13 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Eric Christopher, Richard Sandiford, gcc-patches, binutils

Hi Maciej,

Your comments also make a great deal of sense to me.

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> 
> > 2) -mips4 -32
> >   This won't work anyhow. This will produce an error.
> 
>  Why?  This is a valid configuration.  I may have a 32-bit R8000 system
> which is, again, configured to default to "-mabi=32".  And I want to
> generate code optimized for this exact CPU (including the "movn" and
> "movz" instructions), not caring about backward compatibility.  Is it
> unreasonable?

It is not unreasonable to me. 

There are times when backward compatibility is not the issue.
For example, it is sometimes useful for an embedded target to utilize
those kind of configurations for performance reasons. 

Such an embedded target may want to utilize a 32bit pointer and still
have access to 64bit integers as well as access to cpu-specific
instructions that are normally not part of the ISA being used by the
rest of the code base. ISA and ABI should be able to be controlled
separately where possible. Right now it is a pain at times to need to
hack the assembler of some kernel source code to use, for example, 

   '.set mips32; ssnop; .set mips0' 

or 

   '.set mips64; dmtc0 $zero,$29,2; .set mips0' 

when the rest of the entire system is being compiled in -mips4. It is
much nicer to use '-EB -march=sb1250 -mabi=32' if that is what is needed
to get the elf32-bigmips format file desired.

Agreed that there are some combinations that could lead to a bad object
file being generated. Those combinations should probably generate a
warning (that becomes an error under -Werror).

IMO, a warning would be better than silently switching the -mabi=32 in
the case of an -march=R3000 arg on a toolchain that defaults to using a
64-bit ABI. It should only be an error if the user specifies -Werror
too. This is okay for the situation of not overriding all of the needed
defaults. It does not really cover the case of specifying incompatible
options on the command line.

What should be done in with a command line that specified -march=R3000
-mabi=64 ? Should it generate an error and bailout? Or should it also
just be a warning that gets promoted to error on -Werror?

	Thanks,
	-- Mark

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-14 10:43 ` Thiemo Seufer
@ 2002-07-15  3:40   ` Richard Sandiford
  2002-07-15  3:57     ` Mark D. Baushke
                       ` (3 more replies)
  0 siblings, 4 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-15  3:40 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: gcc-patches, binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> I agree, -mipsN should be an alias for the equivalent -march=FOO.
> Please note that the -mipsN options should IMHO be obsoleted:
>
> 	- They are asymmetric because all of them can be replaced by
> 	  -march=FOO, but there are -march=FOO without -mipsN equivalents

I'd guess the ISA levels are more well known than the processors we're
associating them with, so there's probably no harm in keeping them as
aliases, but...

> 	- They are confusing because it's often guessed they do ISA
> 	  selection, but they actually do CPU selection, which is quite
> 	  a difference for GAS. (For current GCC they attempt to do ABI
> 	  selection, too)

...agreed here.

> 	- As CPU aliases they can allow opcodes which aren't available
> 	  on other ISA-conforming CPUs.

Not sure what you mean.  Do you have any examples?

> I don't see a good reason to mix ISA and ABI selection. AFAICS it's
> enough to
> 
> 	- choose the lowest ISA required for a selected ABI
> 
> 	- use the 'highest' ABI for any selected ISA

I'm not sure what you mean by "mix" here.  Anyway, I don't think
it's a good idea to select the lowest ISA for an ABI.  If you have
a configuration that uses a particular CPU by default (let's say a
MIPS II one), specifying an ABI shouldn't "downgrade" to MIPS I.

If someone's using a MIPS II or higher toolchain to generate code
that must run on a MIPS I machine, it doesn't seem unreasonable
to ask them to say so explicitly.

> GCC and GAS have different requirements: For GCC it's sensible to guess
> ISA from ABI and vice versa because it usually handles ABI-conforming
> code. For GAS, the ABI selection is not that useful because assembly
> normally isn't ABI-conformant (which would be limited to opcodes covered
> in the respective ISA).

I agree that might be true for embedded configs.  But like Maciej
said, it could be useful to have a default ABI for hosted toolchains
like mips64-linux-gnu.  It seems reasonable that anyone using such
an assembler would be at least try to write ABI-conformant code.

So the way the GAS config stuff is structured, it will assume NO_ABI
by default, since that seems sensible for most embedded configs,
and won't lead to spurious "incompatible ABI" link failures.
Not setting EF_MIPS_ABI is also the historical behaviour.
There's then the option of overriding the NO_ABI default for
particular configurations.

> >     For example, if "mips64-elf-gcc -mips1" chooses o32 code
> >     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.
> 
> This may break the 'No ABI' case which means default ABI plus e.g.
> -mlong64 as it is used in the embedded world. OTOH, basing this usage
> on o32/o64 in future is probably a good idea.

I'm not sure how it could break things like that.  -mlong64 only
controls type sizes.

> >     (a) It seems counter-intuitive for -mabi to override the default
> >         architecture even when that default was compatible.  For
> >         example, "mipsisa32-elf-gcc -mabi=o32" would generate
> > 	MIPS I code rather than MIPS 32 code.
> 
> Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
> The same should be true for MIPS IV opcodes in n32 code.

Hmm... not sure why, but if it's related to...

> This would mean the User can use
> 
> 	gcc -mabi=32
> 
> and then he gets code which might _not_ run on o32 conformant
> Systems. This defeats the idea of having an ABI.

It sounds like you're saying that, because the original o32 systems were
MIPS I only, -mabi=32 should mean "generate MIPS I code" unless the user
says otherwise.  That's the current behaviour, but like I said above,
it seems strange to pick MIPS I regardless of the default processor.

> > 	(OPTION_FP64): New.
> > 	(md_longopts): Add -mfp64, remove -mcpu.
> 
> There's little reason to have -m[gf]p64, see
> http://sources.redhat.com/ml/binutils/2001-07/msg00417.html

One of the changes was that the default float register size would
be worked out from -mgp32, -mgp64, -msingle-float, etc.  That was
mostly for multilib convenience.  GAS can generate -mgp32 -mfp64
"no ABI" code, so we'd need the -mfp64 option then.  Why anyone
would use it, well, who knows?  But someone once went to a lot of
effort to make it work in GCC too (although it doesn't any more).

Anyway, it sounds like there's more support than I expected for
the idea of leaving the ABI unchanged unless the command line
says otherwise.  Which means the special treatment of -mgp32
might not be necessary after all...

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  3:40   ` Richard Sandiford
@ 2002-07-15  3:57     ` Mark D. Baushke
       [not found]       ` <mailpost.1026729642.18965@news-sj1-1>
       [not found]     ` <mailpost.1026728027.18467@news-sj1-1>
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 97+ messages in thread
From: Mark D. Baushke @ 2002-07-15  3:57 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Thiemo Seufer, gcc-patches, binutils

Richard Sandiford <rsandifo@redhat.com> writes:
> 
> > >     For example, if "mips64-elf-gcc -mips1" chooses o32 code
> > >     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.
> > 
> > This may break the 'No ABI' case which means default ABI plus e.g.
> > -mlong64 as it is used in the embedded world. OTOH, basing this usage
> > on o32/o64 in future is probably a good idea.
> 
> I'm not sure how it could break things like that.  -mlong64 only
> controls type sizes.

In MIPS I the -mlong64 also implies the use of register pairs right? 
Where in MIPS III, the -mlong64 implies the use of a single register.

If 'No ABI' is in use, would you be able to figure out if you are
linking between those two variants of -mlong64 compiled code?

	Curious,
	-- Mark

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-12 11:39 ` Maciej W. Rozycki
  2002-07-12 12:28   ` Paul Koning
@ 2002-07-15  4:50   ` Richard Sandiford
  2002-07-15 13:18     ` Thiemo Seufer
  2002-07-16  3:54     ` Maciej W. Rozycki
  1 sibling, 2 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-15  4:50 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, binutils

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> > (2) Traditionally, GCC has tried to infer sensible things from a sparse
> >     command line.  Passing -mipsN would select a suitable ABI for ISA N,
> >     passing -mabi=FOO would select a suitable ISA for ABI FOO, and so on.
> >     Lately, gas has done the same thing, although the assumptions are
> >     slightly different (more later).
> > 
> >     If -march is going to act like -mipsN, then it ought to choose the
> >     ABI as well.  For example, if "mips64-elf-gcc -mips1" chooses o32 code
> >     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.
> 
>  I'd prefer to select the default ABI at the configure time, from the
> target triplet ideally.  E.g. I use a local patch that select the 64 ABI
> as the default for binutils if configuring for mips64*-*-linux*.  The same
> is set in the specs file for gcc for this target.

Well, the GAS patch was written so that NO_ABI would be the default for
most configs, but that you could override it for particular target
triples where appropriate.  mips64-linux-gnu is probably a prime
candidate for that.

It might also be nice to have a --with-abi configure option,
although that's something we could add later...

> >     (b) Passing -mips3 to an n32 MIPS III config (e.g. mips-sgi-irix6)
> > 	will select n64, which seems counter-intuitive.
> 
>  Agreed, I think nothing beside the "-mabi=" and the "-32", "-n32" and
> "-64" options should change the default ABI. 

[And in a later message]

>  How can you guess an ABI from anything else?  If I pass the "-march=4000"
> option, then which ABI do I mean?  If I pass "-mips4" for conditional
> moves, then why should I add "-32" to keep the ABI unchanged?

The reason for -mgp32 is for consitency with EABIs.  If you
have a 32-bit EABI configuration like mipstx39-elf, does
-mips4 select 64-bit EABI code, or 32-bit EABI code?  The
first seems most natural to me, so the rule was: if you
select a 64-bit processor, you get 64-bit code, unless
you also select -mgp32.

In general, the main reason to keep the implicit ABI selection
is that that's what we've done before.  I didn't think there'd
be much support for dropping it entirely.

On the other hand, my main complaint with the current code is
that it changes the ABI even when you wouldn't expect it to.
If others agree that there should be no implicit ABI selection,
I'm happy to submit a revised version.

The main difficulty with dropping the ABI selection entirely
is: how do you select between the 32-bit and 64-bit versions
of the EABIs?  mipstx39-elf-gcc generates 32-bit EABI code
by default.  What happens if you select a 64-bit processor?
Options I can see:

1. Stick with the idea in the patch I sent.  Selecting a 64-bit
   processor would usually select the 64-bit EABI, but adding
   -mgp32 forces the 32-bit version.

2. Reverse of (1).  You get the 32-bit version of the EABI
   unless you use -mgp64.

3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
   the 32-bit version unless you use -mabi=eabi64.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-13  0:40   ` cgd
@ 2002-07-15  5:07     ` Richard Sandiford
       [not found]       ` <mailpost.1026733871.20742@news-sj1-1>
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-15  5:07 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

cgd@broadcom.com writes:
> At Fri, 12 Jul 2002 17:04:01 +0000 (UTC), "Richard Sandiford" wrote:
> > - GAS and GCC didn't have quite the same -march arguments.  For
> >   example, GCC accepts -march=r4kc, but GAS insists on -march=4kc.
> >   To avoid that sort of thing in future, I've written a function
> >   that tries all the variations, using a table of just the
> >   "canonical" names.
> 
> accepting "r4kc" etc., would appear to be a bug w/ with GCC
> implementation.  I wouldn't suggest propagating it, since it does
> cause confusion with "r4000" (which people think of as 'r4k').

OK.  I'll do it the other way round then, and stop gcc accepting
the 'r4kc', etc.

> > Before 2.12, we only set EF_MIPS_ABI when -mabi was given on
> > the command line.  Since EF_MIPS_ABI is a GNU extension, the
> > onus seems to be on proving that it's safe to use it by default,
> > rather than the other way about.  So the patch uses NO_ABI as
> > the default for all configurations, but leaves open the possibility
> > of setting the default to something else on a per-configuration
> > basis.
> 
> So, in the absence of EF_MIPS_ABI, what is a sane, compact code
> fragment which will reliably determine which ABI is in use?  It's
> important to have such a thing.

I hope the patch at least makes things better: gcc will never implicitly
choose an ABI except when switching between 32-bit and 64-bit code
generation.  So objects compiled with the same gcc are likely to be OK.
Not strong enough, I know, but even that isn't guaranteed at the moment.

> There's still an argument to be had which says "nobody else is doing
> the right thing here, if we need binary ABI marking we should do it
> and encourage others to follow suit," e.g. has happened w/ the arch
> markings.

The original idea was to turn the ABI flags on for specific targets
(as and when it seemed safe).  I guess one way of forcing the issue
would be to use them by default, but turn them off for configurations
that really don't want them.  There'd need to be some easy way of
unsetting an object's ABI flags.

> > + /* This array must have the same order as enum processor_type.  */
> > + static const struct mips_processor mips_processors[] = {
> > +   { "default", 0, 1 },
> > +   { "r3000", "_R3000", 1 },
> > +   { "r3900", "_R3900", 1 },
> > +   { "r6000", "_R6000", 2 },
> > +   { "r4000", "_R4000", 3 },
> > +   { "vr4100", "_R4100", 3 },
> > +   { "vr4300", "_R4300", 3 },
> > +   { "r4600", "_R4600", 3 },
> > +   { "r4650", "_R4650", 3 },
> > +   { "vr5000", "_R5000", 4 },
> > +   { "r8000", "_R8000", 4 },
> > +   { "r4kc", "_R4KC", 32 },
> > +   { "r5kc", "_R5KC", 64 },
> > +   { "r20kc", "_R20KC", 64 }
> > + };
> 
> OK, assuming that i'm seeing all of the uses of these, disagree on a
> couple of grounds:
> 
> * some of these are things which implementations (i.e., existing
>   systems) may have already come to define.  IMO they need more
>   letters.

I took my cue from R3000 and R4000, which were the standard before.
The table is just a mindless extension to the other processors.
How about zeroing out any macro entries that aren't appropriate?

> * we should also be providing a predefine for tune.  Ideally what i'd
>   like to see is something like:
> 
> 	_MIPS_ARCH=_PROCESSOR_FOO
> 	_MIPS_TUNE=_PROCESSOR_BAR
> 
>   then internally define _PROCESSOR_FOO and _PROCESSOR_BAR to have
>   unique numbers internally and only add as defines the ones which are
>   used.

I like it.  Probably a separate patch, though.  I'll try to come
up with something once the options stuff is over with.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-13 19:56         ` cgd
@ 2002-07-15  5:39           ` Richard Sandiford
  0 siblings, 0 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-15  5:39 UTC (permalink / raw)
  To: cgd; +Cc: echristo, Maciej W. Rozycki, gcc-patches, binutils

cgd@broadcom.com writes:
> say mips-elf builds multilibs for -mips1/-mips3...
> 
> you want -march=r4000 if specified on the command line to get -mips3.
> actually, you also want -march=r5000 to get -mips3, if -mips1 and
> -mips3 are your only choices...

And if you use -march=r5000 -mgp32, you want the -mips1 multilibs...

Not doing implicit ABI changes would make the multilibs easier in this
case.  Say we have -mabi=32/-mabi=o64.  If there was no implicit ABI
selection, you'd have to use -mabi=o64 on the command line to get o64
code, which would also mean you'd link against the o64 multlib.

That'd also be an argument in favour of -mabi=eabi64 and the like.

If there's only one way of setting the ABI (barring synonyms like
-32, which are easy to handle), then you're more likely to get
the right multilib.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  3:13         ` Mark D. Baushke
@ 2002-07-15  6:40           ` Richard Sandiford
  0 siblings, 0 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-15  6:40 UTC (permalink / raw)
  To: Mark D. Baushke
  Cc: Maciej W. Rozycki, Eric Christopher, gcc-patches, binutils

"Mark D. Baushke" <mdb@gnu.org> writes:
> IMO, a warning would be better than silently switching the -mabi=32 in
> the case of an -march=R3000 arg on a toolchain that defaults to using a
> 64-bit ABI. It should only be an error if the user specifies -Werror
> too.

If we issue a warning when implicitly changing ABI, I think we should
deprecate it too.  It's the kind of warning that would trigger for
every gcc invocation in a typical build.  I think most people would
shut it up by specifying the ABI explicitly.

> What should be done in with a command line that specified -march=R3000
> -mabi=64 ? Should it generate an error and bailout? Or should it also
> just be a warning that gets promoted to error on -Werror?

FWIW, I think it should be an error.  We'd have to ignore one option
or the other.  The patch I sent would give an error in this case, and
-mips1 -mabi=64 would give an error before the patch too.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]     ` <mailpost.1026728027.18467@news-sj1-1>
@ 2002-07-15 10:47       ` cgd
  2002-07-15 11:22         ` Thiemo Seufer
  2002-07-16  4:04         ` Maciej W. Rozycki
  0 siblings, 2 replies; 97+ messages in thread
From: cgd @ 2002-07-15 10:47 UTC (permalink / raw)
  To: rsandifo; +Cc: Thiemo Seufer, gcc-patches, binutils

At Mon, 15 Jul 2002 10:13:47 +0000 (UTC), "Richard Sandiford" wrote:
> Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> > I agree, -mipsN should be an alias for the equivalent -march=FOO.
> > Please note that the -mipsN options should IMHO be obsoleted:
> >
> > 	- They are asymmetric because all of them can be replaced by
> > 	  -march=FOO, but there are -march=FOO without -mipsN equivalents
> 
> I'd guess the ISA levels are more well known than the processors we're
> associating them with, so there's probably no harm in keeping them as
> aliases, but...

I actually think it's important to keep them.  In general, it's
quite desriable to be able to say, for instance:

"will run on any MIPS N CPU, but optimized for this particular CPU."

where, say, N == 1.  historically, the first part of that has been
caused by -mips1 (for N == 1), and people I think have come to expect
that.

I do think it's reasonable and probably desirable to support (can you
hear the maniacal laughing, too?):

	-march=mips1

(in the NWO would that be mipsisa1. 8-)


> > 	- As CPU aliases they can allow opcodes which aren't available
> > 	  on other ISA-conforming CPUs.
> 
> Not sure what you mean.  Do you have any examples?

If the CPU aliases for the ISA aren't the minimal set for the ISA,
that sounds like a very good reason for somebody to go off and do
something better, i.e., create "actual ISA" definitions.

I believe that at least mipsisa32 and mipsisa64 -- ISAs which are
really ISAs in the code, rather than being CPUs -- are correct.  8-)



> > Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
> > The same should be true for MIPS IV opcodes in n32 code.
> 
> Hmm... not sure why,

Because the o32 ABI specification was defined as MIPS I only.
I.e., MIPS I instructions only and EF_MIPS_ARCH == 0.

It's a definitional thing.  8-)

The notion that a bunch of us like more is something like: "ABI means
file format, calling conventions, etc.  Orthogonal to that is the ISA
level, and the ISA level is easy to check via EF_MIPS_ARCH."  I think
that's a much more useful way to think about things given the plethora
of ISAs.

And, in that view, -mabi=foo probably shouldn't change the ISA (and
definitely shouldn't downgrade it).



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]       ` <mailpost.1026729642.18965@news-sj1-1>
@ 2002-07-15 10:54         ` cgd
  2002-07-15 11:02           ` Mark D. Baushke
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-15 10:54 UTC (permalink / raw)
  To: mdb; +Cc: Richard Sandiford, Thiemo Seufer, gcc-patches, binutils

At Mon, 15 Jul 2002 10:40:42 +0000 (UTC), "Mark D. Baushke" wrote:
> In MIPS I the -mlong64 also implies the use of register pairs right? 
> Where in MIPS III, the -mlong64 implies the use of a single register.

yes.

Several people, myself included, would be ... quite happy if that mode
went away completely, i.e. -mlong64 were disallowed if GPRs weren't
also 64-bit.

Are you actually using -mlong64 w/ 32-bit GPR systems?



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  3:40   ` Richard Sandiford
  2002-07-15  3:57     ` Mark D. Baushke
       [not found]     ` <mailpost.1026728027.18467@news-sj1-1>
@ 2002-07-15 11:01     ` Thiemo Seufer
       [not found]       ` <mailpost.1026755685.506@news-sj1-1>
                         ` (2 more replies)
  2002-07-16  2:46     ` Maciej W. Rozycki
  3 siblings, 3 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 11:01 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Thiemo Seufer, gcc-patches, binutils

Richard Sandiford wrote:
[snip]
> > I don't see a good reason to mix ISA and ABI selection. AFAICS it's
> > enough to
> > 
> > 	- choose the lowest ISA required for a selected ABI
> > 
> > 	- use the 'highest' ABI for any selected ISA
> 
> I'm not sure what you mean by "mix" here.  Anyway, I don't think
> it's a good idea to select the lowest ISA for an ABI.  If you have
> a configuration that uses a particular CPU by default (let's say a
> MIPS II one), specifying an ABI shouldn't "downgrade" to MIPS I.

If you are caring about particular processor features you aren't
using an ABI.

> If someone's using a MIPS II or higher toolchain to generate code
> that must run on a MIPS I machine, it doesn't seem unreasonable
> to ask them to say so explicitly.

There seems to be some misconception about the term 'ABI', maybe
because the current -mabi=FOO option basically means "select calling
conventions and register sizes". But an ABI is a much more powerful
concept than pushing a few compiler options. It defines a platform
over a variety of hardware which allows to run the same binary code.

In fact, all other compiler options we discussed here are already
defined by the ABI if there is one in use. So guessing an ABI from
other compiler options just means doing things backwards. From an
ABI POV, these compiler options will either have no effect or they
will break ABI conformance.

> > GCC and GAS have different requirements: For GCC it's sensible to guess
> > ISA from ABI and vice versa because it usually handles ABI-conforming
> > code. For GAS, the ABI selection is not that useful because assembly
> > normally isn't ABI-conformant (which would be limited to opcodes covered
> > in the respective ISA).
> 
> I agree that might be true for embedded configs.  But like Maciej
> said, it could be useful to have a default ABI for hosted toolchains
> like mips64-linux-gnu.  It seems reasonable that anyone using such
> an assembler would be at least try to write ABI-conformant code.

I don't know about embedded configs. Just have a look at the linux
kernel. I claim it has nearly no assembly code which could be written
in an ABI-conformant way, with few performance improvements in assembly
as an exception.

Having a default ABI is IMHO a good thing in any case: For userland
code the ABI conformance is essential, and for kernels/embedded configs
the ABI can provide the default settings which may get overridden then.

> So the way the GAS config stuff is structured, it will assume NO_ABI
> by default, since that seems sensible for most embedded configs,
> and won't lead to spurious "incompatible ABI" link failures.

Spurious? With some likeliness these are real incompatibilities.

> Not setting EF_MIPS_ABI is also the historical behaviour.
> There's then the option of overriding the NO_ABI default for
> particular configurations.
> 
> > >     For example, if "mips64-elf-gcc -mips1" chooses o32 code
> > >     (as it does now) then "mips64-elf-gcc -march=r3000" should do the same.
> > 
> > This may break the 'No ABI' case which means default ABI plus e.g.
> > -mlong64 as it is used in the embedded world. OTOH, basing this usage
> > on o32/o64 in future is probably a good idea.
> 
> I'm not sure how it could break things like that.  -mlong64 only
> controls type sizes.

I heard

	mips64-elf-gcc -march=FOO -mlong64

is used in the embedded world to get 64 bit code and allow FOO's
opcodes in it. Selecting an ABI definition automatically for e.g.
FOO == r4000 while keeping "No ABI" for FOO == r5000 would be
at least surprising.

> > >     (a) It seems counter-intuitive for -mabi to override the default
> > >         architecture even when that default was compatible.  For
> > >         example, "mipsisa32-elf-gcc -mabi=o32" would generate
> > > 	MIPS I code rather than MIPS 32 code.
> > 
> > Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
> > The same should be true for MIPS IV opcodes in n32 code.
> 
> Hmm... not sure why, but if it's related to...

The ABI defines the platform to run code on. So it specifies
the set of opcodes which are legal with this ABI. E.g., MIPS 32
specific opcodes are outside the o32 definition. It they weren't,
every o32 conformant platform would need to emulate them.

> > This would mean the User can use
> > 
> > 	gcc -mabi=32
> > 
> > and then he gets code which might _not_ run on o32 conformant
> > Systems. This defeats the idea of having an ABI.
> 
> It sounds like you're saying that, because the original o32 systems were
> MIPS I only, -mabi=32 should mean "generate MIPS I code" unless the user
> says otherwise.

Slightly different:
If -mabi=32 really means "Create o32 ABI conformant code", the MIPS I
opcodes are the only ones which can be allowed.

> That's the current behaviour, but like I said above,
> it seems strange to pick MIPS I regardless of the default processor.

An ABI defines _minimal_ requirements for the processor. It also
gives a _maximum_ what is guaranteed to the userland. The strangeness
you see is simply the fact that there are/should be better ABIs than
o32 for current processors.

> > > 	(OPTION_FP64): New.
> > > 	(md_longopts): Add -mfp64, remove -mcpu.
> > 
> > There's little reason to have -m[gf]p64, see
> > http://sources.redhat.com/ml/binutils/2001-07/msg00417.html
> 
> One of the changes was that the default float register size would
> be worked out from -mgp32, -mgp64, -msingle-float, etc.  That was
> mostly for multilib convenience.

For embedded use, I assume. For hosted systems this should be done
by the ABI.

> GAS can generate -mgp32 -mfp64
> "no ABI" code, so we'd need the -mfp64 option then.  Why anyone
> would use it, well, who knows?

I don't see even an half-sane use for it, and it's IMHO a bad idea
to try to support everything without need.

> But someone once went to a lot of
> effort to make it work in GCC too (although it doesn't any more).

Are you actually talking about the combination -mgp32 -mfp64?


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 10:54         ` cgd
@ 2002-07-15 11:02           ` Mark D. Baushke
  2002-07-15 11:11             ` cgd
  0 siblings, 1 reply; 97+ messages in thread
From: Mark D. Baushke @ 2002-07-15 11:02 UTC (permalink / raw)
  To: cgd; +Cc: Richard Sandiford, Thiemo Seufer, gcc-patches, binutils

cgd@broadcom.com writes:
> 
> At Mon, 15 Jul 2002 10:40:42 +0000 (UTC), "Mark D. Baushke" wrote:
> > In MIPS I the -mlong64 also implies the use of register pairs right? 
> > Where in MIPS III, the -mlong64 implies the use of a single register.
> 
> yes.
> 
> Several people, myself included, would be ... quite happy if that mode
> went away completely, i.e. -mlong64 were disallowed if GPRs weren't
> also 64-bit.

I am not sure it fully solves your problem. You would still have to deal
with 64-bit 'long long' integers.

We do use long long on 32-bit processors to manipulate 64-bit values.
When operating a mips processor in 32-bit mode you still need to use
register pairs for such values or figure out that the ABI only needs a
single register for a 64-bit value and use that instead. In the end, it
matters how the chip itself is configured to run as to what happens to
the size of the GPRs.
 
> Are you actually using -mlong64 w/ 32-bit GPR systems?

No, but we do use 64-bit integers w/ 32-bit GPR systems.

    -- Mark

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]       ` <mailpost.1026733871.20742@news-sj1-1>
@ 2002-07-15 11:04         ` cgd
  2002-07-15 14:28           ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-15 11:04 UTC (permalink / raw)
  To: rsandifo; +Cc: gcc-patches, binutils

At Mon, 15 Jul 2002 11:51:11 +0000 (UTC), "Richard Sandiford" wrote:
> > > + /* This array must have the same order as enum processor_type.  */
> > > + static const struct mips_processor mips_processors[] = {
> > > +   { "default", 0, 1 },
> > > +   { "r3000", "_R3000", 1 },
> > > +   { "r3900", "_R3900", 1 },
> > > +   { "r6000", "_R6000", 2 },
> > > +   { "r4000", "_R4000", 3 },
> > > +   { "vr4100", "_R4100", 3 },
> > > +   { "vr4300", "_R4300", 3 },
> > > +   { "r4600", "_R4600", 3 },
> > > +   { "r4650", "_R4650", 3 },
> > > +   { "vr5000", "_R5000", 4 },
> > > +   { "r8000", "_R8000", 4 },
> > > +   { "r4kc", "_R4KC", 32 },
> > > +   { "r5kc", "_R5KC", 64 },
> > > +   { "r20kc", "_R20KC", 64 }
> > > + };
> > 
> > OK, assuming that i'm seeing all of the uses of these, disagree on a
> > couple of grounds:
> > 
> > * some of these are things which implementations (i.e., existing
> >   systems) may have already come to define.  IMO they need more
> >   letters.
> 
> I took my cue from R3000 and R4000, which were the standard before.

So, historically, those defines _seem_ to be used less as 'processor'
defines and more as 'GPR size' defines, at least looking at the way
GCC defined them in say 3.0.x.


> The table is just a mindless extension to the other processors.
> How about zeroing out any macro entries that aren't appropriate?

Well...

Nobody expects the new defines, something better seems like it would
be worthwhile (rest of msg), and I'd _guess_ (not knowing for sure)
that code which uses _R3000 & _R4000 do so expecting them to indicate
GPR size...

So, really, I'd just the define names in that table and leave _R3000
and _R4000 alone.

I don't know what code actually depends on those defines... but in a
perfect world, I think we'd nuke them.  8-)  Maybe make it possible for
OSes to kill those backward-compatibility defines, so that OSes which
want to clean up their define space can do so.



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:02           ` Mark D. Baushke
@ 2002-07-15 11:11             ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-15 11:11 UTC (permalink / raw)
  To: Mark D. Baushke; +Cc: Richard Sandiford, Thiemo Seufer, gcc-patches, binutils

At Mon, 15 Jul 2002 11:01:05 -0700, Mark D. Baushke wrote:
> > Several people, myself included, would be ... quite happy if that mode
> > went away completely, i.e. -mlong64 were disallowed if GPRs weren't
> > also 64-bit.
> 
> I am not sure it fully solves your problem. You would still have to deal
> with 64-bit 'long long' integers.

Well, my problem w.r.t -mips1 -mlong64 is that it's allegedly
supported, and coping with it in code which needs to handle lots of
options gracefully... makes for a problem.

It causes the one case for mips GCC currently where sizeof long !=
sizeof pointer.  8-)

yes, long long is still a pain, but it's a slightly different pain.
8-)


> > Are you actually using -mlong64 w/ 32-bit GPR systems?
> 
> No, but we do use 64-bit integers w/ 32-bit GPR systems.

Yes.  There are a LOT of people doing that.


cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 10:47       ` cgd
@ 2002-07-15 11:22         ` Thiemo Seufer
       [not found]           ` <mailpost.1026757359.1135@news-sj1-1>
  2002-07-16  4:04         ` Maciej W. Rozycki
  1 sibling, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 11:22 UTC (permalink / raw)
  To: cgd; +Cc: rsandifo, gcc-patches, binutils

cgd@broadcom.com wrote:
> At Mon, 15 Jul 2002 10:13:47 +0000 (UTC), "Richard Sandiford" wrote:
> > Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> > > I agree, -mipsN should be an alias for the equivalent -march=FOO.
> > > Please note that the -mipsN options should IMHO be obsoleted:
> > >
> > > 	- They are asymmetric because all of them can be replaced by
> > > 	  -march=FOO, but there are -march=FOO without -mipsN equivalents
> > 
> > I'd guess the ISA levels are more well known than the processors we're
> > associating them with, so there's probably no harm in keeping them as
> > aliases, but...
> 
> I actually think it's important to keep them.  In general, it's
> quite desriable to be able to say, for instance:
> 
> "will run on any MIPS N CPU, but optimized for this particular CPU."
> 
> where, say, N == 1.  historically, the first part of that has been
> caused by -mips1 (for N == 1),

Unfortunately, it has not. For GCC there's not much difference, but
GAS allows the default CPUs specific opcodes, too.

> and people I think have come to expect
> that.
> 
> I do think it's reasonable and probably desirable to support (can you
> hear the maniacal laughing, too?):
> 
> 	-march=mips1
> 
> (in the NWO would that be mipsisa1. 8-)

Seconded. :-)

> > > 	- As CPU aliases they can allow opcodes which aren't available
> > > 	  on other ISA-conforming CPUs.
> > 
> > Not sure what you mean.  Do you have any examples?
> 
> If the CPU aliases for the ISA aren't the minimal set for the ISA,
> that sounds like a very good reason for somebody to go off and do
> something better, i.e., create "actual ISA" definitions.
> 
> I believe that at least mipsisa32 and mipsisa64 -- ISAs which are
> really ISAs in the code, rather than being CPUs -- are correct.  8-)

Are the CP0 and TLB instructions really covered by the ISA there?

> > > Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
> > > The same should be true for MIPS IV opcodes in n32 code.
> > 
> > Hmm... not sure why,
> 
> Because the o32 ABI specification was defined as MIPS I only.
> I.e., MIPS I instructions only and EF_MIPS_ARCH == 0.
> 
> It's a definitional thing.  8-)
> 
> The notion that a bunch of us like more is something like: "ABI means
> file format, calling conventions, etc.  Orthogonal to that is the ISA
> level, and the ISA level is easy to check via EF_MIPS_ARCH."

It's not truely orthogonal because there's a minimal required ISA
for some ABIs.

> I think
> that's a much more useful way to think about things given the plethora
> of ISAs.

From a ABI POV there aren't many: MIPS I and MIPS III.

> And, in that view, -mabi=foo probably shouldn't change the ISA (and
> definitely shouldn't downgrade it).

My idea is to get sane defaults from the ABI definition.

	gcc -mabi=FOO

should create ABI conformant code, while

	gcc -mabi=FOO -march=BAR

loosens the ABI restrictions in order to allow BAR opcodes.
AFAICS this fulfils the "least surprise" priciple for hosted
systems, and the embedded world can live with it, too.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]       ` <mailpost.1026755685.506@news-sj1-1>
@ 2002-07-15 11:24         ` cgd
  2002-07-15 12:51           ` Thiemo Seufer
                             ` (2 more replies)
  0 siblings, 3 replies; 97+ messages in thread
From: cgd @ 2002-07-15 11:24 UTC (permalink / raw)
  To: ica2_ts; +Cc: Richard Sandiford, gcc-patches, binutils

At Mon, 15 Jul 2002 17:54:45 +0000 (UTC), "Thiemo Seufer" wrote:
> There seems to be some misconception about the term 'ABI', maybe
> because the current -mabi=FOO option basically means "select calling
> conventions and register sizes". But an ABI is a much more powerful
> concept than pushing a few compiler options. It defines a platform
> over a variety of hardware which allows to run the same binary code.

I prefer to think of it that there are two competing definitions.  8-)

All of the binary formats in question have a field, EF_MIPS_ARCH,
which can easily be used to determine which ISA is used to compile the
binary.

According to your strict definition, only one value of that field is
allowed per ABI.

However, it is much more useful to people creating optimized code to
be able to generate code for specific ISAs, it is almost free from the
POV of checking whether said code is compatible with the current
system(*), and it doesn't really diminish the value of the ABI for
'binary portability' if the portable binaries are compiled with
the options that produce the exact ABI.

If somebody's using, say, mips64-linux, I'd say that they expect
-mabi=X to get them the either 'portable' ABI 'X', or the "-mips3" ISA
version, depending on how they look at things.

If they're using a target like, say, mipsisa64-linux, then they almost
certainly want -mabi=X to get them the ABI 'X' for binary format,
calling conventions, etc., but with use of MIPS64 instructions.

If they're using mipsisa64sb1-linux, they probably expect built-in
support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
well, regardless of the ABI they choose on the command line.


I'm wondering if the right thing to do here is have flags like
-mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...

There's use for it: people building e.g. userland binary distributions
would want it, and would encourage users building e.g. RPMs to use it
so they didn't have to remember the exact ISA to use to get things
right.

I think there're a large number of people out there doing embedded
work with systems that use the standard ABIs (E.g. linux), whose lives
would be a fair bit harder if -mabi=X always implied ISA.


cgd
--
(*) Alas, it's almost free to check ISA, but not really possible to
check CPU extensions.


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:24         ` cgd
@ 2002-07-15 12:51           ` Thiemo Seufer
  2002-07-16  3:57             ` Maciej W. Rozycki
       [not found]             ` <mailpost.1026759415.2116@news-sj1-1>
  2002-07-16  4:45           ` Maciej W. Rozycki
  2002-07-16  5:31           ` Richard Sandiford
  2 siblings, 2 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 12:51 UTC (permalink / raw)
  To: cgd; +Cc: ica2_ts, Richard Sandiford, gcc-patches, binutils

cgd@broadcom.com wrote:
> At Mon, 15 Jul 2002 17:54:45 +0000 (UTC), "Thiemo Seufer" wrote:
> > There seems to be some misconception about the term 'ABI', maybe
> > because the current -mabi=FOO option basically means "select calling
> > conventions and register sizes". But an ABI is a much more powerful
> > concept than pushing a few compiler options. It defines a platform
> > over a variety of hardware which allows to run the same binary code.
> 
> I prefer to think of it that there are two competing definitions.  8-)
> 
> All of the binary formats in question have a field, EF_MIPS_ARCH,
> which can easily be used to determine which ISA is used to compile the
> binary.
> 
> According to your strict definition, only one value of that field is
> allowed per ABI.

For strict ABI conformance, it obviously is.

> However, it is much more useful to people creating optimized code to
> be able to generate code for specific ISAs,

For people who create, maintain and use an whole OS this would
be horrible. :-)

> it is almost free from the
> POV of checking whether said code is compatible with the current
> system(*), and it doesn't really diminish the value of the ABI for
> 'binary portability' if the portable binaries are compiled with
> the options that produce the exact ABI.
> 
> If somebody's using, say, mips64-linux, I'd say that they expect
> -mabi=X to get them the either 'portable' ABI 'X', or the "-mips3" ISA
> version, depending on how they look at things.

I this special example,

	gcc -mabi=o32

should produce MIPS II code, while

	gcc -mabi=64

should give MIPS III code, so it runs on any supported hardware.
Note that the MIPS II is a deviation from stock o32 ABI, the
linux-mips kernel emulates the necessary instructions on MIPS I
hardware. This means we have an o32-linux ABI there.

> If they're using a target like, say, mipsisa64-linux, then they almost
> certainly want -mabi=X to get them the ABI 'X' for binary format,
> calling conventions, etc., but with use of MIPS64 instructions.
> 
> If they're using mipsisa64sb1-linux, they probably expect built-in
> support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
> well, regardless of the ABI they choose on the command line.

If all of the hardware for this target supports these, ok.
But the ISA pre-selection should then be done in the target specific
code and not globally.

> I'm wondering if the right thing to do here is have flags like
> -mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...

-mabi=isa64sb1-with-many-wonderful-extensions ;-)

> There's use for it: people building e.g. userland binary distributions
> would want it, and would encourage users building e.g. RPMs to use it
> so they didn't have to remember the exact ISA to use to get things
> right.
>
> I think there're a large number of people out there doing embedded
> work with systems that use the standard ABIs (E.g. linux), whose lives
> would be a fair bit harder if -mabi=X always implied ISA.

In this case, people should not even need to care about the ABI.
The ABI should be a sane default, and they have only to specify
where they want to deviate from it. E.g.

	mips-linux-gcc -march=r4600

should cenerate code which uses r4600 specific opcodes but uses
o32 definitions otherwise. The definition of the default ABI
should be done in the target specific code, maybe with "No ABI"
for embedded toolchains.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  4:50   ` Richard Sandiford
@ 2002-07-15 13:18     ` Thiemo Seufer
  2002-07-15 13:31       ` Eric Christopher
  2002-07-16  3:54     ` Maciej W. Rozycki
  1 sibling, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 13:18 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Maciej W. Rozycki, gcc-patches, binutils

Richard Sandiford wrote:
[snip]
> The main difficulty with dropping the ABI selection entirely
> is: how do you select between the 32-bit and 64-bit versions
> of the EABIs?  mipstx39-elf-gcc generates 32-bit EABI code
> by default.  What happens if you select a 64-bit processor?
> Options I can see:
> 
> 1. Stick with the idea in the patch I sent.  Selecting a 64-bit
>    processor would usually select the 64-bit EABI, but adding
>    -mgp32 forces the 32-bit version.
>
> 2. Reverse of (1).  You get the 32-bit version of the EABI
>    unless you use -mgp64.
> 
> 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
>    the 32-bit version unless you use -mabi=eabi64.

I would prefer the third option. At least it makes explicit
what's going on and does not interfere with other ABIs.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 13:18     ` Thiemo Seufer
@ 2002-07-15 13:31       ` Eric Christopher
  2002-07-15 13:59         ` Thiemo Seufer
  0 siblings, 1 reply; 97+ messages in thread
From: Eric Christopher @ 2002-07-15 13:31 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Richard Sandiford, Maciej W. Rozycki, gcc-patches, binutils


> > 1. Stick with the idea in the patch I sent.  Selecting a 64-bit
> >    processor would usually select the 64-bit EABI, but adding
> >    -mgp32 forces the 32-bit version.
> >
> > 2. Reverse of (1).  You get the 32-bit version of the EABI
> >    unless you use -mgp64.
> > 
> > 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
> >    the 32-bit version unless you use -mabi=eabi64.
> 
> I would prefer the third option. At least it makes explicit
> what's going on and does not interfere with other ABIs.

It _does_ make it explicit, however, there aren't really two different
ABIs...

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 13:31       ` Eric Christopher
@ 2002-07-15 13:59         ` Thiemo Seufer
  2002-07-15 14:25           ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 13:59 UTC (permalink / raw)
  To: Eric Christopher
  Cc: Thiemo Seufer, Richard Sandiford, Maciej W. Rozycki, gcc-patches,
	binutils

Eric Christopher wrote:
[snip]
> > > 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
> > >    the 32-bit version unless you use -mabi=eabi64.
> > 
> > I would prefer the third option. At least it makes explicit
> > what's going on and does not interfere with other ABIs.
> 
> It _does_ make it explicit, however, there aren't really two different
> ABIs...

Err, different register sizes make the binary interfaces incompatible.
If this is the same ABI nevertheless, what ABIs would you call
different then?


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 13:59         ` Thiemo Seufer
@ 2002-07-15 14:25           ` Eric Christopher
  2002-07-15 14:30             ` Thiemo Seufer
  0 siblings, 1 reply; 97+ messages in thread
From: Eric Christopher @ 2002-07-15 14:25 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Richard Sandiford, Maciej W. Rozycki, gcc-patches, binutils


> 
> Err, different register sizes make the binary interfaces incompatible.
> If this is the same ABI nevertheless, what ABIs would you call
> different then?

Ah yes, but that's an architecture difference here. Neither of the EABIs
are restricted to particular register sizes. This should be a check in
architecture, not ABI, at least IMO.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:04         ` cgd
@ 2002-07-15 14:28           ` Eric Christopher
  2002-07-16  3:23             ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: Eric Christopher @ 2002-07-15 14:28 UTC (permalink / raw)
  To: cgd; +Cc: rsandifo, gcc-patches, binutils, thorpej


> > I took my cue from R3000 and R4000, which were the standard before.
> 
> So, historically, those defines _seem_ to be used less as 'processor'
> defines and more as 'GPR size' defines, at least looking at the way
> GCC defined them in say 3.0.x.
> 

It was annoying too. There _were_ preprocessor directives for mips and
mips64.. anyhow


> 
> Nobody expects the new defines, something better seems like it would
> be worthwhile (rest of msg), and I'd _guess_ (not knowing for sure)
> that code which uses _R3000 & _R4000 do so expecting them to indicate
> GPR size...
> 
> So, really, I'd just the define names in that table and leave _R3000
> and _R4000 alone.
> 
> I don't know what code actually depends on those defines... but in a
> perfect world, I think we'd nuke them.  8-)  Maybe make it possible for
> OSes to kill those backward-compatibility defines, so that OSes which
> want to clean up their define space can do so.

I agree with this. We need to leave the preprocessor defines there, I'd
_like_ to extend them so that we can have code that tests for it and
tests for mips or mips64 as necessary (like newlib does...)

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 14:25           ` Eric Christopher
@ 2002-07-15 14:30             ` Thiemo Seufer
  2002-07-15 14:59               ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 14:30 UTC (permalink / raw)
  To: Eric Christopher
  Cc: Richard Sandiford, Maciej W. Rozycki, gcc-patches, binutils

Eric Christopher wrote:
> 
> > 
> > Err, different register sizes make the binary interfaces incompatible.
> > If this is the same ABI nevertheless, what ABIs would you call
> > different then?
> 
> Ah yes, but that's an architecture difference here. Neither of the EABIs
> are restricted to particular register sizes. This should be a check in
> architecture, not ABI, at least IMO.

What if somebody wants to run 32 bit EABI on a 64 bit processor for
some (backward compatibility) reason, and also wants to use some
processor specific opcodes?


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 14:30             ` Thiemo Seufer
@ 2002-07-15 14:59               ` Eric Christopher
  2002-07-15 15:04                 ` Thiemo Seufer
  0 siblings, 1 reply; 97+ messages in thread
From: Eric Christopher @ 2002-07-15 14:59 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Richard Sandiford, Maciej W. Rozycki, gcc-patches, binutils


> What if somebody wants to run 32 bit EABI on a 64 bit processor for
> some (backward compatibility) reason, and also wants to use some
> processor specific opcodes?

-mgp32.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 14:59               ` Eric Christopher
@ 2002-07-15 15:04                 ` Thiemo Seufer
  2002-07-15 17:26                   ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-15 15:04 UTC (permalink / raw)
  To: Eric Christopher
  Cc: Thiemo Seufer, Richard Sandiford, Maciej W. Rozycki, gcc-patches,
	binutils

Eric Christopher wrote:
> 
> > What if somebody wants to run 32 bit EABI on a 64 bit processor for
> > some (backward compatibility) reason, and also wants to use some
> > processor specific opcodes?
> 
> -mgp32.

Why is this better than -mabi=eabi32?


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 15:04                 ` Thiemo Seufer
@ 2002-07-15 17:26                   ` Eric Christopher
  0 siblings, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-15 17:26 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Richard Sandiford, Maciej W. Rozycki, gcc-patches, binutils

On Mon, 2002-07-15 at 14:58, Thiemo Seufer wrote:
> Eric Christopher wrote:
> > 
> > > What if somebody wants to run 32 bit EABI on a 64 bit processor for
> > > some (backward compatibility) reason, and also wants to use some
> > > processor specific opcodes?
> > 
> > -mgp32.
> 
> Why is this better than -mabi=eabi32?

No reason than that it's already there and then we'd have to make an
alias for -mabi=eabi32 to turn on gp32 anyhow.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:01     ` Thiemo Seufer
       [not found]       ` <mailpost.1026755685.506@news-sj1-1>
@ 2002-07-16  2:40       ` Richard Sandiford
  2002-07-18 13:36         ` Thiemo Seufer
  2002-07-16  4:17       ` Maciej W. Rozycki
  2 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-16  2:40 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: gcc-patches, binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> Richard Sandiford wrote:
> > > GCC and GAS have different requirements: For GCC it's sensible to guess
> > > ISA from ABI and vice versa because it usually handles ABI-conforming
> > > code. For GAS, the ABI selection is not that useful because assembly
> > > normally isn't ABI-conformant (which would be limited to opcodes covered
> > > in the respective ISA).
> > 
> > I agree that might be true for embedded configs.  But like Maciej
> > said, it could be useful to have a default ABI for hosted toolchains
> > like mips64-linux-gnu.  It seems reasonable that anyone using such
> > an assembler would be at least try to write ABI-conformant code.
> 
> I don't know about embedded configs. Just have a look at the linux
> kernel. I claim it has nearly no assembly code which could be written
> in an ABI-conformant way, with few performance improvements in assembly
> as an exception.
>
> Having a default ABI is IMHO a good thing in any case: For userland
> code the ABI conformance is essential, and for kernels/embedded configs
> the ABI can provide the default settings which may get overridden then.

I'm still not sure what you're suggesting should be done in the
kernel case.

> > So the way the GAS config stuff is structured, it will assume NO_ABI
> > by default, since that seems sensible for most embedded configs,
> > and won't lead to spurious "incompatible ABI" link failures.
> 
> Spurious? With some likeliness these are real incompatibilities.

Sure, it could catch real incompatibilities, but it could generate
false positives too.  My point is that, before now, there has been
no default ABI assumption for "mips-elf-as", either invoked directly,
or through the GCC driver.  It hasn't been necessary to think about
ABI flags when assembling (to pick a trivial example):

version:
        .asciz "version (2.10)"

I'm not saying it's necessarily bad to have a default ABI for all
configs, but I just feel that some users might think we're being
a bit too pedantic.

> I heard
> 
> 	mips64-elf-gcc -march=FOO -mlong64
> 
> is used in the embedded world to get 64 bit code and allow FOO's
> opcodes in it. Selecting an ABI definition automatically for e.g.
> FOO == r4000 while keeping "No ABI" for FOO == r5000 would be
> at least surprising.

There isn't a "no ABI" mode in GCC as such.  What we have is ad-hoc
variations on the real ABIs.  So mips64-elf-gcc is o64 by default.
If you specify -mlong64, gcc generates a "long64" version of o64
code (mips_abi == ABI_O64, TARGET_LONG64).  Specifying a 64-bit FOO
would not change the ABI at all wrt just "mips64-elf-gcc -mlong64".

After the patch I sent, specifying a 32-bit FOO would switch to o32,
but you'd get gcc's "long64" version of o32 (just as you would with
"mips-elf-gcc -mlong64").

> > One of the changes was that the default float register size would
> > be worked out from -mgp32, -mgp64, -msingle-float, etc.  That was
> > mostly for multilib convenience.
> 
> For embedded use, I assume. For hosted systems this should be done
> by the ABI.

Well, -mabi isn't the only GCC option that changes the ABI.  At the
moment, you need -mgp32 to select between 32-bit and 64-bit code when
an EABI is selected.  And we have the -msingle-float variations too.
For example:

  -mgp32 -mabi=eabi                     => -mfp32
  -mgp64 -mabi=eabi                     => -mfp64
  -mgp64 -mabi=eabi -msingle-float      => -mfp32

(All supported combinations, I think.)

> > GAS can generate -mgp32 -mfp64 "no ABI" code, so we'd need the
> > -mfp64 option then.  Why anyone would use it, well, who knows?
> 
> I don't see even an half-sane use for it, and it's IMHO a bad idea
> to try to support everything without need.
> 
> > But someone once went to a lot of effort to make it work in GCC too
> > (although it doesn't any more).
> 
> Are you actually talking about the combination -mgp32 -mfp64?

Sadly, yes ;).  E.g., from mips.md:

    (define_insn "movdf_internal1a"
      [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
            (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
      "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)

Like I say, gcc doesn't support it any more, but someone somewhere
must have cared.  The archive even has patches to fix bugs in
-mgp32 -mfp64 code.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  3:40   ` Richard Sandiford
                       ` (2 preceding siblings ...)
  2002-07-15 11:01     ` Thiemo Seufer
@ 2002-07-16  2:46     ` Maciej W. Rozycki
  2002-07-16  8:01       ` Paul Koning
  3 siblings, 1 reply; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  2:46 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Thiemo Seufer, gcc-patches, binutils

On 15 Jul 2002, Richard Sandiford wrote:

> > I agree, -mipsN should be an alias for the equivalent -march=FOO.
> > Please note that the -mipsN options should IMHO be obsoleted:
> >
> > 	- They are asymmetric because all of them can be replaced by
> > 	  -march=FOO, but there are -march=FOO without -mipsN equivalents
> 
> I'd guess the ISA levels are more well known than the processors we're
> associating them with, so there's probably no harm in keeping them as
> aliases, but...

 There is no need, either, as there are "-march=mips1", etc. equivalents,
and specifying "-march=3000 -march=mips2" is obviously incorrect for
anyone, while "-march=3000 -mips2" isn't that obvious, even though it has 
the same meaning.

> > Strictly speaking, MIPS 32 code isn't conforming to o32 ABI.
> > The same should be true for MIPS IV opcodes in n32 code.
> 
> Hmm... not sure why, but if it's related to...

 Well, the o32 ABI explicitly states only MIPS1 instructions (which MIPS32
is a superset of) are allowed.  But for practical reasons it's useful to
assume an ABI only specifies the register allocation, the calling
convention and addressing, leaving the instruction set used to be handled
by the execution environment.  The set is more or less reported in the ELF
header anyway.

> > This would mean the User can use
> > 
> > 	gcc -mabi=32
> > 
> > and then he gets code which might _not_ run on o32 conformant
> > Systems. This defeats the idea of having an ABI.
> 
> It sounds like you're saying that, because the original o32 systems were
> MIPS I only, -mabi=32 should mean "generate MIPS I code" unless the user
> says otherwise.  That's the current behaviour, but like I said above,
> it seems strange to pick MIPS I regardless of the default processor.

 The confusion is a result of binding two unrelated properties together,
i.e. the instruction set and the code conventions.  Maybe the solution is
adding another option to specify the conventions only?  But is it really
desireable? 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 14:28           ` Eric Christopher
@ 2002-07-16  3:23             ` Richard Sandiford
  2002-07-16 12:16               ` Eric Christopher
       [not found]               ` <mailpost.1026812813.25035@news-sj1-1>
  0 siblings, 2 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-16  3:23 UTC (permalink / raw)
  To: Eric Christopher; +Cc: cgd, gcc-patches, binutils, thorpej

Eric Christopher <echristo@redhat.com> writes:
> > > I took my cue from R3000 and R4000, which were the standard before.
> > 
> > So, historically, those defines _seem_ to be used less as 'processor'
> > defines and more as 'GPR size' defines, at least looking at the way
> > GCC defined them in say 3.0.x.
> 
> It was annoying too. There _were_ preprocessor directives for mips and
> mips64.. anyhow

Ugh.  Ok, I'll keep _R3000 & _R4000 as they are now, and add the
_MIPS_ARCH and _MIPS_TUNE that Chris suggested.

Question: if gcc treats two processors as the same for scheduling,
should they have the same _MIPS_ARCH and _MIPS_TUNE value?  Like,
should -march=r2000 and -march=r3000 set _MIPS_ARCH to the same
value (_MIPS_R3000?) to reflect what GCC's doing, or should there
be separate _MIPS_R2000 and _MIPS_R3000 defines?  How about
-mtune= and _MIPS_TUNE?

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15  4:50   ` Richard Sandiford
  2002-07-15 13:18     ` Thiemo Seufer
@ 2002-07-16  3:54     ` Maciej W. Rozycki
  2002-07-16  4:47       ` Mark D. Baushke
  1 sibling, 1 reply; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  3:54 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

On 15 Jul 2002, Richard Sandiford wrote:

> It might also be nice to have a --with-abi configure option,
> although that's something we could add later...

 I'm not sure that is desireable -- I think the default ABI would best be
selectable with the target triple.  Like with "mips64abin32-*-*" or so.

> The reason for -mgp32 is for consitency with EABIs.  If you
> have a 32-bit EABI configuration like mipstx39-elf, does
> -mips4 select 64-bit EABI code, or 32-bit EABI code?  The
> first seems most natural to me, so the rule was: if you
> select a 64-bit processor, you get 64-bit code, unless
> you also select -mgp32.

 The implicit dependencies seem unfortunate for me.

> In general, the main reason to keep the implicit ABI selection
> is that that's what we've done before.  I didn't think there'd
> be much support for dropping it entirely.

 Certainly we can't drop them immediately, if there is no alternative,
which seem to be true from what you wrote above.  At least a single
release with both ways available must be created.

> The main difficulty with dropping the ABI selection entirely
> is: how do you select between the 32-bit and 64-bit versions
> of the EABIs?  mipstx39-elf-gcc generates 32-bit EABI code
> by default.  What happens if you select a 64-bit processor?
> Options I can see:
> 
> 1. Stick with the idea in the patch I sent.  Selecting a 64-bit
>    processor would usually select the 64-bit EABI, but adding
>    -mgp32 forces the 32-bit version.
> 
> 2. Reverse of (1).  You get the 32-bit version of the EABI
>    unless you use -mgp64.
> 
> 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
>    the 32-bit version unless you use -mabi=eabi64.

 The last option seems the cleanest to me.  With your changes, it would
permit selecting a default ABI when configuring for certain embedded
targets as well (though I'm not sure how useful it would be in practice at
the moment, since I am not an embedded user).

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 12:51           ` Thiemo Seufer
@ 2002-07-16  3:57             ` Maciej W. Rozycki
  2002-07-18 13:43               ` Thiemo Seufer
       [not found]             ` <mailpost.1026759415.2116@news-sj1-1>
  1 sibling, 1 reply; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  3:57 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: cgd, Richard Sandiford, gcc-patches, binutils

On Mon, 15 Jul 2002, Thiemo Seufer wrote:

> Note that the MIPS II is a deviation from stock o32 ABI, the
> linux-mips kernel emulates the necessary instructions on MIPS I
> hardware. This means we have an o32-linux ABI there.

 Does it?  I haven't seen any code to emulate trap, branch likely, dword
coprocessor transfer instructions.  What is emulated are only the ll and
sc instructions, but they are only a small subset of MIPS II extensions
which is never used by gcc, unlike the others.

> > If they're using mipsisa64sb1-linux, they probably expect built-in
> > support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
> > well, regardless of the ABI they choose on the command line.
> 
> If all of the hardware for this target supports these, ok.
> But the ISA pre-selection should then be done in the target specific
> code and not globally.

 If a target triplet defines a CPU, it should always be used as the
default for uniformity.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 10:47       ` cgd
  2002-07-15 11:22         ` Thiemo Seufer
@ 2002-07-16  4:04         ` Maciej W. Rozycki
  1 sibling, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  4:04 UTC (permalink / raw)
  To: cgd; +Cc: rsandifo, Thiemo Seufer, gcc-patches, binutils

On 15 Jul 2002 cgd@broadcom.com wrote:

> I do think it's reasonable and probably desirable to support (can you
> hear the maniacal laughing, too?):
> 
> 	-march=mips1

 Which already exists. ;-)

> (in the NWO would that be mipsisa1. 8-)

 The name doesn't really matter, but such an alias may exist for
uniformity with mipsisa32 and mipsisa64.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:01     ` Thiemo Seufer
       [not found]       ` <mailpost.1026755685.506@news-sj1-1>
  2002-07-16  2:40       ` Richard Sandiford
@ 2002-07-16  4:17       ` Maciej W. Rozycki
  2 siblings, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  4:17 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Richard Sandiford, gcc-patches, binutils

On Mon, 15 Jul 2002, Thiemo Seufer wrote:

> There seems to be some misconception about the term 'ABI', maybe
> because the current -mabi=FOO option basically means "select calling
> conventions and register sizes". But an ABI is a much more powerful
> concept than pushing a few compiler options. It defines a platform
> over a variety of hardware which allows to run the same binary code.

 As I already stated, the compromise might be to add an option to select
the code conventions regardless of the ABI and then make all the "-mabi="
options strict, i.e. select both a convention and an ISA and be
incompatible with both "-march=" and the convention selection option (bail
out if specified). 

> > I agree that might be true for embedded configs.  But like Maciej
> > said, it could be useful to have a default ABI for hosted toolchains
> > like mips64-linux-gnu.  It seems reasonable that anyone using such
> > an assembler would be at least try to write ABI-conformant code.
> 
> I don't know about embedded configs. Just have a look at the linux
> kernel. I claim it has nearly no assembly code which could be written
> in an ABI-conformant way, with few performance improvements in assembly
> as an exception.

 The kernel is special -- it's not a real target for a toolchain (it
doesn't even use PIC for MIPS).  Think e.g. glibc which uses assembly
directly here and there. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:24         ` cgd
  2002-07-15 12:51           ` Thiemo Seufer
@ 2002-07-16  4:45           ` Maciej W. Rozycki
  2002-07-16  5:31           ` Richard Sandiford
  2 siblings, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16  4:45 UTC (permalink / raw)
  To: cgd; +Cc: ica2_ts, Richard Sandiford, gcc-patches, binutils

On 15 Jul 2002 cgd@broadcom.com wrote:

> There's use for it: people building e.g. userland binary distributions
> would want it, and would encourage users building e.g. RPMs to use it
> so they didn't have to remember the exact ISA to use to get things
> right.

 The distributions are the least trouble.  If sane, they have a global
configuration file that specifies various options, including C flags.  
E.g. I have all configurations set up in ~/.rpmrc and it currently
includes appropriate flags for "alpha", "i386", "i486", "i586", "i686" and
"mipsel".  Depending on which of these CPUs I select when building a
package, the toolchain receives appropriate flags.  Of course, a package
built for "i686" might not necessarily run on an i386 CPU (and at least
one distribution I know of makes an active use of this property).

 Since my "mipsel" configuration has to run on an R3400 chip, it only
specifies "-pipe -O2 -fomit-frame-pointer", but if I needed an entry for a
better MIPS CPU entry I would simply add it.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  3:54     ` Maciej W. Rozycki
@ 2002-07-16  4:47       ` Mark D. Baushke
  2002-07-16 11:33         ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Mark D. Baushke @ 2002-07-16  4:47 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Richard Sandiford, gcc-patches, binutils

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> On 15 Jul 2002, Richard Sandiford wrote:
> 
> > It might also be nice to have a --with-abi configure option,
> > although that's something we could add later...
> 
>  I'm not sure that is desireable -- I think the default ABI would best be
> selectable with the target triple.  Like with "mips64abin32-*-*" or so.

Having an unambiguous default ABI is desirable. If the name of the
compiler is mips64-elf-gcc or mipsisa32-elf-gcc, then there should only
be one ABI that defaults for each of those and it should not depend on
how the toolchain was configured and built. Otherwise, users might need
to always specify the ABI they want to use for every compile and that
would be tedious and prone to errors.

> > The main difficulty with dropping the ABI selection entirely
> > is: how do you select between the 32-bit and 64-bit versions
> > of the EABIs?  mipstx39-elf-gcc generates 32-bit EABI code
> > by default.  What happens if you select a 64-bit processor?
> > Options I can see:
> > 
> > 1. Stick with the idea in the patch I sent.  Selecting a 64-bit
> >    processor would usually select the 64-bit EABI, but adding
> >    -mgp32 forces the 32-bit version.
> > 
> > 2. Reverse of (1).  You get the 32-bit version of the EABI
> >    unless you use -mgp64.
> > 
> > 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
> >    the 32-bit version unless you use -mabi=eabi64.
> 
>  The last option seems the cleanest to me.  With your changes, it would
> permit selecting a default ABI when configuring for certain embedded
> targets as well (though I'm not sure how useful it would be in practice at
> the moment, since I am not an embedded user).

Speaking as an embedded user, any of the three options work. The first
one has the advantage of working even if you happen to have an old
version of the toolchain around by accident.

For the above choices, my order of preference would be: (3), (2), (1).
However, I think there needs to be at least one release that serves as
a transitional introduction if (3) is chosen.

Richard Sandiford <rsandifo@redhat.com> writes:
> 
> Eric Christopher <echristo@redhat.com> writes:
> > > > I took my cue from R3000 and R4000, which were the standard before.
> > > 
> > > So, historically, those defines _seem_ to be used less as 'processor'
> > > defines and more as 'GPR size' defines, at least looking at the way
> > > GCC defined them in say 3.0.x.
> > 
> > It was annoying too. There _were_ preprocessor directives for mips and
> > mips64.. anyhow
> 
> Ugh.  Ok, I'll keep _R3000 & _R4000 as they are now, and add the
> _MIPS_ARCH and _MIPS_TUNE that Chris suggested.

That is good news.

> Question: if gcc treats two processors as the same for scheduling,
> should they have the same _MIPS_ARCH and _MIPS_TUNE value?  Like,
> should -march=r2000 and -march=r3000 set _MIPS_ARCH to the same
> value (_MIPS_R3000?) to reflect what GCC's doing, or should there
> be separate _MIPS_R2000 and _MIPS_R3000 defines?  How about
> -mtune= and _MIPS_TUNE?

A ask a hard question...

I would have no significant problems with _MIPS_R2000 and _MIPS_R3000
using the same value rather than being independent if that were necessary.

However, I think that if both symbols need to exist, it might be useful
to have distinct values for them if possible.

With regard to strictness of the ABI, be advised that kernel code may
sometimes need to pragmatically run using o32 mode but still have access
to cache and other non-conformant ISA instructions... For example, for
space reasons in the embedded world, it is often the case that the
kernel will want to be run in -mips2 mode adding what cpu cache
instructions are required, but otherwise able to use exactly the same
library code as is being used by non-privileged user code.

	-- Mark

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-15 11:24         ` cgd
  2002-07-15 12:51           ` Thiemo Seufer
  2002-07-16  4:45           ` Maciej W. Rozycki
@ 2002-07-16  5:31           ` Richard Sandiford
  2002-07-16 11:39             ` Eric Christopher
  2002-07-18 14:44             ` Thiemo Seufer
  2 siblings, 2 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-16  5:31 UTC (permalink / raw)
  To: cgd; +Cc: ica2_ts, gcc-patches, binutils

[Answering two messages together]

cgd@broadcom.com writes:
> At Mon, 15 Jul 2002 17:54:45 +0000 (UTC), "Thiemo Seufer" wrote:
> > There seems to be some misconception about the term 'ABI', maybe
> > because the current -mabi=FOO option basically means "select calling
> > conventions and register sizes". But an ABI is a much more powerful
> > concept than pushing a few compiler options. It defines a platform
> > over a variety of hardware which allows to run the same binary code.

Hmm... I thought "o32" was a term that SGI invented.  And (going
from the n32 handbook and SGI's cc) their idea of "o32" includes
the ability to run MIPS II code.

Granted, the System V supplement says:

    Some processors might support the MIPS I ISA as a subset, providing
    additional instructions or capabilities, e.g., the R6000 processor.
    Programs that use those capabilities explicitly do not conform to
    the MIPS ABI.

but does -mabi=32 select the ABI defined there, or does it
work like SGI's -32 option?  I assumed the latter.

As for the other ABIs: I don't know whether o64 was ever formally
defined.  The Cygnus EABI spec doesn't mention any architecture
restrictions.  The MIPS EABI (at least in the draft I have)
explicitly allows you to pick an ISA.  n32 & n64 allow
MIPS III or MIPS IV.

> I'm wondering if the right thing to do here is have flags like
> -mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...

I wonder whether it would be clearer to have a special -march
argument.  Something like -mabi=XXX -march=from-abi?  It should
make the multilib matching easier as well.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  2:46     ` Maciej W. Rozycki
@ 2002-07-16  8:01       ` Paul Koning
  2002-07-16 11:01         ` Maciej W. Rozycki
  0 siblings, 1 reply; 97+ messages in thread
From: Paul Koning @ 2002-07-16  8:01 UTC (permalink / raw)
  To: macro; +Cc: gcc-patches, binutils

>>>>> "Maciej" == Maciej W Rozycki <macro@ds2.pg.gda.pl> writes:

 Maciej> There is no need, either, as there are "-march=mips1",
 Maciej> etc. equivalents, and specifying "-march=3000 -march=mips2"
 Maciej> is obviously incorrect for anyone...

Actually, it isn't.  By the usual rules, if you mention a switch more
than once, the last occurrence is in effect.  So this should be
equivalent simply to saying -march=mips2.

That rule is necessary to allow makefiles to set options that are
generally in effect but can be overridden when needed.

	  paul

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  8:01       ` Paul Koning
@ 2002-07-16 11:01         ` Maciej W. Rozycki
  0 siblings, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-16 11:01 UTC (permalink / raw)
  To: Paul Koning; +Cc: gcc-patches, binutils

On Tue, 16 Jul 2002, Paul Koning wrote:

>  Maciej> There is no need, either, as there are "-march=mips1",
>  Maciej> etc. equivalents, and specifying "-march=3000 -march=mips2"
>  Maciej> is obviously incorrect for anyone...
> 
> Actually, it isn't.  By the usual rules, if you mention a switch more
> than once, the last occurrence is in effect.  So this should be
> equivalent simply to saying -march=mips2.

 I might have been unclear: with "-march=3000 -march=mips2" it is as you
describe, with "-march=3000 -mips2" one might not expect it as it's not
obvious the two options are of the same class.

> That rule is necessary to allow makefiles to set options that are
> generally in effect but can be overridden when needed.

 Certainly. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  4:47       ` Mark D. Baushke
@ 2002-07-16 11:33         ` Eric Christopher
       [not found]           ` <mailpost.1026843855.9110@news-sj1-1>
  0 siblings, 1 reply; 97+ messages in thread
From: Eric Christopher @ 2002-07-16 11:33 UTC (permalink / raw)
  To: Mark D. Baushke
  Cc: Maciej W. Rozycki, Richard Sandiford, gcc-patches, binutils


> Having an unambiguous default ABI is desirable. If the name of the
> compiler is mips64-elf-gcc or mipsisa32-elf-gcc, then there should only
> be one ABI that defaults for each of those and it should not depend on
> how the toolchain was configured and built. Otherwise, users might need
> to always specify the ABI they want to use for every compile and that
> would be tedious and prone to errors.
> 

I agree. I feel that setting the abi at configure time isn't even under
consideration. It would be confusing and cause more problems than this
patch is fixing.

> > > 
> > > 1. Stick with the idea in the patch I sent.  Selecting a 64-bit
> > >    processor would usually select the 64-bit EABI, but adding
> > >    -mgp32 forces the 32-bit version.
> > > 
> > > 2. Reverse of (1).  You get the 32-bit version of the EABI
> > >    unless you use -mgp64.
> > > 
> > > 3. Add eabi32, eabi64, meabi32 and meabi64 to -mabi.  You get
> > >    the 32-bit version unless you use -mabi=eabi64.

> Speaking as an embedded user, any of the three options work. The first
> one has the advantage of working even if you happen to have an old
> version of the toolchain around by accident.
> 
> For the above choices, my order of preference would be: (3), (2), (1).
> However, I think there needs to be at least one release that serves as
> a transitional introduction if (3) is chosen.
> 

I want to keep #1 around. It just seems to make the best sense for me,
and we might as well keep as much backward compatibility as possible :)


> A ask a hard question...
> 
> I would have no significant problems with _MIPS_R2000 and _MIPS_R3000
> using the same value rather than being independent if that were necessary.
> 
> However, I think that if both symbols need to exist, it might be useful
> to have distinct values for them if possible.

I can agree with this...

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  5:31           ` Richard Sandiford
@ 2002-07-16 11:39             ` Eric Christopher
  2002-07-18 14:44             ` Thiemo Seufer
  1 sibling, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-16 11:39 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: cgd, Thiemo Seufer, gcc-patches, binutils


> 
> > I'm wondering if the right thing to do here is have flags like
> > -mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...
> 
> I wonder whether it would be clearer to have a special -march
> argument.  Something like -mabi=XXX -march=from-abi?  It should
> make the multilib matching easier as well.

This isn't a bad idea. Maybe a -mdeduce-arch option...

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  3:23             ` Richard Sandiford
@ 2002-07-16 12:16               ` Eric Christopher
       [not found]               ` <mailpost.1026812813.25035@news-sj1-1>
  1 sibling, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-16 12:16 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: cgd, gcc-patches, binutils, thorpej


> Ugh.  Ok, I'll keep _R3000 & _R4000 as they are now, and add the
> _MIPS_ARCH and _MIPS_TUNE that Chris suggested.
> 
> Question: if gcc treats two processors as the same for scheduling,
> should they have the same _MIPS_ARCH and _MIPS_TUNE value?  Like,
> should -march=r2000 and -march=r3000 set _MIPS_ARCH to the same
> value (_MIPS_R3000?) to reflect what GCC's doing, or should there
> be separate _MIPS_R2000 and _MIPS_R3000 defines?  How about
> -mtune= and _MIPS_TUNE?

Not the same _MIPS_ARCH for sure, the same _MIPS_TUNE possibly. There
are arguments either way :)

Probably should separate them out so we make changes as little as
possible.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]           ` <mailpost.1026757359.1135@news-sj1-1>
@ 2002-07-16 17:24             ` cgd
  2002-07-18 12:48               ` Thiemo Seufer
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-16 17:24 UTC (permalink / raw)
  To: ica2_ts; +Cc: rsandifo, gcc-patches, binutils

At Mon, 15 Jul 2002 18:22:39 +0000 (UTC), "Thiemo Seufer" wrote:
> > If the CPU aliases for the ISA aren't the minimal set for the ISA,
> > that sounds like a very good reason for somebody to go off and do
> > something better, i.e., create "actual ISA" definitions.
> > 
> > I believe that at least mipsisa32 and mipsisa64 -- ISAs which are
> > really ISAs in the code, rather than being CPUs -- are correct.  8-)
> 
> Are the CP0 and TLB instructions really covered by the ISA there?

I have never actually seen a complete and canonical MIPS ISA
definition pre-dating MIPS32/MIPS64.


> > And, in that view, -mabi=foo probably shouldn't change the ISA (and
> > definitely shouldn't downgrade it).
> 
> My idea is to get sane defaults from the ABI definition.
> 
> 	gcc -mabi=FOO
> 
> should create ABI conformant code, while
> 
> 	gcc -mabi=FOO -march=BAR
> 
> loosens the ABI restrictions in order to allow BAR opcodes.
> AFAICS this fulfils the "least surprise" priciple for hosted
> systems, and the embedded world can live with it, too.

Since I'm a bit behind on this discussion, I'll just have to risk
reiterating points already made in response to your msg by others:

That may be appropriate for "mips-linux" tools.

It's probably not appropriate for "mipsisa32-linux" tools, since
somebody configured the tools naming a specific architecture that they
wanted to build for by default.



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]             ` <mailpost.1026759415.2116@news-sj1-1>
@ 2002-07-16 17:34               ` cgd
  2002-07-16 18:56                 ` H. J. Lu
  2002-07-18 13:57                 ` Thiemo Seufer
  0 siblings, 2 replies; 97+ messages in thread
From: cgd @ 2002-07-16 17:34 UTC (permalink / raw)
  To: ica2_ts; +Cc: Richard Sandiford, gcc-patches, binutils

At Mon, 15 Jul 2002 18:56:55 +0000 (UTC), "Thiemo Seufer" wrote:
> > However, it is much more useful to people creating optimized code to
> > be able to generate code for specific ISAs,
> 
> For people who create, maintain and use an whole OS this would
> be horrible. :-)

People who create and maintain a whole OS often do so via scripts,
which allow them to set defaults for things like this.

So, once you ship that OS to customers, you expect them to be able to
say "gcc -mabi=XXX" and have it do the right thing for them.

Similarly, if I ship mipsisa64sb1-linux tools to customers, my strong
hope is that they won't need to name -march=sb1 on every command
line... because that's the whole bloody reason a specific target other
than mips-linux was used for the build.


> > If they're using a target like, say, mipsisa64-linux, then they almost
> > certainly want -mabi=X to get them the ABI 'X' for binary format,
> > calling conventions, etc., but with use of MIPS64 instructions.
> > 
> > If they're using mipsisa64sb1-linux, they probably expect built-in
> > support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
> > well, regardless of the ABI they choose on the command line.
> 
> If all of the hardware for this target supports these, ok.
> But the ISA pre-selection should then be done in the target specific
> code and not globally.

I don't know that there's such a thing as "all of the hardware that
this target supports," really.

Given the flags you can pass to the compiler and assembler, you can
use the MIPS tools to generate code for any target you want, pretty
much.


> > I'm wondering if the right thing to do here is have flags like
> > -mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...
> 
> -mabi=isa64sb1-with-many-wonderful-extensions ;-)

I'd argue that in the case where you specify a -march flag or specify
a default architecture as part of the target triple, you really want
"-mabi=X" to mean "X with those extensions which you have implied."

If you want strict conformance to ABI 'foo' in that situation, you
want a special flag that says that.



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]               ` <mailpost.1026812813.25035@news-sj1-1>
@ 2002-07-16 17:48                 ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-16 17:48 UTC (permalink / raw)
  To: rsandifo; +Cc: Eric Christopher, gcc-patches, binutils, thorpej

At Tue, 16 Jul 2002 09:46:53 +0000 (UTC), "Richard Sandiford" wrote:
> Question: if gcc treats two processors as the same for scheduling,
> should they have the same _MIPS_ARCH and _MIPS_TUNE value?  Like,
> should -march=r2000 and -march=r3000 set _MIPS_ARCH to the same
> value (_MIPS_R3000?) to reflect what GCC's doing, or should there
> be separate _MIPS_R2000 and _MIPS_R3000 defines?  How about
> -mtune= and _MIPS_TUNE?

I'd say, if GCC recognizes different names for different processors,
it should use different defines for them (for both arch and tune).

The theory is that the application coder may know something (to be
expressed in asms) more than the compiler does.

r2k and r3k might be historical special cases, I don't know if there's
any practical difference between them for the purposes of such
defines...  but for consistency, they should probably be given
different defines, IMO.


(Another way to look at this issue is, don't add arch names to the FSF
GCC unless users really may want to tell the difference.  8-)



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
       [not found]           ` <mailpost.1026843855.9110@news-sj1-1>
@ 2002-07-16 18:18             ` cgd
  2002-07-17  2:19               ` Maciej W. Rozycki
  2002-07-17 15:18               ` Eric Christopher
  0 siblings, 2 replies; 97+ messages in thread
From: cgd @ 2002-07-16 18:18 UTC (permalink / raw)
  To: echristo
  Cc: Mark D. Baushke, Maciej W. Rozycki, Richard Sandiford,
	gcc-patches, binutils

At Tue, 16 Jul 2002 18:24:15 +0000 (UTC), "Eric Christopher" wrote:
> > Having an unambiguous default ABI is desirable. If the name of the
> > compiler is mips64-elf-gcc or mipsisa32-elf-gcc, then there should only
> > be one ABI that defaults for each of those and it should not depend on
> > how the toolchain was configured and built. Otherwise, users might need
> > to always specify the ABI they want to use for every compile and that
> > would be tedious and prone to errors.
> 
> I agree. I feel that setting the abi at configure time isn't even under
> consideration. It would be confusing and cause more problems than this
> patch is fixing.

I hope you mean "via a --with-foo" or "via target name."

I thought we mostly agreed that having a given target triple imply a
default ABI (via code in config*) was the right thing.  To me, that's
"at configure time" too, but the ABI isn't directly selectable by the
user.


cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 17:34               ` cgd
@ 2002-07-16 18:56                 ` H. J. Lu
  2002-07-16 18:57                   ` cgd
  2002-07-18 13:57                 ` Thiemo Seufer
  1 sibling, 1 reply; 97+ messages in thread
From: H. J. Lu @ 2002-07-16 18:56 UTC (permalink / raw)
  To: cgd; +Cc: ica2_ts, Richard Sandiford, gcc-patches, binutils

On Tue, Jul 16, 2002 at 05:29:01PM -0700, cgd@broadcom.com wrote:
> 
> Similarly, if I ship mipsisa64sb1-linux tools to customers, my strong
> hope is that they won't need to name -march=sb1 on every command
> line... because that's the whole bloody reason a specific target other
> than mips-linux was used for the build.

Does gcc support that? It is a nice thing to have. However, given the
varieties of MIPS cpus, I don't know if it is feasible. Maybe something
like --with-default-target=xxx.


H.J.

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 18:56                 ` H. J. Lu
@ 2002-07-16 18:57                   ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-16 18:57 UTC (permalink / raw)
  To: H. J. Lu; +Cc: ica2_ts, Richard Sandiford, gcc-patches, binutils

At Tue, 16 Jul 2002 18:51:38 -0700, H. J. Lu wrote:
> On Tue, Jul 16, 2002 at 05:29:01PM -0700, cgd@broadcom.com wrote:
> > 
> > Similarly, if I ship mipsisa64sb1-linux tools to customers, my strong
> > hope is that they won't need to name -march=sb1 on every command
> > line... because that's the whole bloody reason a specific target other
> > than mips-linux was used for the build.
> 
> Does gcc support that? It is a nice thing to have. However, given the
> varieties of MIPS cpus, I don't know if it is feasible. Maybe something
> like --with-default-target=xxx.

Uh, there are _lots_ of different cpu types supported in config.sub
for mips.

Right now the configury for mips linux looks like:

mips*-*-linux*)                         # Linux MIPS, either endian.
        tm_file="dbxelf.h elfos.h svr4.h linux.h mips/linux.h"
        case $machine in
        mipsisa32*-*)
                tm_file="$tm_file mips/isa32-linux.h"
                target_cpu_default="MASK_SOFT_FLOAT"
                ;;
        esac
        tmake_file="t-slibgcc-elf-ver t-linux mips/t-linux"
        extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o
        crtendS.o"
        gnu_ld=yes
        gas=yes
        if test x$enable_threads = xyes; then
                thread_file='posix'
        fi
        ;;

that plus upcoming changes from Eric or Richard (i forget which) to
make default CPU done via a define rather than string match on the
name make it really easy.

There's something to be said for trying to do the CPU name -> default
ISA/arch selection more generically (i.e., so they're OS-independent),
but in the absence of that it would be obvious where to poke the right
code in.



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 18:18             ` cgd
@ 2002-07-17  2:19               ` Maciej W. Rozycki
  2002-07-17 15:18               ` Eric Christopher
  1 sibling, 0 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-17  2:19 UTC (permalink / raw)
  To: cgd; +Cc: echristo, Mark D. Baushke, Richard Sandiford, gcc-patches, binutils

On 16 Jul 2002 cgd@broadcom.com wrote:

> I thought we mostly agreed that having a given target triple imply a
> default ABI (via code in config*) was the right thing.  To me, that's
> "at configure time" too, but the ABI isn't directly selectable by the
> user.

 That's my understanding of the term as well.  A user selects the ABI with
an appropriate target triple.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 18:18             ` cgd
  2002-07-17  2:19               ` Maciej W. Rozycki
@ 2002-07-17 15:18               ` Eric Christopher
  1 sibling, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-17 15:18 UTC (permalink / raw)
  To: cgd
  Cc: Mark D. Baushke, Maciej W. Rozycki, Richard Sandiford,
	gcc-patches, binutils


> I hope you mean "via a --with-foo" or "via target name."
> 
> I thought we mostly agreed that having a given target triple imply a
> default ABI (via code in config*) was the right thing.  To me, that's
> "at configure time" too, but the ABI isn't directly selectable by the
> user.

Yes.

I'm not going to change the interfaces to have:

mips64n64-elf
mips64n32-elf
mips64eabi-elf
...

For every target, and a --with-foo option isn't good either. This is
what multilibs are for :)

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* [Revised patch] Rework MIPS command-line handling
  2002-07-12 10:16 RFC & patch: Rework MIPS command-line handling Richard Sandiford
                   ` (3 preceding siblings ...)
  2002-07-14 10:43 ` Thiemo Seufer
@ 2002-07-18 12:44 ` Richard Sandiford
  2002-07-18 13:44   ` cgd
  2002-07-18 16:32   ` Thiemo Seufer
  4 siblings, 2 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-18 12:44 UTC (permalink / raw)
  To: gcc-patches, binutils
  Cc: cgd, Thiemo Seufer, Maciej W. Rozycki, Eric Christopher, Mark D. Baushke

[-- Attachment #1: Type: text/plain, Size: 11205 bytes --]

First, thanks to everyone who responded to my first message.
I've tried to incorporate the feedback into the patch below.

Brief summary of changes:

1) both gcc & gas now accept -march=mipsN
2) gcc defines _MIPS_ARCH and _MIPS_TUNE
3) ELF gccs will always pass an ABI option to the assembler
4) all configs now support -mabi
5) there is now a special 'from-abi' architecture
6) -mabi doesn't change the default architecture (but see below)
7) -march doesn't change the ABI (modulo 32/64-bit selection for EABIs)

More details:

1) Internally, gcc treats -mips1 and -march=mips1 like -march=r2000,
   and similarly for the other ISA levels.

   Question is, what are right values for _MIPS_ARCH and _MIPS_TUNE when
   you use a generic ISA?  It doesn't seem right for them to name a
   processor when the command line and configuration don't specify one.
   So in the patch I've just set them to 0.  It gives users a way of
   distinguishing between -march=mipsN and -march=<processor>, should
   they want to.

2) Each processor has a macro of the form _MIPS_<name>.  As suggested,
   each known processor has distinct macro, even if GCC treats them
   the same way internally.  So there's both a _MIPS_R2000 and
   a _MIPS_R3000, for example.

   Not the biggest issue, I know, but is _MIPS_<foo> OK for the
   processor macros?  I guess other alternatives would be
   _MIPS_PROCESSOR_<foo> or _PROCESSOR_<foo>.

   I guess the values of these macros ought not to change between
   releases, just in case someone stores _MIPS_ARCH in a variable
   in one compilation unit and reads it in another, compiled with
   a different version of gcc.  So I've used a (lame!) convention
   for giving each entry a unique value.  See comment above
   mips_cpu_info_table[] in mips.c for details.

   This should also make it easier to check for a range of
   processors, such as members of a family that have different
   tuning characteristics but the same basic ISA.

3) There seemed to be general agreement that we should record the
   default ABI in ELF objects.  We could teach GAS about the default
   ABI for each target (I left this option open in my earlier patch).
   But I'd really rather not do it that way: it would mean duplicating
   a whole load of config.gcc logic, and it could lead to subtle
   incompatabilities between GCC and GAS in future.

   In this case, I'd rather use gcc specs.  This stands more chance of
   working with non-GAS targets and earlier binutils releases.  It's
   also much cleaner code-wise.  All I'm talking about is

	%{!mabi=*: %(asm_abi_default_spec)}

   in ASM_SPEC (see comments in patch for why ASM_SPEC instead of
   the others).

   There's still the problem that some OSes don't understand
   E_MIPS_ABI_O32.  I've added a way of disabling it for specific
   targets.  So far, irix is the only one to take advantage.

4) After these changes, there doesn't seem any reason to limit
   -mabi to the current handful of targets.  I often hack it in
   to the other targets for testing, and I'm sure others do too.

   Safety might be one concern.  But since ELF targets will always
   pass an ABI flag to the assembler, there should be little chance of
   accidents there.  For COFF targets, the user will get an error if
   they use -mabi with an assembler that doesn't support it (see
   changes to ASM_SPEC).

5) I prefer '-march=from-abi' over '-mstrict-abi' and '-mdeduce-arch'
   (which were the other suggestions I saw).  For one thing, it brings
   all architecture-changing stuff under -march, but more importantly,
   a configuration can then have "from-abi" as its default architecture.
   Which leads on to...

6) The consensus seemed to be that, when using a configuration associated
   with a particular ISA or processor, we should try to stick to the
   default where possible.  So "mips64orion-elf-gcc -mabi=32" would
   generate 32-bit 4600 code rather than than MIPS I code.

   Then, we would only deviate from the default architecture when that
   architecture is a 32-bit one, and the selected ABI requires 64-bit
   registers.  For example, "mipstx39-elf -mabi=o64".  For configs
   like mipstx39-elf that are associated with a particular ISA, I
   think specifying an incompatible ABI should be a hard error.
   The user can of course say "mipstx39-elf -mabi=o64 -mips3" if
   that's what they truly mean.

   The question is, how do people see configs like mips-elf and
   mips64-elf?  Is mips-elf "a target for generating MIPS I code",
   or (by a weaker definition) "a target that generates 32-bit code
   by default".  Similarly mips64-elf, MIPS III and 64-bit code.

   According to the stronger definition, mips-elf-gcc would give
   an error if you pass -mabi=o64 without changing the architecture.
   According to the weaker definition, it should switch to MIPS III,
   since -mabi=o64 obviously overrides the "32-bit" default.  The
   stronger definition implies the default should be -march=mips1,
   while the weaker one implies it should be -march=from-abi.

   Same sort of question for mips64-elf.

   At the moment I'm leaning towards the weaker definition, so the patch
   makes "from-abi" the default for both.  Specifically, instead of
   setting MIPS_ISA_DEFAULT to 3 in elf64.h and 1 in mips.h, there is
   just a default definition of MIPS_CPU_STRING_DEFAULT as "from-abi".
   That means the default behaviour is to select the "most compatible"
   architecture for the given ABI, as Thiemo suggested.

7) [Changing ABI based on architecture.]  This time round there's no
   logic to impliclty switch between {n32,n64,o64} and {o32}.  The
   consensus seemed to be that it should at least produce a warning.
   But if we pass the default ABI to GAS using specs, we would
   also have to use specs to override the default, since GAS can't
   tell the difference between a user-supplied or gcc-supplied option.
   So this time I've removed that functionality entirely.

   The behaviour for the EABIs is the same as before: selecting a 64-bit
   architecture implicitly selects 64-bit code, but you can use -mgp32
   to get 32-bit code instead.  Thus 'mipsisa32-elf-gcc -mips64' selects
   64-bit MEABI and "mipsisa64-elf-gcc -mips32" selects 32-bit MEABI.

GAS patch tested as before.  GCC patch tested on mips64-elf with
and without patched GAS.  Irix bootstrap still ongoing.

How does this version look?

Richard

[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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: GAS patch --]
[-- Type: text/x-patch, Size: 61342 bytes --]

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	18 Jul 2002 13:59:27 -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	18 Jul 2002 13:59:27 -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	18 Jul 2002 13:59:27 -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*)
+ changequote(,)dnl
+ 	    mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*64//' -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_cpu} 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	18 Jul 2002 13:59:28 -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));
  \f
  /* 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));
  \f
  /* 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
- }
- \f
  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;
  }
+ \f
+ /* 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, ABI 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)
*** 13709,13882 ****
  
  /* 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;
--- 13429,13603 ----
  
  /* CPU name/ISA/number mapping table.
  
!    Entries are grouped by type.  The first mention of a CPU_* value
!    is taken to be the canonical entry for that CPU.  */
  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;
  }
--- 13606,13724 ----
  
    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;
  }
+ \f
+ 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	18 Jul 2002 13:59:28 -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	18 Jul 2002 13:59:28 -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.*

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: GCC patch --]
[-- Type: text/x-patch, Size: 58969 bytes --]

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	18 Jul 2002 15:13:24 -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,7017 ----
  
  @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 recognized
! generic ISAs are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4},
! @samp{mips32} and @samp{mips64}.  Recognized processors 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 (MIPS I for 32-bit
! ABIs and MIPS III 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}.
! 
! @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.
  
  @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
--- 7025,7045 ----
  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
--- 7055,7086 ----
  @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	18 Jul 2002 15:13:24 -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	18 Jul 2002 15:13:25 -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	18 Jul 2002 15:13:25 -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	18 Jul 2002 15:13:25 -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	18 Jul 2002 15:13:25 -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	18 Jul 2002 15:13:25 -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	18 Jul 2002 15:13:25 -0000
*************** enum block_move_type {
*** 118,123 ****
--- 118,151 ----
    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;
+ 
+   /* A macro used to identify the processor, used as a possible value
+      for _MIPS_ARCH and _MIPS_TUNE.  Null if this entry describes a
+      generic ISA rather than a specific processor.  */
+   const char *macro;
+ 
+   /* The value of MACRO.  For compatability reasons, the macros
+      mustn't change value between releases, so we don't generate
+      them automatically.  Null if MACRO is null, or if the value
+      is defined in another entry.  */
+   const char *macro_value;
+ 
+   /* 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 */
--- 174,185 ----
*************** extern GTY(()) rtx mips_load_reg2;	/* 2n
*** 167,172 ****
--- 193,201 ----
  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,351 ****
--- 371,388 ----
  #define TUNE_MIPS5000               (mips_tune == PROCESSOR_R5000)
  #define TUNE_MIPS6000               (mips_tune == PROCESSOR_R6000)
  
+ /* Set a preprocessor macro NAME to PROC's macro, or to 0 if PROC
+    represents a generic ISA.  */
+ #define MIPS_CPP_SET_PROCESSOR(NAME, PROC)			\
+   builtin_define_with_value					\
+     ((NAME), (PROC)->macro == 0? "0" : (PROC)->macro, 0)
+ 
  /* Target CPU builtins.  */
  #define TARGET_CPU_CPP_BUILTINS()				\
    do								\
      {								\
+       const struct mips_cpu_info *p;				\
+ 								\
        builtin_assert ("cpu=mips");				\
        builtin_define ("__mips__");     				\
        builtin_define ("_mips");					\
*************** 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,426 ----
        if (TARGET_MIPS16)					\
  	  builtin_define ("__mips16");				\
  								\
+       /* Define a macro for each recognized processor.  */	\
+       for (p = mips_cpu_info_table; p->name != 0; p++)		\
+ 	if (p->macro_value != 0)				\
+ 	  builtin_define_with_value (p->macro, p->macro_value, 0); \
+ 								\
+       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
--- 650,660 ----
  #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
--- 704,711 ----
  #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,				\
--- 724,741 ----
  #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 ****
--- 763,778 ----
  #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;
--- 968,974 ----
  /* 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
--- 977,1019 ----
  #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 "\
--- 1061,1071 ----
  #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)"
  
--- 1074,1082 ----
  %(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)"
--- 1147,1152 ----
*************** 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
  
--- 1177,1188 ----
    { "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	18 Jul 2002 15:13:26 -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,627 ----
    NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  };
  \f
+ /* A table describing all the processors gcc knows about.  The canonical
+    names will be matched in the order listed.  The first mention of an
+    ISA level is taken as the canonical name for that ISA.
+ 
+    It's probably not a good idea to use a straight 1, 2, 3 ... enumeration
+    for the processor macros, since it might lead to clashes when new ports
+    are contributed.  So the convention used here is that the five least
+    significant decimal digits are the processor's numerical designation.
+    Since several processors have the same designation, the next four
+    decimal digits can describe up to two letters.  As a prefix 'a' = 01,
+    'b' = 02, etc.  If the letter is a suffix, add 30 to this number.
+    For example, 'vr5000' = 221805000 and '4kp' = 4604000.  There's
+    no need to use prefixes for generic "r<number>" entries.
+ 
+    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", 0, 0, PROCESSOR_R3000, 1 },
+   { "mips2", 0, 0, PROCESSOR_R6000, 2 },
+   { "mips3", 0, 0, PROCESSOR_R4000, 3 },
+   { "mips4", 0, 0, PROCESSOR_R8000, 4 },
+   { "mips32", 0, 0, PROCESSOR_R4KC, 32 },
+   { "mips64", 0, 0, PROCESSOR_R5KC, 64 },
+ 
+   /* MIPS I */
+   { "r3000", "_MIPS_R3000", "3000", PROCESSOR_R3000, 1 },
+   { "r2000", "_MIPS_R2000", "2000", PROCESSOR_R3000, 1 }, /* = r3000 */
+   { "r3900", "_MIPS_R3900", "3900", PROCESSOR_R3900, 1 },
+ 
+   /* MIPS II */
+   { "r6000", "_MIPS_R6000", "6000", PROCESSOR_R6000, 2 },
+ 
+   /* MIPS III */
+   { "r4000", "_MIPS_R4000", "4000", PROCESSOR_R4000, 3 },
+   { "vr4100", "_MIPS_VR4100", "221804100", PROCESSOR_R4100, 3 },
+   { "vr4300", "_MIPS_VR4300", "221804300", PROCESSOR_R4300, 3 },
+   { "r4400", "_MIPS_R4400", "4400", PROCESSOR_R4000, 3 }, /* = r4000 */
+   { "r4600", "_MIPS_R4600", "4600", PROCESSOR_R4600, 3 },
+   { "orion", "_MIPS_R4600", 0, PROCESSOR_R4600, 3 }, /* = r4600 */
+   { "r4650", "_MIPS_R4650", "4650", PROCESSOR_R4650, 3 },
+ 
+   /* MIPS IV */
+   { "r8000", "_MIPS_R8000", "8000", PROCESSOR_R8000, 4 },
+   { "vr5000", "_MIPS_VR5000", "221805000", PROCESSOR_R5000, 4 },
+ 
+   /* MIPS 32 */
+   { "4kc", "_MIPS_4KC", "3304000", PROCESSOR_R4KC, 32 },
+   { "4kp", "_MIPS_4KP", "4604000", PROCESSOR_R4KC, 32 }, /* = 4kc */
+ 
+   /* MIPS 64 */
+   { "5kc", "_MIPS_5KC", "3305000", PROCESSOR_R5KC, 64 },
+   { "20kc", "_MIPS_20KC", "3320000", PROCESSOR_R20KC, 64 },
+   { 0, 0, 0, 0, 0 }
+ };
+ \f
  /* 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 ();
  }
  \f
  /* 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;
  
--- 4991,5034 ----
    abort ();
  }
  \f
+ /* 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)
--- 5046,5183 ----
      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, ABI 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);
  }
  \f
  /* If we are optimizing the global pointer, emit the text section now and any
--- 6337,6343 ----
    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);
  }
  \f
  /* 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.
--- 10142,10261 ----
    /* NOTREACHED */
    return 0;
  }
+ \f
+ /* 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;
+ }
+ \f
  /* 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	Thu Jul 18 14:28:46 2002
***************
*** 0 ****
--- 1,53 ----
+ /* Check that certain preprocessor macros are defined, and do some
+    consistency checks.  */
+ /* { dg-do compile { target mips*-*-* } } */
+ 
+ /* Exactly one of these conditions must be true for ARCH, where ARCH
+    is _MIPS_ARCH or _MIPS_TUNE.  Add new checks as appropriate.  */
+ #define MIPS_ADD(ARCH)			\
+   (((ARCH) == 0)			\
+    + ((ARCH) == _MIPS_R2000)		\
+    + ((ARCH) == _MIPS_R3000)		\
+    + ((ARCH) == _MIPS_R3900)		\
+    + ((ARCH) == _MIPS_R6000)		\
+    + ((ARCH) == _MIPS_R4000)		\
+    + ((ARCH) == _MIPS_VR4100)		\
+    + ((ARCH) == _MIPS_VR4300)		\
+    + ((ARCH) == _MIPS_R4400)		\
+    + ((ARCH) == _MIPS_R4600)		\
+    + ((ARCH) == _MIPS_R4650)		\
+    + ((ARCH) == _MIPS_VR5000)		\
+    + ((ARCH) == _MIPS_R8000)		\
+    + ((ARCH) == _MIPS_4KC)		\
+    + ((ARCH) == _MIPS_4KP)		\
+    + ((ARCH) == _MIPS_5KC)		\
+    + ((ARCH) == _MIPS_20KC))
+ 
+ int f1[MIPS_ADD (_MIPS_ARCH) == 1 ? 1 : -1];
+ int f2[MIPS_ADD (_MIPS_TUNE) == 1 ? 1 : -1];
+ int f3[__mips_fpr == 32 || __mips_fpr == 64 ? 1 : -1];
+ 
+ /* 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);
+ }

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 17:24             ` cgd
@ 2002-07-18 12:48               ` Thiemo Seufer
  2002-07-18 13:09                 ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 12:48 UTC (permalink / raw)
  To: cgd; +Cc: rsandifo, gcc-patches, binutils

cgd@broadcom.com wrote:
[snip]
> > > I believe that at least mipsisa32 and mipsisa64 -- ISAs which are
> > > really ISAs in the code, rather than being CPUs -- are correct.  8-)
> > 
> > Are the CP0 and TLB instructions really covered by the ISA there?
> 
> I have never actually seen a complete and canonical MIPS ISA
> definition pre-dating MIPS32/MIPS64.

I have
"MIPS IV Instruction Set, Revision 3.2, By Charles Price, September 1995"
which fits well together with
"MIPS R10000 Microprocessor User's Manual"

The CP0, TLB, CACHE and ERET instructions are covered in the latter
as being CPU specific.

> > > And, in that view, -mabi=foo probably shouldn't change the ISA (and
> > > definitely shouldn't downgrade it).
> > 
> > My idea is to get sane defaults from the ABI definition.
> > 
> > 	gcc -mabi=FOO
> > 
> > should create ABI conformant code, while
> > 
> > 	gcc -mabi=FOO -march=BAR
> > 
> > loosens the ABI restrictions in order to allow BAR opcodes.
> > AFAICS this fulfils the "least surprise" priciple for hosted
> > systems, and the embedded world can live with it, too.
> 
> Since I'm a bit behind on this discussion, I'll just have to risk
> reiterating points already made in response to your msg by others:
> 
> That may be appropriate for "mips-linux" tools.

That's what I'm actually caring about. :-)

> It's probably not appropriate for "mipsisa32-linux" tools, since
> somebody configured the tools naming a specific architecture that they
> wanted to build for by default.

AFAICS this toolchain will have EABI(32) and MIPS32 as defaults.
This won't interfere with what I wrote.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-18 12:48               ` Thiemo Seufer
@ 2002-07-18 13:09                 ` Eric Christopher
  0 siblings, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-18 13:09 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: cgd, rsandifo, gcc-patches, binutils


> 
> AFAICS this toolchain will have EABI(32) and MIPS32 as defaults.
> This won't interfere with what I wrote.
> 

It'll be o32 actually.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  2:40       ` Richard Sandiford
@ 2002-07-18 13:36         ` Thiemo Seufer
  0 siblings, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 13:36 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

Richard Sandiford wrote:
[snip]
> > > So the way the GAS config stuff is structured, it will assume NO_ABI
> > > by default, since that seems sensible for most embedded configs,
> > > and won't lead to spurious "incompatible ABI" link failures.
> > 
> > Spurious? With some likeliness these are real incompatibilities.
> 
> Sure, it could catch real incompatibilities, but it could generate
> false positives too.  My point is that, before now, there has been
> no default ABI assumption for "mips-elf-as", either invoked directly,
> or through the GCC driver.

Now I understand the misconception: With "ABI", I meant binary
compatibility, while you primarily meant ELF header flags.

> It hasn't been necessary to think about
> ABI flags when assembling (to pick a trivial example):
> 
> version:
>         .asciz "version (2.10)"

AFAICS this is only true for mixing o32 and NoABI code. I don't
know how relevant this is in praxis.

> I'm not saying it's necessarily bad to have a default ABI for all
> configs, but I just feel that some users might think we're being
> a bit too pedantic.

Given that the "No ABI" case is a sort of o32 under the hood,
there's not much actual difference. Of course, requiring the header
flag will break link compatibility in the transition phase, but
it prevents "spurious" link failures furtheron.

[snip]
> > > One of the changes was that the default float register size would
> > > be worked out from -mgp32, -mgp64, -msingle-float, etc.  That was
> > > mostly for multilib convenience.
> > 
> > For embedded use, I assume. For hosted systems this should be done
> > by the ABI.
> 
> Well, -mabi isn't the only GCC option that changes the ABI.

But it should, for the sake of clarity. Changing the ABI by -mips1
is a relic from the time where -mabi=o32 was disfunctional.

> At the
> moment, you need -mgp32 to select between 32-bit and 64-bit code when
> an EABI is selected.  And we have the -msingle-float variations too.
> For example:
> 
>   -mgp32 -mabi=eabi                     => -mfp32
>   -mgp64 -mabi=eabi                     => -mfp64
>   -mgp64 -mabi=eabi -msingle-float      => -mfp32
> 
> (All supported combinations, I think.)

So if we had -mabi=eabi{32,64} we could get rid of -m[fg]p* options,
at least for the EABI case. I would prefer it this way, it gives better
abstraction without losing anything.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  3:57             ` Maciej W. Rozycki
@ 2002-07-18 13:43               ` Thiemo Seufer
  0 siblings, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 13:43 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: cgd, Richard Sandiford, gcc-patches, binutils

Maciej W. Rozycki wrote:
> On Mon, 15 Jul 2002, Thiemo Seufer wrote:
> 
> > Note that the MIPS II is a deviation from stock o32 ABI, the
> > linux-mips kernel emulates the necessary instructions on MIPS I
> > hardware. This means we have an o32-linux ABI there.
> 
>  Does it?  I haven't seen any code to emulate trap, branch likely, dword
> coprocessor transfer instructions.  What is emulated are only the ll and
> sc instructions, but they are only a small subset of MIPS II extensions
> which is never used by gcc, unlike the others.

You are right, only ll/sc are emulated.

> > > If they're using mipsisa64sb1-linux, they probably expect built-in
> > > support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
> > > well, regardless of the ABI they choose on the command line.
> > 
> > If all of the hardware for this target supports these, ok.
> > But the ISA pre-selection should then be done in the target specific
> > code and not globally.
> 
>  If a target triplet defines a CPU, it should always be used as the
> default for uniformity.

I agree.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-18 12:44 ` [Revised patch] " Richard Sandiford
@ 2002-07-18 13:44   ` cgd
  2002-07-18 18:12     ` Eric Christopher
  2002-07-19  2:53     ` Richard Sandiford
  2002-07-18 16:32   ` Thiemo Seufer
  1 sibling, 2 replies; 97+ messages in thread
From: cgd @ 2002-07-18 13:44 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher, Mark D. Baushke

> More details:
> 
> 1) Internally, gcc treats -mips1 and -march=mips1 like -march=r2000,
>    and similarly for the other ISA levels.
> 
>    Question is, what are right values for _MIPS_ARCH and _MIPS_TUNE when
>    you use a generic ISA?  It doesn't seem right for them to name a
>    processor when the command line and configuration don't specify one.
>    So in the patch I've just set them to 0.  It gives users a way of
>    distinguishing between -march=mipsN and -march=<processor>, should
>    they want to.

I would advise simply going with whatever the processor is, unless
you're going to create 'real' entries for the arches
(e.g. _PROCESSOR_MIPS1.)


> 2) Each processor has a macro of the form _MIPS_<name>.  As suggested,
>    each known processor has distinct macro, even if GCC treats them
>    the same way internally.  So there's both a _MIPS_R2000 and
>    a _MIPS_R3000, for example.
> 
>    Not the biggest issue, I know, but is _MIPS_<foo> OK for the
>    processor macros?  I guess other alternatives would be
>    _MIPS_PROCESSOR_<foo> or _PROCESSOR_<foo>.

Personlly, I don't like having MIPS in the name.  Many processors are
not, and have never been, made by "MIPS" (MTI).  There's something to
be said that they all (should be) MIPS architecture licensees, but,
well, if somebody other than a licensee wants to ue the back-end and
is close enough, it would be broken to force them to have MIPS in
their name.

I'm for _PROCESSOR_*.


>    I guess the values of these macros ought not to change between
>    releases, just in case someone stores _MIPS_ARCH in a variable
>    in one compilation unit and reads it in another, compiled with
>    a different version of gcc.  So I've used a (lame!) convention
>    for giving each entry a unique value.  See comment above
>    mips_cpu_info_table[] in mips.c for details.

I don't see why the values shouldn't change.

(1) The numbers aren't really meaningful.

(2) if used properly (as outlined in my message which spawned this
    particular feature), they'll all be resolved at compile time.

If there's a desire to record the values, e.g. for diagnostic output
from programs, that should probably be done using defines that use
strings.


>    This should also make it easier to check for a range of
>    processors, such as members of a family that have different
>    tuning characteristics but the same basic ISA.

Only if those values become well known.

from where I sit:

(1) it's unreasonable to have people code numeric constants in their
    code or header files, for these values provided internally by GCC,
    since GCC _may_ have to change some of them in the future.

(2) it's unreasonable to pass all of these all the time on the command
    line.

(3) it's not really reasonable to have GCC provide a special header
    which defines all of them.

(4) without having them all around all the time, it's hard to use them
    for e.g. "range checking."


I've outlined (in off-list mail) a mechanism that would allow code to
check for specific CPUs being used in arch/tune which doesn't involve
any of this persistent, ad hoc numbering crud.  I think it's the right
way.

For the benefit of everybody else:

	assume the processors _PROCESSOR_FOO and _PROCESSOR_BAR are
	used by _MIPS_ARCH and _MIPS_TUNE

	define _PROCESSOR_FOO the value 1.

	iff FOO != BAR, define _PROCESSOR_BAR the value 2.

Since CPP math treats undefined values as 0, code like:

#if (_MIPS_ARCH == _PROCESSOR_LALALA)

will work properly, and code written as the example in my orignal
message:

	switch (_MIPS_ARCH) {
#ifdef _PROCESSOR_LALALA
	case _PROCESSOR_LALALA:
		...
		break;
#endif
	default:
		...
		break;
	}

will also work properly.

I believe that those are good examples of the style with which these
new defines should be used.


> 5) I prefer '-march=from-abi' over '-mstrict-abi' and '-mdeduce-arch'
>    (which were the other suggestions I saw).  For one thing, it brings
>    all architecture-changing stuff under -march, but more importantly,
>    a configuration can then have "from-abi" as its default architecture.

This does seem to be The Right Thing, at least to me.  8-)



> 6) The consensus seemed to be that, when using a configuration associated
>    with a particular ISA or processor, we should try to stick to the
>    default where possible.  So "mips64orion-elf-gcc -mabi=32" would
>    generate 32-bit 4600 code rather than than MIPS I code.
> 
>    Then, we would only deviate from the default architecture when that
>    architecture is a 32-bit one, and the selected ABI requires 64-bit
>    registers.  For example, "mipstx39-elf -mabi=o64".  For configs
>    like mipstx39-elf that are associated with a particular ISA, I
>    think specifying an incompatible ABI should be a hard error.
>    The user can of course say "mipstx39-elf -mabi=o64 -mips3" if
>    that's what they truly mean.
> 
>    The question is, how do people see configs like mips-elf and
>    mips64-elf?  [ ... ]

I think I agree with you here...



I don't have time to read all of the diffs right now, or to read them
deeply, but there are a couple of comments below.


chris
=======
>   # 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*)
> + changequote(,)dnl
> + 	    mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*64//' -e 's/el$//'`
> + changequote([,])dnl
> + 	    ;;

Why not do the same here for mipsisa32*?  (OK, nothing uses it yet...
8-)

> + 	# 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_cpu} in
> + 	  mips64* | mipsisa64*)
> + 	    mips_default_64bit=1
> + 	    ;;
> + 	  *)
> + 	    mips_default_64bit=0
> + 	    ;;

Might be desirable to provide an easy, existing way/place to override
this based on the OS in question.

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16 17:34               ` cgd
  2002-07-16 18:56                 ` H. J. Lu
@ 2002-07-18 13:57                 ` Thiemo Seufer
  1 sibling, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 13:57 UTC (permalink / raw)
  To: cgd; +Cc: Richard Sandiford, gcc-patches, binutils

cgd@broadcom.com wrote:
> At Mon, 15 Jul 2002 18:56:55 +0000 (UTC), "Thiemo Seufer" wrote:
> > > However, it is much more useful to people creating optimized code to
> > > be able to generate code for specific ISAs,
> > 
> > For people who create, maintain and use an whole OS this would
> > be horrible. :-)
> 
> People who create and maintain a whole OS often do so via scripts,
> which allow them to set defaults for things like this.

I referred to "people creating optimized code" and imagined
people == debian package maintainers. :-)

[snip]
> > > If they're using mipsisa64sb1-linux, they probably expect built-in
> > > support for, say, MIPS-3D, MDMX .ob, and the few SB-1 extensions as
> > > well, regardless of the ABI they choose on the command line.
> > 
> > If all of the hardware for this target supports these, ok.
> > But the ISA pre-selection should then be done in the target specific
> > code and not globally.
> 
> I don't know that there's such a thing as "all of the hardware that
> this target supports," really.

Support according to user's expectations. AFAICS your example
"mipsisa64sb1-linux" is defined to support sb1 only.

> Given the flags you can pass to the compiler and assembler, you can
> use the MIPS tools to generate code for any target you want, pretty
> much.

Not in all places. See e.g. TE_TMIPS in gas.

> > > I'm wondering if the right thing to do here is have flags like
> > > -mstrict-abi=XXX, which also set the ISA type, or -mabi=strict-XXX...
> > 
> > -mabi=isa64sb1-with-many-wonderful-extensions ;-)
> 
> I'd argue that in the case where you specify a -march flag or specify
> a default architecture as part of the target triple, you really want
> "-mabi=X" to mean "X with those extensions which you have implied."
> 
> If you want strict conformance to ABI 'foo' in that situation, you
> want a special flag that says that.

Ok, that's what I meant.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: RFC & patch: Rework MIPS command-line handling
  2002-07-16  5:31           ` Richard Sandiford
  2002-07-16 11:39             ` Eric Christopher
@ 2002-07-18 14:44             ` Thiemo Seufer
  1 sibling, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 14:44 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: cgd, gcc-patches, binutils

Richard Sandiford wrote:
> [Answering two messages together]
> 
> cgd@broadcom.com writes:
> > At Mon, 15 Jul 2002 17:54:45 +0000 (UTC), "Thiemo Seufer" wrote:
> > > There seems to be some misconception about the term 'ABI', maybe
> > > because the current -mabi=FOO option basically means "select calling
> > > conventions and register sizes". But an ABI is a much more powerful
> > > concept than pushing a few compiler options. It defines a platform
> > > over a variety of hardware which allows to run the same binary code.
> 
> Hmm... I thought "o32" was a term that SGI invented.  And (going
> from the n32 handbook and SGI's cc) their idea of "o32" includes
> the ability to run MIPS II code.

Hm, some of SGI's (very old) hardware running o32 is MIPS I. Maybe
they invented some MIPS II emulation on it, or they simply don't
support MIPS I systems any more.

> Granted, the System V supplement says:
> 
>     Some processors might support the MIPS I ISA as a subset, providing
>     additional instructions or capabilities, e.g., the R6000 processor.
>     Programs that use those capabilities explicitly do not conform to
>     the MIPS ABI.
> 
> but does -mabi=32 select the ABI defined there, or does it
> work like SGI's -32 option?  I assumed the latter.

IMHO -mabi=32 should work ok on all targets, not only on SGI. :-)


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-18 12:44 ` [Revised patch] " Richard Sandiford
  2002-07-18 13:44   ` cgd
@ 2002-07-18 16:32   ` Thiemo Seufer
  1 sibling, 0 replies; 97+ messages in thread
From: Thiemo Seufer @ 2002-07-18 16:32 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: gcc-patches, binutils, cgd, Maciej W. Rozycki, Eric Christopher,
	Mark D. Baushke

Richard Sandiford wrote:
[snip: much stuff]
> GAS patch tested as before.  GCC patch tested on mips64-elf with
> and without patched GAS.  Irix bootstrap still ongoing.
> 
> How does this version look?

This looks very reasonable to me. Thanks.


Thiemo

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-18 13:44   ` cgd
@ 2002-07-18 18:12     ` Eric Christopher
  2002-07-19  2:53     ` Richard Sandiford
  1 sibling, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-18 18:12 UTC (permalink / raw)
  To: cgd
  Cc: Richard Sandiford, gcc-patches, binutils, Thiemo Seufer,
	Maciej W. Rozycki, Mark D. Baushke


> I think I agree with you here...
> 
> 

I'll just sum up that I agree with Chris. He'll like that thought. :)

> 
> I don't have time to read all of the diffs right now, or to read them
> deeply, but there are a couple of comments below.
> 
> 
> chris
> =======
> >   # 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*)
> > + changequote(,)dnl
> > + 	    mips_cpu=`echo $target_cpu | sed -e 's/[a-z]*64//' -e 's/el$//'`
> > + changequote([,])dnl
> > + 	    ;;
> 
> Why not do the same here for mipsisa32*?  (OK, nothing uses it yet...
> 8-)
> 

And, well, mips64 is different from mipsisa64...

> > + 	# 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_cpu} in
> > + 	  mips64* | mipsisa64*)
> > + 	    mips_default_64bit=1
> > + 	    ;;
> > + 	  *)
> > + 	    mips_default_64bit=0
> > + 	    ;;
> 
> Might be desirable to provide an easy, existing way/place to override
> this based on the OS in question.

Yup.

-eric

-- 
I will not grease the monkey bars


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-18 13:44   ` cgd
  2002-07-18 18:12     ` Eric Christopher
@ 2002-07-19  2:53     ` Richard Sandiford
  2002-07-19  3:10       ` Mark D. Baushke
  2002-07-19  9:56       ` cgd
  1 sibling, 2 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-19  2:53 UTC (permalink / raw)
  To: cgd
  Cc: gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher, Mark D. Baushke

cgd@broadcom.com writes:
> >    Question is, what are right values for _MIPS_ARCH and _MIPS_TUNE when
> >    you use a generic ISA?  It doesn't seem right for them to name a
> >    processor when the command line and configuration don't specify one.
> 
> I would advise simply going with whatever the processor is, unless
> you're going to create 'real' entries for the arches
> (e.g. _PROCESSOR_MIPS1.)

OK, if no-one jumps in, that's what I'll do.

> >    Not the biggest issue, I know, but is _MIPS_<foo> OK for the
> >    processor macros?  I guess other alternatives would be
> >    _MIPS_PROCESSOR_<foo> or _PROCESSOR_<foo>.
> 
> I'm for _PROCESSOR_*.

Others thought so too, so OK.

> I don't see why the values shouldn't change.
> 
> (1) The numbers aren't really meaningful.
> 
> (2) if used properly (as outlined in my message which spawned this
>     particular feature), they'll all be resolved at compile time.
> 
> If there's a desire to record the values, e.g. for diagnostic output
> from programs, that should probably be done using defines that use
> strings.

Well, string macros are no problem, so I can add _MIPS_ARCH_STRING
and _MIPS_TUNE_STRING.  If there really is no need for the macros
to have guaranteed values, then there's obviously no need for a
numbering convention, but...

> I've outlined (in off-list mail) a mechanism that would allow code to
> check for specific CPUs being used in arch/tune which doesn't involve
> any of this persistent, ad hoc numbering crud.  I think it's the right
> way.
> 
> For the benefit of everybody else:
> 
> 	assume the processors _PROCESSOR_FOO and _PROCESSOR_BAR are
> 	used by _MIPS_ARCH and _MIPS_TUNE
> 
> 	define _PROCESSOR_FOO the value 1.
> 
> 	iff FOO != BAR, define _PROCESSOR_BAR the value 2.
> 
> Since CPP math treats undefined values as 0, code like:
> 
> #if (_MIPS_ARCH == _PROCESSOR_LALALA)
> 
> will work properly, and code written as the example in my orignal
> message:
> 
> 	switch (_MIPS_ARCH) {
> #ifdef _PROCESSOR_LALALA
> 	case _PROCESSOR_LALALA:
> 		...
> 		break;
> #endif
> 	default:
> 		...
> 		break;
> 	}
> 
> will also work properly.
> 
> I believe that those are good examples of the style with which these
> new defines should be used.

It seems counter-intuitive to me that a condition written using '=='
should only be usable in preprocessor statements.  Many style guides
ask you to use C conditions instead of preprocessor ones, but you
wouldn't be able to write:

    if (_MIPS_ARCH == _PROCESSOR_LALALA)
      ...

There's also the chance of subtle errors, like:

    int optimize_for = _MIPS_TUNE;

and, in another file, perhaps part of a library:

    switch (optimize_for)
      {
#ifdef _PROCESSOR_LALALA
      case _PROCESSOR_LALALA:
	...
#endif
      }

OK, it obviously wouldn't be supported under the _MIPS_TUNE == 1 or 2
scheme, but it would compile, and having '_MIPS_TUNE == FOO' conditions
might just lead people to believe that _MIPS_TUNE can be treated as a
regular number (like __mips or __mips_fpr can).

The optimiser will (ought to?) remove redundant code, so why force
the user to wrap each case in '#ifdef's?  Why not allow...

    switch (_MIPS_ARCH)
      {
      case _PROCESSOR_LALALA:
        ...
      }

And if we define all the _PROCESSOR_FOO macros for each compilation
unit, we might as well try to give them lasting values...

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.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-19  2:53     ` Richard Sandiford
@ 2002-07-19  3:10       ` Mark D. Baushke
  2002-07-19 10:11         ` cgd
  2002-07-19  9:56       ` cgd
  1 sibling, 1 reply; 97+ messages in thread
From: Mark D. Baushke @ 2002-07-19  3:10 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: cgd, gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher

> From: Richard Sandiford <rsandifo@redhat.com>
> 
> cgd@broadcom.com writes:
> > >    Question is, what are right values for _MIPS_ARCH and _MIPS_TUNE when
> > >    you use a generic ISA?  It doesn't seem right for them to name a
> > >    processor when the command line and configuration don't specify one.
> > 
> > I would advise simply going with whatever the processor is, unless
> > you're going to create 'real' entries for the arches
> > (e.g. _PROCESSOR_MIPS1.)
> 
> OK, if no-one jumps in, that's what I'll do.

I like the idea of 'real' entries for the known existing mips and
mips-like processors.

> > >    Not the biggest issue, I know, but is _MIPS_<foo> OK for the
> > >    processor macros?  I guess other alternatives would be
> > >    _MIPS_PROCESSOR_<foo> or _PROCESSOR_<foo>.
> > 
> > I'm for _PROCESSOR_*.
> 
> Others thought so too, so OK.

Sounds fine to me. I know of a few mips-like projects in the real world
that didn't get licensed by MTI for various reasons. No reason that they
should not be able to use this backend with some very minor tweaks to
synthesize any missing instructions or other minor differences...

> > I don't see why the values shouldn't change.
> > 
> > (1) The numbers aren't really meaningful.
> > 
> > (2) if used properly (as outlined in my message which spawned this
> >     particular feature), they'll all be resolved at compile time.

I do not know if I can say that (2) above is likely in the real world. A
LOT of folks use macros improperly and mix-and-match software that they
compile without understanding. It is the cross-compilation unit
integrity/abstractions that I suspect as being most vulnerable.

> > If there's a desire to record the values, e.g. for diagnostic output
> > from programs, that should probably be done using defines that use
> > strings.

Strings are nice. In a big memory machine, they are a fine thing to use.
When you have limited space they can be unfriendly, else why does the
-mips16 instruction set exist?

> Well, string macros are no problem, so I can add _MIPS_ARCH_STRING
> and _MIPS_TUNE_STRING.  If there really is no need for the macros
> to have guaranteed values, then there's obviously no need for a
> numbering convention, but...

Hmmm... yes, 'but...'

> > I've outlined (in off-list mail) a mechanism that would allow code to
> > check for specific CPUs being used in arch/tune which doesn't involve
> > any of this persistent, ad hoc numbering crud.  I think it's the right
> > way.
> > 
> > For the benefit of everybody else:
> > 
> > 	assume the processors _PROCESSOR_FOO and _PROCESSOR_BAR are
> > 	used by _MIPS_ARCH and _MIPS_TUNE
> > 
> > 	define _PROCESSOR_FOO the value 1.
> > 
> > 	iff FOO != BAR, define _PROCESSOR_BAR the value 2.
> > 
> > Since CPP math treats undefined values as 0, code like:
> > 
> > #if (_MIPS_ARCH == _PROCESSOR_LALALA)
> > 
> > will work properly, and code written as the example in my orignal
> > message:
> > 
> > 	switch (_MIPS_ARCH) {
> > #ifdef _PROCESSOR_LALALA
> > 	case _PROCESSOR_LALALA:
> > 		...
> > 		break;
> > #endif
> > 	default:
> > 		...
> > 		break;
> > 	}
> > 
> > will also work properly.
> > 
> > I believe that those are good examples of the style with which these
> > new defines should be used.

Hmmm... I think I see a problem with this, or at least it makes me
uneasy to make the assumption that users will code in the above manner.

If we presume that a user has built a library for a system and this
particular library was built with -march=foo -mtune=bar and is in place
a 'long' time such that the library users may have lost track as to what
it was tuned to do....

Now, time passes (say, the time between package mylibfoo is grabbed from
the net, built and installed and the time that mynewpkg (which is
dependent on mylibfoo) is also grabbed off the net, built and installed
with with -march=foo -mtune=baz as the default...

If the _PROCESSOR_FOO and _PROCESSOR_BAR and _PROCESSOR_BAZ do not hold
some long-term values, then it is possible for the _PROCESSOR_BAR to be
easily mis-used in the library and _PROCESSOR_BAZ misused in the
application to presume that they were both tuned for optimization in the
same way and/or for other assumptions to be made.

If the only examples of _PROCESSOR_BAR and _PROCESSOR_BAZ are in the
mylibfoo .h files, then there might be no problem, but if they are
spread around between mylibfoo and mynewpkg there is a potential for
trouble.

I agree that cgd's general proposal would work if everyone was very
careful... but I doubt the ability for careful consideration of this
kind of subtle idea to be well understood by general developers or by
folks that just grab and compile code from various sources without
regard for what flags are being passed to the compiler.

> It seems counter-intuitive to me that a condition written using '=='
> should only be usable in preprocessor statements.  Many style guides
> ask you to use C conditions instead of preprocessor ones, but you
> wouldn't be able to write:
> 
>     if (_MIPS_ARCH == _PROCESSOR_LALALA)
>       ...
> 
> There's also the chance of subtle errors, like:
> 
>     int optimize_for = _MIPS_TUNE;
> 
> and, in another file, perhaps part of a library:
> 
>     switch (optimize_for)
>       {
> #ifdef _PROCESSOR_LALALA
>       case _PROCESSOR_LALALA:
> 	...
> #endif
>       }
> 
> OK, it obviously wouldn't be supported under the _MIPS_TUNE == 1 or 2
> scheme, but it would compile, and having '_MIPS_TUNE == FOO' conditions
> might just lead people to believe that _MIPS_TUNE can be treated as a
> regular number (like __mips or __mips_fpr can).

Yup. I see that problem as well.

> The optimiser will (ought to?) remove redundant code, so why force
> the user to wrap each case in '#ifdef's?  Why not allow...
> 
>     switch (_MIPS_ARCH)
>       {
>       case _PROCESSOR_LALALA:
>         ...
>       }
> 
> And if we define all the _PROCESSOR_FOO macros for each compilation
> unit, we might as well try to give them lasting values...

I see no reason that a number space could not be used, we still have the
potential problem where two divergent copies of gcc might add a new
processor to the list and not coordinate the conflict until much later,
so the macros will likely need to be mutable over time unless someone
wants to run a central registry. If the whole point of using
_PROCESSOR_<foo> instead of _MIPS_<foo> is to make sense, then we can
not count on MTI to keep the <foo> namespace or numberspace unique which
introduces another challenge...

> 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.
> 
> Richard

Well, the use of long strings that might show up multiple times in the
text or data segments of a program can be painful to the embedded world
who seems to always need more space to fit everything onto the device,
so care would be needed if that path was chosen to keep the names of
reasonable length if possible.

	-- Mark

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-19  2:53     ` Richard Sandiford
  2002-07-19  3:10       ` Mark D. Baushke
@ 2002-07-19  9:56       ` cgd
  2002-07-22  3:47         ` Richard Sandiford
  1 sibling, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-19  9:56 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher, Mark D. Baushke

At 19 Jul 2002 09:36:11 +0100, Richard Sandiford wrote:
> It seems counter-intuitive to me that a condition written using '=='
> should only be usable in preprocessor statements.  Many style guides
> ask you to use C conditions instead of preprocessor ones, but you
> wouldn't be able to write:
> 
>     if (_MIPS_ARCH == _PROCESSOR_LALALA)
>       ...

Yes you would.  It would have to look the same as the switch, though:

#ifdef _PROCESSOR_LALALA
    if (_MIPS_ARCH == _PROCESSOR_LALALA
	...
#endif


> There's also the chance of subtle errors, like:
> 
>     int optimize_for = _MIPS_TUNE;
> 
> and, in another file, perhaps part of a library:
> 
>     switch (optimize_for)
>       {
> #ifdef _PROCESSOR_LALALA
>       case _PROCESSOR_LALALA:
> 	...
> #endif
>       }
> 
> OK, it obviously wouldn't be supported under the _MIPS_TUNE == 1 or 2
> scheme, but it would compile, and having '_MIPS_TUNE == FOO' conditions
> might just lead people to believe that _MIPS_TUNE can be treated as a
> regular number (like __mips or __mips_fpr can).

one of the cases would compile at least.  If done with the 'tune'
setting, it should be OK if slower.  If done with the arch setting, it
could be painful.

I think the moral of the story here is... programmers need to exercise
_some_ small bit of care when coding and compiling for
optimization...

I suspect that not defining most of the values most of the time would
keep people from making the really silly errors.


> The optimiser will (ought to?) remove redundant code, so why force
> the user to wrap each case in '#ifdef's?  Why not allow...
> 
>     switch (_MIPS_ARCH)
>       {
>       case _PROCESSOR_LALALA:
>         ...
>       }
>
> And if we define all the _PROCESSOR_FOO macros for each compilation
> unit, we might as well try to give them lasting values...

If you want to define all of the _PROCESSOR_FOO macros for each
compilation unit, i suppose that'll work, but I think that solution is
really quite lame.

It's a _whole_ bunch of completely unnecessary definitions, which do
nothing except add stuff to the command line which will be irrelevant
99.9% of the time.  I actually think this might make debugging (people
using gcc -v then running the steps independently) a fair bit more
annoying, too.

I don't think there are enough that you'll be in danger of running any
system out of command line argument space... but it really does seem
absurd.

If the desire is to have them consistently dfined, then they should be
put into a header file.


> 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-)



chris

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-19  3:10       ` Mark D. Baushke
@ 2002-07-19 10:11         ` cgd
  0 siblings, 0 replies; 97+ messages in thread
From: cgd @ 2002-07-19 10:11 UTC (permalink / raw)
  To: Mark D. Baushke
  Cc: Richard Sandiford, gcc-patches, binutils, Thiemo Seufer,
	Maciej W. Rozycki, Eric Christopher

At Fri, 19 Jul 2002 02:53:39 -0700, Mark D. Baushke wrote:
> I like the idea of 'real' entries for the known existing mips and
> mips-like processors.

But, defined where?  8-)


> > > If there's a desire to record the values, e.g. for diagnostic output
> > > from programs, that should probably be done using defines that use
> > > strings.
> 
> Strings are nice. In a big memory machine, they are a fine thing to use.
> When you have limited space they can be unfriendly, else why does the
> -mips16 instruction set exist?

well, re: the latter, I'm sure you could get differing opinions by
asking a few people.  8-)

Are the things that use -mips16 likely to want to spend the space on
multi-arch/multi-tune configuration in the same set of binaries?  If
not (and I think the answer is not ... else why use them to begin
with?), then the size of the strings for them is irrelevant.


> > 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.
> 
> Well, the use of long strings that might show up multiple times in the
> text or data segments of a program can be painful to the embedded world
> who seems to always need more space to fit everything onto the device,
> so care would be needed if that path was chosen to keep the names of
> reasonable length if possible.

(1) not long strings.  8-)

(2) strings shouldn't show up often -- if at all, only in a few the
    'configure the optimized routines' fns/args/globals.  I.e., if
    you're doing string, or even integer, comparison often, it's
    likely you've lost the benefit of using optimized routines to
    begin with.



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-19  9:56       ` cgd
@ 2002-07-22  3:47         ` Richard Sandiford
  2002-07-22  4:19           ` Gerald Pfeifer
                             ` (4 more replies)
  0 siblings, 5 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-22  3:47 UTC (permalink / raw)
  To: cgd
  Cc: gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher, Mark D. Baushke, Gerald Pfeifer

[-- Attachment #1: Type: text/plain, Size: 5839 bytes --]

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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: GAS patch --]
[-- Type: text/x-patch, Size: 61421 bytes --]

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));
  \f
  /* 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));
  \f
  /* 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
- }
- \f
  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;
  }
+ \f
+ /* 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;
  }
+ \f
+ 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.*

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: GCC patch --]
[-- Type: text/x-patch, Size: 57622 bytes --]

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,
  };
  \f
+ /* 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 }
+ };
+ \f
  /* 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 ();
  }
  \f
  /* 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 ();
  }
  \f
+ /* 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);
  }
  \f
  /* 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);
  }
  \f
  /* 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;
  }
+ \f
+ /* 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;
+ }
+ \f
  /* 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);
+ }

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: Patch to changes.html --]
[-- Type: text/x-patch, Size: 1677 bytes --]

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>
  
  

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22  3:47         ` Richard Sandiford
@ 2002-07-22  4:19           ` Gerald Pfeifer
  2002-07-22 11:13           ` Maciej W. Rozycki
                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 97+ messages in thread
From: Gerald Pfeifer @ 2002-07-22  4:19 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: cgd, gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Eric Christopher, Mark D. Baushke

On 22 Jul 2002, Richard Sandiford wrote:
> OK to install?

The wwwdocs part looks fine, thanks!

Gerald
-- 
Gerald "Jerry" pfeifer@dbai.tuwien.ac.at http://www.dbai.tuwien.ac.at/~pfeifer/

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22  3:47         ` Richard Sandiford
  2002-07-22  4:19           ` Gerald Pfeifer
@ 2002-07-22 11:13           ` Maciej W. Rozycki
  2002-07-22 11:21             ` Richard Sandiford
                               ` (2 more replies)
  2002-07-22 13:13           ` Eric Christopher
                             ` (2 subsequent siblings)
  4 siblings, 3 replies; 97+ messages in thread
From: Maciej W. Rozycki @ 2002-07-22 11:13 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: cgd, gcc-patches, binutils, Thiemo Seufer, Eric Christopher,
	Mark D. Baushke, Gerald Pfeifer

On 22 Jul 2002, Richard Sandiford wrote:

> New version below.  Also includes the suggested gas config changes
> (infer processor name from mipsisa32foo, base MIPS_DEFAULT_64BIT
> on full target triple).

 Basically OK with me.  I'm somewhat uncertain about the warnings about
multiple "-march=" and "-mtune=" options, but they are unlikely to exist
in Makefiles as a default for a possible user override (unlike "-g" or
"-O"), so the benefit of additional diagnostics probably surpasses the
drawback of possible spurious warnings.  I'd leave it as is and wait for
any user screams before changing it.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22 11:13           ` Maciej W. Rozycki
@ 2002-07-22 11:21             ` Richard Sandiford
  2002-07-22 11:53             ` Eric Christopher
  2002-07-22 12:12             ` Paul Koning
  2 siblings, 0 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-22 11:21 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: cgd, gcc-patches, binutils, Thiemo Seufer, Eric Christopher,
	Mark D. Baushke

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> I'm somewhat uncertain about the warnings about multiple "-march=" and
> "-mtune=" options,

Understood.  I think it's been that way for a while now, but it may
be that -march and -mtune aren't widely used yet, so nobody's picked
up on it.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22 11:13           ` Maciej W. Rozycki
  2002-07-22 11:21             ` Richard Sandiford
@ 2002-07-22 11:53             ` Eric Christopher
  2002-07-22 12:12             ` Paul Koning
  2 siblings, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-22 11:53 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Richard Sandiford, cgd, gcc-patches, binutils, Thiemo Seufer,
	Mark D. Baushke, Gerald Pfeifer

On Mon, 2002-07-22 at 11:10, Maciej W. Rozycki wrote:
> On 22 Jul 2002, Richard Sandiford wrote:
> 
> > New version below.  Also includes the suggested gas config changes
> > (infer processor name from mipsisa32foo, base MIPS_DEFAULT_64BIT
> > on full target triple).
> 
>  Basically OK with me.  I'm somewhat uncertain about the warnings about
> multiple "-march=" and "-mtune=" options, but they are unlikely to exist
> in Makefiles as a default for a possible user override (unlike "-g" or
> "-O"), so the benefit of additional diagnostics probably surpasses the
> drawback of possible spurious warnings.  I'd leave it as is and wait for
> any user screams before changing it.

Reasonably accurate warnings are one reason why I wanted this so... :)

-eric

-- 
I don't want a pony, I want a rocket
powered jetpack!

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22 11:13           ` Maciej W. Rozycki
  2002-07-22 11:21             ` Richard Sandiford
  2002-07-22 11:53             ` Eric Christopher
@ 2002-07-22 12:12             ` Paul Koning
  2 siblings, 0 replies; 97+ messages in thread
From: Paul Koning @ 2002-07-22 12:12 UTC (permalink / raw)
  To: macro
  Cc: rsandifo, cgd, gcc-patches, binutils, ica2_ts, echristo, mdb, pfeifer

>>>>> "Maciej" == Maciej W Rozycki <macro@ds2.pg.gda.pl> writes:

 Maciej> On 22 Jul 2002, Richard Sandiford wrote:
 >> New version below.  Also includes the suggested gas config changes
 >> (infer processor name from mipsisa32foo, base MIPS_DEFAULT_64BIT
 >> on full target triple).

 Maciej> Basically OK with me.  I'm somewhat uncertain about the
 Maciej> warnings about multiple "-march=" and "-mtune=" options, but
 Maciej> they are unlikely to exist in Makefiles as a default for a
 Maciej> possible user override (unlike "-g" or "-O"), so the benefit
 Maciej> of additional diagnostics probably surpasses the drawback of
 Maciej> possible spurious warnings. 

I don't care for that.  Isn't it a general GNU rule that repeated
options are always legal and the latest wins (unless it's a switch
like -I, of course)?  That certainly is what I've come to expect, and
it would be a strange surprise to see it not work that way for some
options. 

	 paul

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22  3:47         ` Richard Sandiford
  2002-07-22  4:19           ` Gerald Pfeifer
  2002-07-22 11:13           ` Maciej W. Rozycki
@ 2002-07-22 13:13           ` Eric Christopher
       [not found]           ` <mailpost.1027334536.9318@news-sj1-1>
  2002-07-25  3:03           ` Richard Sandiford
  4 siblings, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-22 13:13 UTC (permalink / raw)
  To: Richard Sandiford
  Cc: cgd, gcc-patches, binutils, Thiemo Seufer, Maciej W. Rozycki,
	Mark D. Baushke, Gerald Pfeifer


> 
> OK to install?

Looks great to me. Now, the question of requiring certain versions of
gas with certain versions of gcc comes up. I think now is a great
occasion to do this.



-eric

> 
> [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.
> 
> ----
> 

-- 
I don't want a pony, I want a rocket
powered jetpack!

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
       [not found]           ` <mailpost.1027334536.9318@news-sj1-1>
@ 2002-07-22 15:13             ` cgd
  2002-07-23  2:03               ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-22 15:13 UTC (permalink / raw)
  To: rsandifo; +Cc: gcc-patches, binutils

> 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).

(Did you run the assembler/linker checks, as well was check-gcc?  I'd
assume so, but just checking.  8-)


> !   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);

So, given that there's some duplication of name -> CPU mappings in the
cpu names table (4600 vs.  orion, some of the SB-1 related names hich
i plan to clean up after you commit this), does it make sense to print
out only the first name for a given CPU (since presumably that's the
preferred name)?

It might be nice to have an additional field 'deprecated' to allow old
names to persist a bit, with warnings (and w/o being printed)... but
that can be added later...


> ! -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);

missing meabi?


> ! Note that the @samp{_MIPS_ARCH} uses processor names given above.  In

macro?


> ! other words, it will have the full prefix, and will not abbreviate

					     ^ kill this comma.  8-)


> ! @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

"failing that"?  Why not just kill ", or ..."?


> ! 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

@samp{n64} ?


> *** 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}}"
> 

Is this change to the existing / historical behaviour desirable?  Or
is it just a necessary side effect of the rest of the changes (i.e.,
consistency)?  Eh, i guess i don't really care.  8-)






chris

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22 15:13             ` cgd
@ 2002-07-23  2:03               ` Richard Sandiford
       [not found]                 ` <mailpost.1027412600.13407@news-sj1-1>
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-23  2:03 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

Thanks for the comments.

cgd@broadcom.com writes:
> > !   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);
> 
> So, given that there's some duplication of name -> CPU mappings in the
> cpu names table (4600 vs.  orion, some of the SB-1 related names hich
> i plan to clean up after you commit this), does it make sense to print
> out only the first name for a given CPU (since presumably that's the
> preferred name)?
> 
> It might be nice to have an additional field 'deprecated' to allow old
> names to persist a bit, with warnings (and w/o being printed)... but
> that can be added later...

If you like.  I don't see any particular reason not to print both
orion & 4600: it makes it clear both names are recognised.  I'll
leave the sb1 decision to you ;).  But FWIW, yes, I'd much prefer
a "deprecated" flag over a long list of show() calls.  Maybe
convert is_isa to a bitmask of flags?

> > ! -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);
>
> missing meabi?

Well, gas doesn't recognise meabi.  I haven't added it as part of this
patch because there isn't anything we can do with it yet.

BTW, GCC just doesn't pass an ABI flag in this case.  I guess
changes.html should read: "ELF configurations will always pass an ABI
flag to the assembler, except when the MIPS EABI is selected.".

> > ! Note that the @samp{_MIPS_ARCH} uses processor names given above.  In
> 
> macro?

Will fix.

> > ! other words, it will have the full prefix, and will not abbreviate
> 
> 					     ^ kill this comma.  8-)

Hmm, OK.

> "failing that"?  Why not just kill ", or ..."?

I'll kill ", or ...".

> > ! 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
> 
> @samp{n64} ?

Wanted to name the ABI rather than the -mabi argument.
How about "SGI's n64 ABI"?

> > *** 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}}"
> > 
> 
> Is this change to the existing / historical behaviour desirable?  Or
> is it just a necessary side effect of the rest of the changes (i.e.,
> consistency)?  Eh, i guess i don't really care.  8-)

Well, it's partly a necessary side effect.  It used to be
override_options that switched to -mips4.  So I had to either add a
-mabi=64 -> -mips4 rule to SUBTARGET_CC1_SPEC, or make the change above.
And PR 5938 (filed by SGI, no less) says that -mabi=64 should generate
MIPS III code by default, so that it can run on R4400 systems.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
       [not found]                 ` <mailpost.1027412600.13407@news-sj1-1>
@ 2002-07-23  9:42                   ` cgd
  2002-07-23  9:42                     ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-23  9:42 UTC (permalink / raw)
  To: rsandifo; +Cc: gcc-patches, binutils

At Tue, 23 Jul 2002 08:23:20 +0000 (UTC), "Richard Sandiford" wrote:
> Maybe
> convert is_isa to a bitmask of flags?

Maybe.  can be done later.  8-)


> Well, gas doesn't recognise meabi.  I haven't added it as part of this
> patch because there isn't anything we can do with it yet.
>
> BTW, GCC just doesn't pass an ABI flag in this case.  I guess
> changes.html should read: "ELF configurations will always pass an ABI
> flag to the assembler, except when the MIPS EABI is selected.".

Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
this case?

If not: Shouldn't it suffer the same fate as other options which are
specified by which don't have the desired result (e.g. various options
w/ SGI assember), i.e., flag is passed, and (probably) an error is
signaled?  8-)


> > > ! 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
> > 
> > @samp{n64} ?
> 
> Wanted to name the ABI rather than the -mabi argument.
> How about "SGI's n64 ABI"?

There's someting to that, but it will also be used by Linux and other
operating systems so saying "SGI's" here may be misleading.

"The n64 ABI" (but even then, not being a texinfo master, i suspect
that 'n64' should be formatted specially 8-)...

(SGI seems to be of two minds about N32 and presumably N64
capitalization.  In the IRIX 6.5 MIPSpro N32 ABI Handbooky they define
the names of the ABIs as lower case, but they they seem to use "n32"
and "N32" interchangeably in text...)

(I was surprised, looking at said book, that they actually _do_ refer
to n64 as n64 occasionally!  I didn't realize that)



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23  9:42                   ` cgd
@ 2002-07-23  9:42                     ` Richard Sandiford
  2002-07-23 10:04                       ` cgd
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-23  9:42 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

cgd@broadcom.com writes:
> > Well, gas doesn't recognise meabi.  I haven't added it as part of this
> > patch because there isn't anything we can do with it yet.
> >
> > BTW, GCC just doesn't pass an ABI flag in this case.  I guess
> > changes.html should read: "ELF configurations will always pass an ABI
> > flag to the assembler, except when the MIPS EABI is selected.".
> 
> Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
> this case?

Sort of.  The only checks of the ABI in gas are for:

   - setting the ELF ABI flags (MEABI doesn't have one according to
        version 1.0B of the spec)

   - setting the ELF "32-bit" flag (I think MEABI should if using a
        64-bit arch, since we have no other way of telling between
        32- and 64-bit mode)

   - checking for a NewABI (MEABI isn't)

   - determining register size (MEABI accepts either size)

All the MEABI comments apply to NO_ABI too, so they are
handled in the same way at the moment.

> "The n64 ABI" (but even then, not being a texinfo master, i suspect
> that 'n64' should be formatted specially 8-)...

Well, I'll no texinfo master either.  Next version will use
"The n64 ABI" (as-is) if no-one objects...

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23  9:42                     ` Richard Sandiford
@ 2002-07-23 10:04                       ` cgd
  2002-07-23 10:16                         ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-23 10:04 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

At 23 Jul 2002 17:42:00 +0100, Richard Sandiford wrote:
> > Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
> > this case?
> 
> Sort of.  The only checks of the ABI in gas are for:

Err, so, does it handle/produce all of the relocations, etc. specified
by that ABI properly?  (doesn't sound like it, from what you said...)



cgd

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 10:04                       ` cgd
@ 2002-07-23 10:16                         ` Richard Sandiford
  2002-07-23 10:24                           ` cgd
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-23 10:16 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

cgd@broadcom.com writes:
> At 23 Jul 2002 17:42:00 +0100, Richard Sandiford wrote:
> > > Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
> > > this case?
> > 
> > Sort of.  The only checks of the ABI in gas are for:
> 
> Err, so, does it handle/produce all of the relocations, etc. specified
> by that ABI properly?  (doesn't sound like it, from what you said...)

Dunno off-hand.  That was "sort of" as in "as well as gas knows how".
I certainly can't claim to have audited gas for ABI compliance.

But as far as this particular patch goes, I don't think it alters
gas's handling of "MEABI" code, beyond the generic changes discussed.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 10:16                         ` Richard Sandiford
@ 2002-07-23 10:24                           ` cgd
  2002-07-23 10:44                             ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-23 10:24 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

At 23 Jul 2002 18:04:32 +0100, Richard Sandiford wrote:
> cgd@broadcom.com writes:
> > At 23 Jul 2002 17:42:00 +0100, Richard Sandiford wrote:
> > > > Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
> > > > this case?
> > > 
> > > Sort of.  The only checks of the ABI in gas are for:
> > 
> > Err, so, does it handle/produce all of the relocations, etc. specified
> > by that ABI properly?  (doesn't sound like it, from what you said...)
> 
> Dunno off-hand.  That was "sort of" as in "as well as gas knows how".
> I certainly can't claim to have audited gas for ABI compliance.

Well, if gas knows how 'well enough' it should support the flag.


> But as far as this particular patch goes, I don't think it alters
> gas's handling of "MEABI" code, beyond the generic changes discussed.

Indeed, but it adds a special case to other (gcc) code, which others
will have to worry about maintaining in the future.

If there's no reason to add that special case, then best to avoid it
up front.


cgd



^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 10:24                           ` cgd
@ 2002-07-23 10:44                             ` Richard Sandiford
  2002-07-23 10:52                               ` cgd
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-23 10:44 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

cgd@broadcom.com writes:
> At 23 Jul 2002 18:04:32 +0100, Richard Sandiford wrote:
> > cgd@broadcom.com writes:
> > > At 23 Jul 2002 17:42:00 +0100, Richard Sandiford wrote:
> > > > > Hmm.  So, does gas then produce correct meabi binaries 'naturally' in
> > > > > this case?
> > > > 
> > > > Sort of.  The only checks of the ABI in gas are for:
> > > 
> > > Err, so, does it handle/produce all of the relocations, etc. specified
> > > by that ABI properly?  (doesn't sound like it, from what you said...)
> > 
> > Dunno off-hand.  That was "sort of" as in "as well as gas knows how".
> > I certainly can't claim to have audited gas for ABI compliance.
> 
> Well, if gas knows how 'well enough' it should support the flag.

But to turn your own question back on you, does it?  Adding -mabi=eabi
at this stage might give the wrong impression.

> If there's no reason to add that special case, then best to avoid it
> up front.

If we did add -mabi=meabi now, it would be a no-op, i.e. the same as
specifying no -mabi switch at all.  All the other -mabi flags leave some
sort of trace in the object file, but -mabi=meabi wouldn't.  So MEABI is
going to be the odd one out one way or the other.

It would be nice to have some way of identifying MEABI code too.
I just think -mabi=meabi should wait until there is.

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 10:44                             ` Richard Sandiford
@ 2002-07-23 10:52                               ` cgd
  2002-07-23 11:38                                 ` Richard Sandiford
  0 siblings, 1 reply; 97+ messages in thread
From: cgd @ 2002-07-23 10:52 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, binutils

At 23 Jul 2002 18:24:21 +0100, Richard Sandiford wrote:
> But to turn your own question back on you, does it?  Adding -mabi=eabi
> at this stage might give the wrong impression.

Yes.  In fact, doing anything other than causing an error might give
the wrong impressions.

That was my original point: specifying -mabi=meabi with gas
approximately equivalent in effect to, say, -march=foo with the MIPS
assembler.  That support is non-functional, and should cause an error.

No real special case in gcc, no special case in the assembler ->
error.  8-)

only difference is, it's an assember that "we" maintain.


chris


^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 10:52                               ` cgd
@ 2002-07-23 11:38                                 ` Richard Sandiford
  2002-07-23 13:18                                   ` Eric Christopher
  0 siblings, 1 reply; 97+ messages in thread
From: Richard Sandiford @ 2002-07-23 11:38 UTC (permalink / raw)
  To: cgd; +Cc: gcc-patches, binutils

cgd@broadcom.com writes:
> At 23 Jul 2002 18:24:21 +0100, Richard Sandiford wrote:
> > But to turn your own question back on you, does it?  Adding -mabi=eabi
> > at this stage might give the wrong impression.
> 
> Yes.  In fact, doing anything other than causing an error might give
> the wrong impressions.
> 
> That was my original point: specifying -mabi=meabi with gas
> approximately equivalent in effect to, say, -march=foo with the MIPS
> assembler.  That support is non-functional, and should cause an error.

OK, maybe I missed your point then ;).  Sounds like you're saying we
should drop MEABI support for gcc when TARGET_GAS.  Is that right?
If so, what do you think we should do with the mipsisa*-elf configs?

Richard

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-23 11:38                                 ` Richard Sandiford
@ 2002-07-23 13:18                                   ` Eric Christopher
  0 siblings, 0 replies; 97+ messages in thread
From: Eric Christopher @ 2002-07-23 13:18 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: cgd, gcc-patches, binutils


> OK, maybe I missed your point then ;).  Sounds like you're saying we
> should drop MEABI support for gcc when TARGET_GAS.  Is that right?
> If so, what do you think we should do with the mipsisa*-elf configs?

Hrm. Given that MIPS doesn't seem to want to release their spec for
MEABI anyhow perhaps we should. It seems dead as far as I can tell.

Let's just leave it alone for right now and revisit it later.

-eric

-- 
I don't want a pony, I want a rocket
powered jetpack!

^ permalink raw reply	[flat|nested] 97+ messages in thread

* Re: [Revised patch] Rework MIPS command-line handling
  2002-07-22  3:47         ` Richard Sandiford
                             ` (3 preceding siblings ...)
       [not found]           ` <mailpost.1027334536.9318@news-sj1-1>
@ 2002-07-25  3:03           ` Richard Sandiford
  4 siblings, 0 replies; 97+ messages in thread
From: Richard Sandiford @ 2002-07-25  3:03 UTC (permalink / raw)
  To: binutils

Eric approved this, so I've checked it in.

Richard Sandiford <rsandifo@redhat.com> writes:
> [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.

^ permalink raw reply	[flat|nested] 97+ messages in thread

end of thread, other threads:[~2002-07-25  9:56 UTC | newest]

Thread overview: 97+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-12 10:16 RFC & patch: Rework MIPS command-line handling Richard Sandiford
2002-07-12 11:39 ` Maciej W. Rozycki
2002-07-12 12:28   ` Paul Koning
2002-07-15  4:50   ` Richard Sandiford
2002-07-15 13:18     ` Thiemo Seufer
2002-07-15 13:31       ` Eric Christopher
2002-07-15 13:59         ` Thiemo Seufer
2002-07-15 14:25           ` Eric Christopher
2002-07-15 14:30             ` Thiemo Seufer
2002-07-15 14:59               ` Eric Christopher
2002-07-15 15:04                 ` Thiemo Seufer
2002-07-15 17:26                   ` Eric Christopher
2002-07-16  3:54     ` Maciej W. Rozycki
2002-07-16  4:47       ` Mark D. Baushke
2002-07-16 11:33         ` Eric Christopher
     [not found]           ` <mailpost.1026843855.9110@news-sj1-1>
2002-07-16 18:18             ` cgd
2002-07-17  2:19               ` Maciej W. Rozycki
2002-07-17 15:18               ` Eric Christopher
2002-07-12 11:46 ` Eric Christopher
2002-07-12 12:46   ` Maciej W. Rozycki
2002-07-12 18:16     ` Eric Christopher
     [not found]       ` <mailpost.1026512166.22848@news-sj1-1>
2002-07-13 19:56         ` cgd
2002-07-15  5:39           ` Richard Sandiford
2002-07-14 11:38       ` Thiemo Seufer
2002-07-15  1:03       ` Maciej W. Rozycki
2002-07-15  3:13         ` Mark D. Baushke
2002-07-15  6:40           ` Richard Sandiford
     [not found]     ` <mailpost.1026503036.18648@news-sj1-1>
2002-07-13  0:52       ` cgd
2002-07-14 11:22     ` Thiemo Seufer
     [not found]   ` <mailpost.1026499181.16972@news-sj1-1>
2002-07-13  0:42     ` cgd
2002-07-14 10:53   ` Thiemo Seufer
2002-07-14 23:13     ` Maciej W. Rozycki
     [not found] ` <mailpost.1026493441.14222@news-sj1-1>
2002-07-13  0:40   ` cgd
2002-07-15  5:07     ` Richard Sandiford
     [not found]       ` <mailpost.1026733871.20742@news-sj1-1>
2002-07-15 11:04         ` cgd
2002-07-15 14:28           ` Eric Christopher
2002-07-16  3:23             ` Richard Sandiford
2002-07-16 12:16               ` Eric Christopher
     [not found]               ` <mailpost.1026812813.25035@news-sj1-1>
2002-07-16 17:48                 ` cgd
2002-07-14 10:43 ` Thiemo Seufer
2002-07-15  3:40   ` Richard Sandiford
2002-07-15  3:57     ` Mark D. Baushke
     [not found]       ` <mailpost.1026729642.18965@news-sj1-1>
2002-07-15 10:54         ` cgd
2002-07-15 11:02           ` Mark D. Baushke
2002-07-15 11:11             ` cgd
     [not found]     ` <mailpost.1026728027.18467@news-sj1-1>
2002-07-15 10:47       ` cgd
2002-07-15 11:22         ` Thiemo Seufer
     [not found]           ` <mailpost.1026757359.1135@news-sj1-1>
2002-07-16 17:24             ` cgd
2002-07-18 12:48               ` Thiemo Seufer
2002-07-18 13:09                 ` Eric Christopher
2002-07-16  4:04         ` Maciej W. Rozycki
2002-07-15 11:01     ` Thiemo Seufer
     [not found]       ` <mailpost.1026755685.506@news-sj1-1>
2002-07-15 11:24         ` cgd
2002-07-15 12:51           ` Thiemo Seufer
2002-07-16  3:57             ` Maciej W. Rozycki
2002-07-18 13:43               ` Thiemo Seufer
     [not found]             ` <mailpost.1026759415.2116@news-sj1-1>
2002-07-16 17:34               ` cgd
2002-07-16 18:56                 ` H. J. Lu
2002-07-16 18:57                   ` cgd
2002-07-18 13:57                 ` Thiemo Seufer
2002-07-16  4:45           ` Maciej W. Rozycki
2002-07-16  5:31           ` Richard Sandiford
2002-07-16 11:39             ` Eric Christopher
2002-07-18 14:44             ` Thiemo Seufer
2002-07-16  2:40       ` Richard Sandiford
2002-07-18 13:36         ` Thiemo Seufer
2002-07-16  4:17       ` Maciej W. Rozycki
2002-07-16  2:46     ` Maciej W. Rozycki
2002-07-16  8:01       ` Paul Koning
2002-07-16 11:01         ` Maciej W. Rozycki
2002-07-18 12:44 ` [Revised patch] " Richard Sandiford
2002-07-18 13:44   ` cgd
2002-07-18 18:12     ` Eric Christopher
2002-07-19  2:53     ` Richard Sandiford
2002-07-19  3:10       ` Mark D. Baushke
2002-07-19 10:11         ` cgd
2002-07-19  9:56       ` cgd
2002-07-22  3:47         ` Richard Sandiford
2002-07-22  4:19           ` Gerald Pfeifer
2002-07-22 11:13           ` Maciej W. Rozycki
2002-07-22 11:21             ` Richard Sandiford
2002-07-22 11:53             ` Eric Christopher
2002-07-22 12:12             ` Paul Koning
2002-07-22 13:13           ` Eric Christopher
     [not found]           ` <mailpost.1027334536.9318@news-sj1-1>
2002-07-22 15:13             ` cgd
2002-07-23  2:03               ` Richard Sandiford
     [not found]                 ` <mailpost.1027412600.13407@news-sj1-1>
2002-07-23  9:42                   ` cgd
2002-07-23  9:42                     ` Richard Sandiford
2002-07-23 10:04                       ` cgd
2002-07-23 10:16                         ` Richard Sandiford
2002-07-23 10:24                           ` cgd
2002-07-23 10:44                             ` Richard Sandiford
2002-07-23 10:52                               ` cgd
2002-07-23 11:38                                 ` Richard Sandiford
2002-07-23 13:18                                   ` Eric Christopher
2002-07-25  3:03           ` Richard Sandiford
2002-07-18 16:32   ` Thiemo Seufer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).