[llvm-objdump] Support detection of feature bits from the object and implement this for Mips.

Summary:
The Mips implementation only covers the feature bits described by the ELF
e_flags so far. Mips stores additional feature bits such as MSA in the
.MIPS.abiflags section.

Also fixed a small bug this revealed where microMIPS wouldn't add the
EF_MIPS_MICROMIPS flag when using -filetype=obj.

Reviewers: echristo, rafael

Subscribers: rafael, mehdi_amini, dsanders, sdardis, llvm-commits

Differential Revision: http://reviews.llvm.org/D21125

llvm-svn: 272880
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index c7df30a..4bd69e3 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -55,4 +55,71 @@
   return std::move(R);
 }
 
+SubtargetFeatures ELFObjectFileBase::getFeatures() const {
+  switch (getEMachine()) {
+  case ELF::EM_MIPS: {
+    SubtargetFeatures Features;
+    unsigned PlatformFlags;
+    getPlatformFlags(PlatformFlags);
+
+    switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
+    case ELF::EF_MIPS_ARCH_1:
+      break;
+    case ELF::EF_MIPS_ARCH_2:
+      Features.AddFeature("mips2");
+      break;
+    case ELF::EF_MIPS_ARCH_3:
+      Features.AddFeature("mips3");
+      break;
+    case ELF::EF_MIPS_ARCH_4:
+      Features.AddFeature("mips4");
+      break;
+    case ELF::EF_MIPS_ARCH_5:
+      Features.AddFeature("mips5");
+      break;
+    case ELF::EF_MIPS_ARCH_32:
+      Features.AddFeature("mips32");
+      break;
+    case ELF::EF_MIPS_ARCH_64:
+      Features.AddFeature("mips64");
+      break;
+    case ELF::EF_MIPS_ARCH_32R2:
+      Features.AddFeature("mips32r2");
+      break;
+    case ELF::EF_MIPS_ARCH_64R2:
+      Features.AddFeature("mips64r2");
+      break;
+    case ELF::EF_MIPS_ARCH_32R6:
+      Features.AddFeature("mips32r6");
+      break;
+    case ELF::EF_MIPS_ARCH_64R6:
+      Features.AddFeature("mips64r6");
+      break;
+    default:
+      llvm_unreachable("Unknown EF_MIPS_ARCH value");
+    }
+
+    switch (PlatformFlags & ELF::EF_MIPS_MACH) {
+    case ELF::EF_MIPS_MACH_NONE:
+      // No feature associated with this value.
+      break;
+    case ELF::EF_MIPS_MACH_OCTEON:
+      Features.AddFeature("cnmips");
+      break;
+    default:
+      llvm_unreachable("Unknown EF_MIPS_ARCH value");
+    }
+
+    if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
+      Features.AddFeature("mips16");
+    if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
+      Features.AddFeature("micromips");
+
+    return Features;
+  }
+  default:
+    return SubtargetFeatures();
+  }
+}
+
 } // end namespace llvm