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