Select MIPS ABi based upon abiflags rather than e_flags.
authorMatthew Fortune <matthew.fortune@imgtec.com>
Wed, 26 Aug 2015 13:42:56 +0000 (14:42 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 26 Aug 2015 13:42:56 +0000 (14:42 +0100)
bfd PR ld/18401
* elfxx-mips.c (bfd_mips_isa_ext_mach): New function: Converts an
ISA value to a bfd machine number.
(bfd_mips_isa_ext): Update the ISA level and revision if
necessary.  Use mips_mach_extends_p to decide if the ISA extension
needs to be set.
(_bfd_mips_elf_merge_private_bfd_data): Allow the ISA extension to
be inferred from the ABI setting.  Set the ISA level from the
maximum of the incoming and outgoing ISA levels.

tests
* ld-mips-elf/mips-elf-flags.exp: Add more ISA conflict tests.

bfd/ChangeLog
bfd/elfxx-mips.c
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf-flags.exp

index 18a5cd0e243d0ced4051122ffa34e32af05cee3d..52fe2cc5d617d200294dc17f7abb8f2ad5f0029e 100644 (file)
@@ -1,3 +1,15 @@
+2015-08-26  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+       PR ld/18401
+       * elfxx-mips.c (bfd_mips_isa_ext_mach): New function: Converts an
+       ISA value to a bfd machine number.
+       (bfd_mips_isa_ext): Update the ISA level and revision if
+       necessary.  Use mips_mach_extends_p to decide if the ISA extension
+       needs to be set.
+       (_bfd_mips_elf_merge_private_bfd_data): Allow the ISA extension to
+       be inferred from the ABI setting.  Set the ISA level from the
+       maximum of the incoming and outgoing ISA levels.
+
 2015-08-25  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/18854
index be1e59accb3ba6e4894cb46d144446e41cd38c11..5ece52d0122ce4ad39e9124a2ec6ca679c1839fe 100644 (file)
@@ -13921,6 +13921,140 @@ _bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
   mips_elf_hash_table (info)->insn32 = on;
 }
 \f
+/* 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[] =
+{
+  /* MIPS64r2 extensions.  */
+  { bfd_mach_mips_octeon3, bfd_mach_mips_octeon2 },
+  { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
+  { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
+  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
+  { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
+
+  /* MIPS64 extensions.  */
+  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
+  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
+  { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
+
+  /* MIPS V extensions.  */
+  { bfd_mach_mipsisa64, bfd_mach_mips5 },
+
+  /* R10000 extensions.  */
+  { bfd_mach_mips12000, bfd_mach_mips10000 },
+  { bfd_mach_mips14000, bfd_mach_mips10000 },
+  { bfd_mach_mips16000, 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 },
+  { bfd_mach_mips7000, bfd_mach_mips8000 },
+  { bfd_mach_mips9000, bfd_mach_mips8000 },
+
+  /* VR4100 extensions.  */
+  { bfd_mach_mips4120, bfd_mach_mips4100 },
+  { bfd_mach_mips4111, bfd_mach_mips4100 },
+
+  /* MIPS III extensions.  */
+  { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
+  { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
+  { 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 },
+  { bfd_mach_mips5900, 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
+mips_mach_extends_p (unsigned long base, unsigned long extension)
+{
+  size_t i;
+
+  if (extension == base)
+    return TRUE;
+
+  if (base == bfd_mach_mipsisa32
+      && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
+    return TRUE;
+
+  if (base == bfd_mach_mipsisa32r2
+      && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
+    return TRUE;
+
+  for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
+    if (extension == mips_mach_extensions[i].extension)
+      {
+       extension = mips_mach_extensions[i].base;
+       if (extension == base)
+         return TRUE;
+      }
+
+  return FALSE;
+}
+
+/* Return the BFD mach for each .MIPS.abiflags ISA Extension.  */
+
+static unsigned long
+bfd_mips_isa_ext_mach (unsigned int isa_ext)
+{
+  switch (isa_ext)
+    {
+    case AFL_EXT_3900:        return bfd_mach_mips3900;
+    case AFL_EXT_4010:        return bfd_mach_mips4010;
+    case AFL_EXT_4100:        return bfd_mach_mips4100;
+    case AFL_EXT_4111:        return bfd_mach_mips4111;
+    case AFL_EXT_4120:        return bfd_mach_mips4120;
+    case AFL_EXT_4650:        return bfd_mach_mips4650;
+    case AFL_EXT_5400:        return bfd_mach_mips5400;
+    case AFL_EXT_5500:        return bfd_mach_mips5500;
+    case AFL_EXT_5900:        return bfd_mach_mips5900;
+    case AFL_EXT_10000:       return bfd_mach_mips10000;
+    case AFL_EXT_LOONGSON_2E: return bfd_mach_mips_loongson_2e;
+    case AFL_EXT_LOONGSON_2F: return bfd_mach_mips_loongson_2f;
+    case AFL_EXT_LOONGSON_3A: return bfd_mach_mips_loongson_3a;
+    case AFL_EXT_SB1:         return bfd_mach_mips_sb1;
+    case AFL_EXT_OCTEON:      return bfd_mach_mips_octeon;
+    case AFL_EXT_OCTEONP:     return bfd_mach_mips_octeonp;
+    case AFL_EXT_OCTEON2:     return bfd_mach_mips_octeon2;
+    case AFL_EXT_XLR:         return bfd_mach_mips_xlr;
+    default:                  return bfd_mach_mips3000;
+    }
+}
+
 /* Return the .MIPS.abiflags value representing each ISA Extension.  */
 
 unsigned int
@@ -13928,110 +14062,71 @@ bfd_mips_isa_ext (bfd *abfd)
 {
   switch (bfd_get_mach (abfd))
     {
-    case bfd_mach_mips3900:
-      return AFL_EXT_3900;
-    case bfd_mach_mips4010:
-      return AFL_EXT_4010;
-    case bfd_mach_mips4100:
-      return AFL_EXT_4100;
-    case bfd_mach_mips4111:
-      return AFL_EXT_4111;
-    case bfd_mach_mips4120:
-      return AFL_EXT_4120;
-    case bfd_mach_mips4650:
-      return AFL_EXT_4650;
-    case bfd_mach_mips5400:
-      return AFL_EXT_5400;
-    case bfd_mach_mips5500:
-      return AFL_EXT_5500;
-    case bfd_mach_mips5900:
-      return AFL_EXT_5900;
-    case bfd_mach_mips10000:
-      return AFL_EXT_10000;
-    case bfd_mach_mips_loongson_2e:
-      return AFL_EXT_LOONGSON_2E;
-    case bfd_mach_mips_loongson_2f:
-      return AFL_EXT_LOONGSON_2F;
-    case bfd_mach_mips_loongson_3a:
-      return AFL_EXT_LOONGSON_3A;
-    case bfd_mach_mips_sb1:
-      return AFL_EXT_SB1;
-    case bfd_mach_mips_octeon:
-      return AFL_EXT_OCTEON;
-    case bfd_mach_mips_octeonp:
-      return AFL_EXT_OCTEONP;
-    case bfd_mach_mips_octeon3:
-      return AFL_EXT_OCTEON3;
-    case bfd_mach_mips_octeon2:
-      return AFL_EXT_OCTEON2;
-    case bfd_mach_mips_xlr:
-      return AFL_EXT_XLR;
-    }
-  return 0;
-}
+    case bfd_mach_mips3900:         return AFL_EXT_3900;
+    case bfd_mach_mips4010:         return AFL_EXT_4010;
+    case bfd_mach_mips4100:         return AFL_EXT_4100;
+    case bfd_mach_mips4111:         return AFL_EXT_4111;
+    case bfd_mach_mips4120:         return AFL_EXT_4120;
+    case bfd_mach_mips4650:         return AFL_EXT_4650;
+    case bfd_mach_mips5400:         return AFL_EXT_5400;
+    case bfd_mach_mips5500:         return AFL_EXT_5500;
+    case bfd_mach_mips5900:         return AFL_EXT_5900;
+    case bfd_mach_mips10000:        return AFL_EXT_10000;
+    case bfd_mach_mips_loongson_2e: return AFL_EXT_LOONGSON_2E;
+    case bfd_mach_mips_loongson_2f: return AFL_EXT_LOONGSON_2F;
+    case bfd_mach_mips_loongson_3a: return AFL_EXT_LOONGSON_3A;
+    case bfd_mach_mips_sb1:         return AFL_EXT_SB1;
+    case bfd_mach_mips_octeon:      return AFL_EXT_OCTEON;
+    case bfd_mach_mips_octeonp:     return AFL_EXT_OCTEONP;
+    case bfd_mach_mips_octeon3:     return AFL_EXT_OCTEON3;
+    case bfd_mach_mips_octeon2:     return AFL_EXT_OCTEON2;
+    case bfd_mach_mips_xlr:         return AFL_EXT_XLR;
+    default:                        return 0;
+    }
+}
+
+/* Encode ISA level and revision as a single value.  */
+#define LEVEL_REV(LEV,REV) ((LEV) << 3 | (REV))
+
+/* Decode a single value into level and revision.  */
+#define ISA_LEVEL(LEVREV)  ((LEVREV) >> 3)
+#define ISA_REV(LEVREV)    ((LEVREV) & 0x7)
 
 /* Update the isa_level, isa_rev, isa_ext fields of abiflags.  */
 
 static void
 update_mips_abiflags_isa (bfd *abfd, Elf_Internal_ABIFlags_v0 *abiflags)
 {
+  int new_isa = 0;
   switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH)
     {
-    case E_MIPS_ARCH_1:
-      abiflags->isa_level = 1;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_2:
-      abiflags->isa_level = 2;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_3:
-      abiflags->isa_level = 3;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_4:
-      abiflags->isa_level = 4;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_5:
-      abiflags->isa_level = 5;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_32:
-      abiflags->isa_level = 32;
-      abiflags->isa_rev = 1;
-      break;
-    case E_MIPS_ARCH_32R2:
-      abiflags->isa_level = 32;
-      /* Handle MIPS32r3 and MIPS32r5 which do not have a header flag.  */
-      if (abiflags->isa_rev < 2)
-       abiflags->isa_rev = 2;
-      break;
-    case E_MIPS_ARCH_32R6:
-      abiflags->isa_level = 32;
-      abiflags->isa_rev = 6;
-      break;
-    case E_MIPS_ARCH_64:
-      abiflags->isa_level = 64;
-      abiflags->isa_rev = 1;
-      break;
-    case E_MIPS_ARCH_64R2:
-      /* Handle MIPS64r3 and MIPS64r5 which do not have a header flag.  */
-      abiflags->isa_level = 64;
-      if (abiflags->isa_rev < 2)
-       abiflags->isa_rev = 2;
-      break;
-    case E_MIPS_ARCH_64R6:
-      abiflags->isa_level = 64;
-      abiflags->isa_rev = 6;
-      break;
+    case E_MIPS_ARCH_1:    new_isa = LEVEL_REV (1, 0); break;
+    case E_MIPS_ARCH_2:    new_isa = LEVEL_REV (2, 0); break;
+    case E_MIPS_ARCH_3:    new_isa = LEVEL_REV (3, 0); break;
+    case E_MIPS_ARCH_4:    new_isa = LEVEL_REV (4, 0); break;
+    case E_MIPS_ARCH_5:    new_isa = LEVEL_REV (5, 0); break;
+    case E_MIPS_ARCH_32:   new_isa = LEVEL_REV (32, 1); break;
+    case E_MIPS_ARCH_32R2: new_isa = LEVEL_REV (32, 2); break;
+    case E_MIPS_ARCH_32R6: new_isa = LEVEL_REV (32, 6); break;
+    case E_MIPS_ARCH_64:   new_isa = LEVEL_REV (64, 1); break;
+    case E_MIPS_ARCH_64R2: new_isa = LEVEL_REV (64, 2); break;
+    case E_MIPS_ARCH_64R6: new_isa = LEVEL_REV (64, 6); break;
     default:
       (*_bfd_error_handler)
        (_("%B: Unknown architecture %s"),
         abfd, bfd_printable_name (abfd));
     }
 
-  abiflags->isa_ext = bfd_mips_isa_ext (abfd);
+  if (new_isa > LEVEL_REV (abiflags->isa_level, abiflags->isa_rev))
+    {
+      abiflags->isa_level = ISA_LEVEL (new_isa);
+      abiflags->isa_rev = ISA_REV (new_isa);
+    }
+
+  /* Update the isa_ext if ABFD describes a further extension.  */
+  if (mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags->isa_ext),
+                          bfd_get_mach (abfd)))
+    abiflags->isa_ext = bfd_mips_isa_ext (abfd);
 }
 
 /* Return true if the given ELF header flags describe a 32-bit binary.  */
@@ -14781,113 +14876,6 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   return TRUE;
 }
 \f
-/* 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[] =
-{
-  /* MIPS64r2 extensions.  */
-  { bfd_mach_mips_octeon3, bfd_mach_mips_octeon2 },
-  { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
-  { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
-  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
-  { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
-
-  /* MIPS64 extensions.  */
-  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
-  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
-  { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
-
-  /* MIPS V extensions.  */
-  { bfd_mach_mipsisa64, bfd_mach_mips5 },
-
-  /* R10000 extensions.  */
-  { bfd_mach_mips12000, bfd_mach_mips10000 },
-  { bfd_mach_mips14000, bfd_mach_mips10000 },
-  { bfd_mach_mips16000, 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 },
-  { bfd_mach_mips7000, bfd_mach_mips8000 },
-  { bfd_mach_mips9000, bfd_mach_mips8000 },
-
-  /* VR4100 extensions.  */
-  { bfd_mach_mips4120, bfd_mach_mips4100 },
-  { bfd_mach_mips4111, bfd_mach_mips4100 },
-
-  /* MIPS III extensions.  */
-  { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
-  { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
-  { 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 },
-  { bfd_mach_mips5900, 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
-mips_mach_extends_p (unsigned long base, unsigned long extension)
-{
-  size_t i;
-
-  if (extension == base)
-    return TRUE;
-
-  if (base == bfd_mach_mipsisa32
-      && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
-    return TRUE;
-
-  if (base == bfd_mach_mipsisa32r2
-      && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
-    return TRUE;
-
-  for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
-    if (extension == mips_mach_extensions[i].extension)
-      {
-       extension = mips_mach_extensions[i].base;
-       if (extension == base)
-         return TRUE;
-      }
-
-  return FALSE;
-}
-
-
 /* Merge object attributes from IBFD into OBFD.  Raise an error if
    there are conflicting attributes.  */
 static bfd_boolean
@@ -15127,9 +15115,8 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       if (in_abiflags.isa_rev == 3 || in_abiflags.isa_rev == 5)
        in_abiflags.isa_rev = 2;
 
-      if (in_abiflags.isa_level != abiflags.isa_level
-         || in_abiflags.isa_rev != abiflags.isa_rev
-         || in_abiflags.isa_ext != abiflags.isa_ext)
+      if (LEVEL_REV (in_abiflags.isa_level, in_abiflags.isa_rev)
+         < LEVEL_REV (abiflags.isa_level, abiflags.isa_rev))
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ISA between e_flags and "
             ".MIPS.abiflags"), ibfd);
@@ -15142,7 +15129,10 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ASEs between e_flags and "
             ".MIPS.abiflags"), ibfd);
-      if (in_abiflags.isa_ext != abiflags.isa_ext)
+      /* The isa_ext is allowed to be an extension of what can be inferred
+        from e_flags.  */
+      if (!mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags.isa_ext),
+                               bfd_mips_isa_ext_mach (in_abiflags.isa_ext)))
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ISA extensions between e_flags and "
             ".MIPS.abiflags"), ibfd);
@@ -15189,6 +15179,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
 #define max(a,b) ((a) > (b) ? (a) : (b))
   /* Merge abiflags.  */
+  mips_elf_tdata (obfd)->abiflags.isa_level
+    = max (mips_elf_tdata (obfd)->abiflags.isa_level,
+          mips_elf_tdata (ibfd)->abiflags.isa_level);
   mips_elf_tdata (obfd)->abiflags.isa_rev
     = max (mips_elf_tdata (obfd)->abiflags.isa_rev,
           mips_elf_tdata (ibfd)->abiflags.isa_rev);
index dbf7358aa7fc16921bce562cdaab3100ce37bb83..67ef467366dd7ea309bbb28d94e76a74a6043a65 100644 (file)
@@ -1,3 +1,8 @@
+2015-08-26  Nick Clifton  <nickc@redhat.com>
+
+       PR ld/18401
+       * ld-mips-elf/mips-elf-flags.exp: Add more ISA conflict tests.
+
 2015-08-19  Jiong Wang  <jiong.wang@arm.com>
 
        * ld-aarch64/emit-relocs-531.s: New testcase.
index 761fb0e67aa4d82fffd408f22a4f034c6ed07d40..a9662dd6a3fdc230e15593fe8a0a1f58bfcbcc26 100644 (file)
@@ -132,39 +132,44 @@ proc regsize_conflict {arglist} {
 }
 
 abi_conflict { "-mabi=eabi -mgp32" "-mips4 -mabi=32" } EABI32 O32
-abi_conflict { "-mips4 -mabi=o64" "-mips3 -mabi=eabi" } O64 EABI64
+abi_conflict { "-mips4 -mabi=o64"  "-mips3 -mabi=eabi" } O64 EABI64
 
-isa_conflict { "-march=vr5500 -32" "-march=sb1 -32" } 5500 sb1
-isa_conflict { "-march=vr5400 -32" "-march=4120 -32" } 5400 4120
-isa_conflict { "-march=r3900 -32" "-march=r6000 -32" } 3900 6000
-isa_conflict { "-march=r4010 -32" "-march=r4650 -32" } 4010 4650
-isa_conflict { "-mips3 -mgp32 -32" "-mips32 -32" } 4000 isa32
+isa_conflict { "-march=vr5500 -32"     "-march=sb1 -32" } 5500 sb1
+isa_conflict { "-march=vr5400 -32"     "-march=4120 -32" } 5400 4120
+isa_conflict { "-march=r3900 -32"      "-march=r6000 -32" } 3900 6000
+isa_conflict { "-march=r4010 -32"      "-march=r4650 -32" } 4010 4650
+isa_conflict { "-mips3 -mgp32 -32"     "-mips32 -32" } 4000 isa32
 isa_conflict { "-march=sb1 -mgp32 -32" "-mips32r2 -32" } sb1 isa32r2
-isa_conflict { "-march=sb1 -32" "-mips64r2 -32" } sb1 isa64r2
-
-regsize_conflict { "-mips4 -mgp64 -mabi=o64" "-mips2 -32" }
-regsize_conflict { "-mips4 -mabi=o64" "-mips4 -mabi=32" }
-regsize_conflict { "-mips4 -mabi=eabi -mgp32" "-mips4 -mabi=eabi -mgp64" }
-regsize_conflict { "-march=vr5000 -mgp64 -mabi=o64" "-march=vr5000 -mgp32 -32" }
-regsize_conflict { "-mips32 -32" "-mips64 -mabi=o64" }
-regsize_conflict { "-mips32r2 -32" "-mips64 -mabi=o64" }
-regsize_conflict { "-mips32r2 -32" "-mips64r2 -mabi=o64" }
-
-good_combination { "-mips4 -mgp32 -32" "-mips2 -32" } { mips4 o32 }
-good_combination { "-mips4 -mabi=32" "-mips2 -32" } { mips4 o32 }
-good_combination { "-mips2 -32" "-mips4 -mabi=32" } { mips4 o32 }
-good_combination { "-mips2 -mabi=eabi" "-mips4 -mabi=eabi -mgp32" } { mips4 eabi32 }
-good_combination { "-mips2 -32" "-mips32 -32" "-mips32r2 -32" } { mips32r2 }
-good_combination { "-mips1 -32" "-mips32r2 -32" "-mips32 -32" } { mips32r2 }
-
-good_combination { "-march=vr4100 -32" "-march=vr4120 -32" } { 4120 }
-good_combination { "-march=vr5400 -32" "-march=vr5500 -32" "-mips4 -32" } { 5500 }
-good_combination { "-mips3 -32" "-mips4 -32" "-march=sb1 -32" "-mips5 -32" } { sb1 }
-good_combination { "-mips1 -32" "-march=3900 -32" } { 3900 }
-good_combination { "-mips3 -32" "-mips64r2 -32" "-mips64 -32" } { mips64r2 }
-
-good_combination { "-march=vr4120 -mabi=32" "-mips3 -mabi=32" } { 4120 o32 }
-good_combination { "-march=sb1 -mgp32 -32" "-march=4000 -mgp32 -32" } { sb1 o32 }
-good_combination { "-mips32 -mabi=32" "-march=sb1 -mabi=32" } { sb1 o32 }
-good_combination { "-mips64r2 -mabi=32" "-mips32 -mabi=32" } { mips64r2 o32 }
-good_combination { "-mips5 -mabi=o64" "-mips64r2 -mabi=o64" } { mips64r2 o64 }
+isa_conflict { "-march=sb1 -32"        "-mips64r2 -32" } sb1 isa64r2
+
+isa_conflict { "-march=vr4100 -32"     "-march=r10000 -32" } 4100 8000
+isa_conflict { "-march=r5900 -32"      "-march=vr4111 -32" } 5900 4111
+isa_conflict { "-march=loongson2e -32" "-march=loongson2f -32" } loongson_2e loongson_2f
+isa_conflict { "-march=loongson3a -32" "-march=loongson2f -32" } loongson_3a loongson_2f
+
+regsize_conflict { "-mips4 -mgp64 -mabi=o64"         "-mips2 -32" }
+regsize_conflict { "-mips4 -mabi=o64"                "-mips4 -mabi=32" }
+regsize_conflict { "-mips4 -mabi=eabi -mgp32"        "-mips4 -mabi=eabi -mgp64" }
+regsize_conflict { "-march=vr5000 -mgp64 -mabi=o64"  "-march=vr5000 -mgp32 -32" }
+regsize_conflict { "-mips32 -32"                     "-mips64 -mabi=o64" }
+regsize_conflict { "-mips32r2 -32"                   "-mips64 -mabi=o64" }
+regsize_conflict { "-mips32r2 -32"                   "-mips64r2 -mabi=o64" }
+
+good_combination { "-mips4 -mgp32 -32"  "-mips2 -32" } { mips4 o32 }
+good_combination { "-mips4 -mabi=32"    "-mips2 -32" } { mips4 o32 }
+good_combination { "-mips2 -32"         "-mips4 -mabi=32" } { mips4 o32 }
+good_combination { "-mips2 -mabi=eabi"  "-mips4 -mabi=eabi -mgp32" } { mips4 eabi32 }
+good_combination { "-mips2 -32"         "-mips32 -32" "-mips32r2 -32" } { mips32r2 }
+good_combination { "-mips1 -32"         "-mips32r2 -32" "-mips32 -32" } { mips32r2 }
+
+good_combination { "-march=vr4100 -32"  "-march=vr4120 -32" } { 4120 }
+good_combination { "-march=vr5400 -32"  "-march=vr5500 -32" "-mips4 -32" } { 5500 }
+good_combination { "-mips3 -32"         "-mips4 -32"        "-march=sb1 -32"  "-mips5 -32" } { sb1 }
+good_combination { "-mips1 -32"         "-march=3900 -32" } { 3900 }
+good_combination { "-mips3 -32"         "-mips64r2 -32" "   -mips64 -32" } { mips64r2 }
+
+good_combination { "-march=vr4120 -mabi=32"  "-mips3 -mabi=32" } { 4120 o32 }
+good_combination { "-march=sb1 -mgp32 -32"   "-march=4000 -mgp32 -32" } { sb1 o32 }
+good_combination { "-mips32 -mabi=32"        "-march=sb1 -mabi=32" } { sb1 o32 }
+good_combination { "-mips64r2 -mabi=32"      "-mips32 -mabi=32" } { mips64r2 o32 }
+good_combination { "-mips5 -mabi=o64"        "-mips64r2 -mabi=o64" } { mips64r2 o64 }