bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 2 Jan 2003 21:31:32 +0000 (21:31 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Thu, 2 Jan 2003 21:31:32 +0000 (21:31 +0000)
* elfxx-mips.c: Include libiberty.h.
(elf_mips_isa, _bfd_mips_elf_mach_extends_p): Remove.
(mips_set_isa_flags): New function, split out from...
(_bfd_mips_elf_final_write_processing): ...here.  Only call
mips_set_isa_flags if the EF_MIPS_MACH bits are clear.
(mips_mach_extensions): New array.
(mips_32bit_flags_p): New function.
(_bfd_mips_elf_merge_private_bfd_data): Rework architecture checks.
Use mips_32bit_flags_p to check if one binary is 32-bit and the
other is 64-bit.  When adopting IBFD's architecture, adopt the
bfd_mach as well as the flags.

ld/testsuite/
* ld-mips-elf/jr.s: New file.
* ld-mips-elf/mips-elf-flags.exp: New test.

bfd/ChangeLog
bfd/elfxx-mips.c
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/jr.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf-flags.exp [new file with mode: 0644]

index a8503c18844d8ac940624b6199414d61d17f53aa..9c6674430a5f0adb32703675f1a5c98fab56f3a1 100644 (file)
@@ -1,3 +1,17 @@
+2003-01-02  Richard Sandiford  <rsandifo@redhat.com>
+
+       * elfxx-mips.c: Include libiberty.h.
+       (elf_mips_isa, _bfd_mips_elf_mach_extends_p): Remove.
+       (mips_set_isa_flags): New function, split out from...
+       (_bfd_mips_elf_final_write_processing): ...here.  Only call
+       mips_set_isa_flags if the EF_MIPS_MACH bits are clear.
+       (mips_mach_extensions): New array.
+       (mips_32bit_flags_p): New function.
+       (_bfd_mips_elf_merge_private_bfd_data): Rework architecture checks.
+       Use mips_32bit_flags_p to check if one binary is 32-bit and the
+       other is 64-bit.  When adopting IBFD's architecture, adopt the
+       bfd_mach as well as the flags.
+
 2003-01-02  Nick Kelsey  <nickk@ubicom.com>
 
        * elf32-ip2k.c: Re-work of linker relaxation code for the ip2k to
index ca79c64b98b5c1d06d94f10470336eba643a0b49..3164a2ec17aa420f3bc17ec00b6cb130fc45e20f 100644 (file)
@@ -1,6 +1,6 @@
 /* MIPS-specific support for ELF
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
+#include "libiberty.h"
 #include "elf-bfd.h"
 #include "elfxx-mips.h"
 #include "elf/mips.h"
@@ -382,11 +383,12 @@ static bfd_boolean mips_elf_create_dynamic_relocation
   PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
           struct mips_elf_link_hash_entry *, asection *,
           bfd_vma, bfd_vma *, asection *));
-static INLINE int elf_mips_isa PARAMS ((flagword));
+static void mips_set_isa_flags PARAMS ((bfd *));
 static INLINE char* elf_mips_abi_name PARAMS ((bfd *));
 static void mips_elf_irix6_finish_dynamic_symbol
   PARAMS ((bfd *, const char *, Elf_Internal_Sym *));
-static bfd_boolean _bfd_mips_elf_mach_extends_p PARAMS ((flagword, flagword));
+static bfd_boolean mips_mach_extends_p PARAMS ((unsigned long, unsigned long));
+static bfd_boolean mips_32bit_flags_p PARAMS ((flagword));
 static hashval_t mips_elf_got_entry_hash PARAMS ((const PTR));
 static int mips_elf_got_entry_eq PARAMS ((const PTR, const PTR));
 
@@ -3080,34 +3082,6 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
   return TRUE;
 }
 \f
-/* Return the ISA for a MIPS e_flags value.  */
-
-static INLINE int
-elf_mips_isa (flags)
-     flagword flags;
-{
-  switch (flags & EF_MIPS_ARCH)
-    {
-    case E_MIPS_ARCH_1:
-      return 1;
-    case E_MIPS_ARCH_2:
-      return 2;
-    case E_MIPS_ARCH_3:
-      return 3;
-    case E_MIPS_ARCH_4:
-      return 4;
-    case E_MIPS_ARCH_5:
-      return 5;
-    case E_MIPS_ARCH_32:
-      return 32;
-    case E_MIPS_ARCH_64:
-      return 64;
-    case E_MIPS_ARCH_32R2:
-      return 33;
-    }
-  return 4;
-}
-
 /* Return the MACH for a MIPS e_flags value.  */
 
 unsigned long
@@ -5967,20 +5941,14 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
   return TRUE;
 }
 
-/* The final processing done just before writing out a MIPS ELF object
-   file.  This gets the MIPS architecture right based on the machine
-   number.  This is used by both the 32-bit and the 64-bit ABI.  */
 
-void
-_bfd_mips_elf_final_write_processing (abfd, linker)
+/* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags.  */
+
+static void
+mips_set_isa_flags (abfd)
      bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
 {
-  unsigned long val;
-  unsigned int i;
-  Elf_Internal_Shdr **hdrpp;
-  const char *name;
-  asection *sec;
+  flagword val;
 
   switch (bfd_get_mach (abfd))
     {
@@ -6059,10 +6027,32 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
       val = E_MIPS_ARCH_32R2;
       break;
     }
-
   elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
   elf_elfheader (abfd)->e_flags |= val;
 
+}
+
+
+/* The final processing done just before writing out a MIPS ELF object
+   file.  This gets the MIPS architecture right based on the machine
+   number.  This is used by both the 32-bit and the 64-bit ABI.  */
+
+void
+_bfd_mips_elf_final_write_processing (abfd, linker)
+     bfd *abfd;
+     bfd_boolean linker ATTRIBUTE_UNUSED;
+{
+  unsigned int i;
+  Elf_Internal_Shdr **hdrpp;
+  const char *name;
+  asection *sec;
+
+  /* Keep the existing EF_MIPS_MACH and EF_MIPS_ARCH flags if the former
+     is nonzero.  This is for compatibility with old objects, which used
+     a combination of a 32-bit EF_MIPS_ARCH and a 64-bit EF_MIPS_MACH.  */
+  if ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == 0)
+    mips_set_isa_flags (abfd);
+
   /* Set the sh_info field for .gptab sections and other appropriate
      info for each special section.  */
   for (i = 1, hdrpp = elf_elfsections (abfd) + 1;
@@ -7731,26 +7721,97 @@ _bfd_mips_elf_final_link (abfd, info)
   return TRUE;
 }
 \f
-/* Return TRUE if machine EXTENSION is an extension of machine BASE,
-   meaning that it should be safe to link code for the two machines
-   and set the output machine to EXTENSION.  EXTENSION and BASE are
-   both submasks of EF_MIPS_MACH.  */
+/* Structure for saying that BFD machine EXTENSION extends BASE.  */
+
+struct mips_mach_extension {
+  unsigned long extension, base;
+};
+
+
+/* An array describing how BFD machines relate to one another.  The entries
+   are ordered topologically with MIPS I extensions listed last.  */
+
+static const struct mips_mach_extension mips_mach_extensions[] = {
+  /* MIPS64 extensions.  */
+  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
+
+  /* MIPS V extensions.  */
+  { bfd_mach_mipsisa64, bfd_mach_mips5 },
+
+  /* R10000 extensions.  */
+  { bfd_mach_mips12000, bfd_mach_mips10000 },
+
+  /* R5000 extensions.  Note: the vr5500 ISA is an extension of the core
+     vr5400 ISA, but doesn't include the multimedia stuff.  It seems
+     better to allow vr5400 and vr5500 code to be merged anyway, since
+     many libraries will just use the core ISA.  Perhaps we could add
+     some sort of ASE flag if this ever proves a problem.  */
+  { bfd_mach_mips5500, bfd_mach_mips5400 },
+  { bfd_mach_mips5400, bfd_mach_mips5000 },
+
+  /* MIPS IV extensions.  */
+  { bfd_mach_mips5, bfd_mach_mips8000 },
+  { bfd_mach_mips10000, bfd_mach_mips8000 },
+  { bfd_mach_mips5000, bfd_mach_mips8000 },
+
+  /* VR4100 extensions.  */
+  { bfd_mach_mips4120, bfd_mach_mips4100 },
+  { bfd_mach_mips4111, bfd_mach_mips4100 },
+
+  /* MIPS III extensions.  */
+  { bfd_mach_mips8000, bfd_mach_mips4000 },
+  { bfd_mach_mips4650, bfd_mach_mips4000 },
+  { bfd_mach_mips4600, bfd_mach_mips4000 },
+  { bfd_mach_mips4400, bfd_mach_mips4000 },
+  { bfd_mach_mips4300, bfd_mach_mips4000 },
+  { bfd_mach_mips4100, bfd_mach_mips4000 },
+  { bfd_mach_mips4010, bfd_mach_mips4000 },
+
+  /* MIPS32 extensions.  */
+  { bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 },
+
+  /* MIPS II extensions.  */
+  { bfd_mach_mips4000, bfd_mach_mips6000 },
+  { bfd_mach_mipsisa32, bfd_mach_mips6000 },
+
+  /* MIPS I extensions.  */
+  { bfd_mach_mips6000, bfd_mach_mips3000 },
+  { bfd_mach_mips3900, bfd_mach_mips3000 }
+};
+
+
+/* Return true if bfd machine EXTENSION is an extension of machine BASE.  */
 
 static bfd_boolean
-_bfd_mips_elf_mach_extends_p (base, extension)
-     flagword base, extension;
+mips_mach_extends_p (base, extension)
+     unsigned long base, extension;
 {
-  /* The vr5500 ISA is an extension of the core vr5400 ISA, but doesn't
-     include the multimedia stuff.  It seems better to allow vr5400
-     and vr5500 code to be merged anyway, since many libraries will
-     just use the core ISA.  Perhaps we could add some sort of ASE
-     flag if this ever proves a problem.  */
-  return (base == 0
-         || (base == E_MIPS_MACH_5400 && extension == E_MIPS_MACH_5500)
-         || (base == E_MIPS_MACH_4100 && extension == E_MIPS_MACH_4111)
-         || (base == E_MIPS_MACH_4100 && extension == E_MIPS_MACH_4120));
+  size_t i;
+
+  for (i = 0; extension != base && i < ARRAY_SIZE (mips_mach_extensions); i++)
+    if (extension == mips_mach_extensions[i].extension)
+      extension = mips_mach_extensions[i].base;
+
+  return extension == base;
 }
 
+
+/* Return true if the given ELF header flags describe a 32-bit binary.  */
+
+static bfd_boolean
+mips_32bit_flags_p (flags)
+     flagword flags;
+{
+  return ((flags & EF_MIPS_32BITMODE) != 0
+         || (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
+         || (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
+         || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1
+         || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2
+         || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32
+         || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2);
+}
+
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -7846,68 +7907,50 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
       ok = FALSE;
     }
 
-  /* Compare the ISA's.  */
-  if ((new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH))
-      != (old_flags & (EF_MIPS_ARCH | EF_MIPS_MACH)))
+  /* Compare the ISAs.  */
+  if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags))
+    {
+      (*_bfd_error_handler)
+       (_("%s: linking 32-bit code with 64-bit code"),
+        bfd_archive_filename (ibfd));
+      ok = FALSE;
+    }
+  else if (!mips_mach_extends_p (bfd_get_mach (ibfd), bfd_get_mach (obfd)))
     {
-      int new_mach = new_flags & EF_MIPS_MACH;
-      int old_mach = old_flags & EF_MIPS_MACH;
-      int new_isa = elf_mips_isa (new_flags);
-      int old_isa = elf_mips_isa (old_flags);
-
-      /* If either has no machine specified, just compare the general isa's.
-        Some combinations of machines are ok, if the isa's match.  */
-      if (new_mach == old_mach
-         || _bfd_mips_elf_mach_extends_p (new_mach, old_mach)
-         || _bfd_mips_elf_mach_extends_p (old_mach, new_mach))
+      /* OBFD's ISA isn't the same as, or an extension of, IBFD's.  */
+      if (mips_mach_extends_p (bfd_get_mach (obfd), bfd_get_mach (ibfd)))
        {
-         /* Don't warn about mixing code using 32-bit ISAs, or mixing code
-            using 64-bit ISAs.  They will normally use the same data sizes
-            and calling conventions.  */
-
-         if ((  (new_isa == 1 || new_isa == 2 || new_isa == 32
-                 || new_isa == 33)
-              ^ (old_isa == 1 || old_isa == 2 || old_isa == 32
-                 || old_isa == 33)) != 0)
-           {
-             (*_bfd_error_handler)
-              (_("%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"),
-               bfd_archive_filename (ibfd), new_isa, old_isa);
-             ok = FALSE;
-           }
-         else
-           {
-             /* Do we need to update the mach field?  */
-             if (_bfd_mips_elf_mach_extends_p (old_mach, new_mach))
-               {
-                 elf_elfheader (obfd)->e_flags &= ~EF_MIPS_MACH;
-                 elf_elfheader (obfd)->e_flags |= new_mach;
-               }
-
-             /* Do we need to update the ISA field?  */
-             if (new_isa > old_isa)
-               {
-                 elf_elfheader (obfd)->e_flags &= ~EF_MIPS_ARCH;
-                 elf_elfheader (obfd)->e_flags
-                   |= new_flags & EF_MIPS_ARCH;
-               }
-           }
+         /* Copy the architecture info from IBFD to OBFD.  Also copy
+            the 32-bit flag (if set) so that we continue to recognise
+            OBFD as a 32-bit binary.  */
+         bfd_set_arch_info (obfd, bfd_get_arch_info (ibfd));
+         elf_elfheader (obfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
+         elf_elfheader (obfd)->e_flags
+           |= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+
+         /* Copy across the ABI flags if OBFD doesn't use them
+            and if that was what caused us to treat IBFD as 32-bit.  */
+         if ((old_flags & EF_MIPS_ABI) == 0
+             && mips_32bit_flags_p (new_flags)
+             && !mips_32bit_flags_p (new_flags & ~EF_MIPS_ABI))
+           elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ABI;
        }
       else
        {
+         /* The ISAs aren't compatible.  */
          (*_bfd_error_handler)
-           (_("%s: ISA mismatch (%d) with previous modules (%d)"),
+           (_("%s: linking %s module with previous %s modules"),
             bfd_archive_filename (ibfd),
-            _bfd_elf_mips_mach (new_flags),
-            _bfd_elf_mips_mach (old_flags));
+            bfd_printable_name (ibfd),
+            bfd_printable_name (obfd));
          ok = FALSE;
        }
-
-      new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
-      old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
     }
 
-  /* Compare ABI's.  The 64-bit ABI does not use EF_MIPS_ABI.  But, it
+  new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+  old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+
+  /* Compare ABIs.  The 64-bit ABI does not use EF_MIPS_ABI.  But, it
      does set EI_CLASS differently from any 32-bit ABI.  */
   if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI)
       || (elf_elfheader (ibfd)->e_ident[EI_CLASS]
index a09864f37822dd518d3ef91a7b38cdf3dbfbb81b..7bdb16be8f34de0da634503eefcf03f7473620d4 100644 (file)
@@ -1,3 +1,8 @@
+2003-01-02  Richard Sandiford  <rsandifo@redhat.com>
+
+       * ld-mips-elf/jr.s: New file.
+       * ld-mips-elf/mips-elf-flags.exp: New test.
+
 2002-12-18  Ralf Habacker  <ralf.habacker@freenet.de>
 
        * ld-auto-import: New directory.
diff --git a/ld/testsuite/ld-mips-elf/jr.s b/ld/testsuite/ld-mips-elf/jr.s
new file mode 100644 (file)
index 0000000..df487d8
--- /dev/null
@@ -0,0 +1 @@
+       jr      $31
diff --git a/ld/testsuite/ld-mips-elf/mips-elf-flags.exp b/ld/testsuite/ld-mips-elf/mips-elf-flags.exp
new file mode 100644 (file)
index 0000000..30f1b49
--- /dev/null
@@ -0,0 +1,146 @@
+#   Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if {![istarget mips*-*-*] || ![is_elf_format]} {
+    return
+}
+
+# Assemble jr.s using each of the argument lists in ARGLIST.  Return the
+# list of object files on success and an empty list on failure.
+proc assemble_for_flags {arglist} {
+    global as srcdir subdir
+
+    set objs {}
+    set index 1
+
+    foreach args $arglist {
+       set obj "tmpdir/mips-flags-${index}.o"
+       if {![ld_assemble $as "$args $srcdir/$subdir/jr.s" $obj]} {
+           return ""
+       }
+       lappend objs $obj
+       incr index
+    }
+    return $objs
+}
+
+# Assemble a file using each set of arguments in ARGLIST.  Check that
+# the objects can be linked together and that the readelf output
+# includes each flag named in FLAGS.
+proc good_combination {arglist flags} {
+    global ld READELF
+
+    set finalobj "tmpdir/mips-flags.o"
+    set testname "MIPS compatible objects: $arglist"
+    set objs [assemble_for_flags $arglist]
+
+    if {$objs == ""} {
+       unresolved $testname
+    } elseif {![ld_simple_link $ld $finalobj "-r $objs"]} {
+       fail $testname
+    } else {
+       catch "exec $READELF --headers $finalobj" output
+       if {![regexp "Flags: *(\[^\n\]*)" $output full gotflags]} {
+           unresolved $testname
+       } else {
+           set failed 0
+
+           # GOTFLAGS is a list of flags separated by ", ".
+           # Convert it to a tcl list.
+           regsub -all ", " $gotflags "," gotflags
+           set gotflags [split $gotflags ","]
+
+           foreach flag $flags {
+               if {[lsearch -exact $gotflags $flag] < 0} {
+                   set failed 1
+               }
+           }
+           if {$failed} {
+               fail $testname
+           } else {
+               pass $testname
+           }
+       }
+    }
+}
+
+# Like good_combination, but check that the objects can't be linked
+# together successfully and that the output includes MESSAGE.
+proc bad_combination {arglist message} {
+    global link_output ld
+
+    set finalobj "tmpdir/mips-flags.o"
+    set testname "MIPS incompatible objects: $arglist"
+    set objs [assemble_for_flags $arglist]
+
+    if {$objs == ""} {
+       unresolved $testname
+    } elseif {[ld_simple_link $ld $finalobj "-r $objs"]
+             || [string first $message $link_output] < 0} {
+       fail $testname
+    } else {
+       pass $testname
+    }
+}
+
+# Routines to check for various kinds of incompatibility.
+
+proc abi_conflict {arglist firstabi secondabi} {
+    bad_combination $arglist \
+      "linking $secondabi module with previous $firstabi modules"
+}
+
+proc isa_conflict {arglist firstisa secondisa} {
+    bad_combination $arglist \
+      "linking mips:$secondisa module with previous mips:$firstisa modules"
+}
+
+proc regsize_conflict {arglist} {
+    bad_combination $arglist \
+      "linking 32-bit code with 64-bit code"
+}
+
+abi_conflict { "-mabi=eabi -mgp32" "-mips4 -mabi=32" } EABI32 O32
+abi_conflict { "-mips4 -mabi=o64" "-mips3 -mabi=eabi" } O64 EABI64
+
+isa_conflict { "-march=vr5500" "-march=sb1" } 5500 sb1
+isa_conflict { "-march=vr5400" "-march=4120" } 5400 4120
+isa_conflict { "-march=r3900" "-march=r6000" } 3900 6000
+isa_conflict { "-march=r4010" "-march=r4650" } 4010 4650
+isa_conflict { "-mips3 -mgp32" "-mips32" } 4000 isa32
+isa_conflict { "-march=sb1 -mgp32" "-mips32r2" } sb1 isa32r2
+
+regsize_conflict { "-mips4 -mgp64" "-mips2" }
+regsize_conflict { "-mips4 -mabi=o64" "-mips4 -mabi=32" }
+regsize_conflict { "-mabi=eabi -mgp32" "-mabi=eabi -mgp64" }
+regsize_conflict { "-march=vr5000 -mgp64" "-march=vr5000 -mgp32" }
+regsize_conflict { "-mips32" "-mips64" }
+regsize_conflict { "-mips32r2" "-mips64" }
+
+good_combination { "-mips4 -mgp32" "-mips2" } { mips4 32bitmode }
+good_combination { "-mips4 -mabi=32" "-mips2" } { mips4 o32 }
+good_combination { "-mips2" "-mips4 -mabi=32" } { mips4 o32 }
+good_combination { "-mips2" "-mips4 -mabi=eabi -mgp32" } { mips4 eabi32 }
+good_combination { "-mips2" "-mips32" "-mips32r2" } { mips32r2 }
+good_combination { "-mips1" "-mips32r2" "-mips32" } { mips32r2 }
+
+good_combination { "-march=vr4100" "-march=vr4120" } { 4120 }
+good_combination { "-march=vr5400" "-march=vr5500" "-mips4" } { 5500 }
+good_combination { "-mips3" "-mips4" "-march=sb1" "-mips5" } { sb1 }
+good_combination { "-mips1" "-march=3900" } { 3900 }
+
+good_combination { "-march=vr4120 -mabi=32" "-mips3 -mabi=32" } { 4120 o32 }
+good_combination { "-march=sb1 -mgp32" "-march=4000 -mgp32" } { sb1 32bitmode }