[llvm] r292366 - [ARM] Create objdump subtarget from build attrs

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 01:43:36 PST 2017


Hi Michael,


Thanks for letting me know. Would you mind doing the review? https://reviews.llvm.org/D29380


Thanks,

sam


Sam Parker

Software Engineer, Compilation Tools

Development Solutions Group

________________________________
From: Michael Kuperstein <mkuper at google.com>
Sent: 31 January 2017 22:55:58
To: Sam Parker
Cc: llvm-commits
Subject: Re: [llvm] r292366 - [ARM] Create objdump subtarget from build attrs

Hi Sam,

I just noticed (on a clean-enough rebuild :-) ) I'm getting a warning from this on GCC 4.8:

../unittests/Support/ARMAttributeParser.cpp: In function ‘bool testBuildAttr(unsigned int, unsigned int, unsigned int, unsigned int)’:
../unittests/Support/ARMAttributeParser.cpp:34:52: warning: cast from type ‘const char*’ to type ‘uint8_t* {aka unsigned char*}’ casts away qualifiers [-Wcast-qual]
   ArrayRef<uint8_t> Bytes((uint8_t*)OS.str().c_str(), OS.str().size());

Thanks,
  Michael


On Wed, Jan 18, 2017 at 5:52 AM, Sam Parker via llvm-commits <llvm-commits at lists.llvm.org<mailto:llvm-commits at lists.llvm.org>> wrote:
Author: sam_parker
Date: Wed Jan 18 07:52:12 2017
New Revision: 292366

URL: http://llvm.org/viewvc/llvm-project?rev=292366&view=rev
Log:
[ARM] Create objdump subtarget from build attrs

Enable an ELFObjectFile to read the its arm build attributes to
produce a target triple with a specific ARM architecture.
llvm-objdump now uses this functionality to automatically produce
a more accurate target.

Differential Revision: https://reviews.llvm.org/D28769

Added:
    llvm/trunk/test/tools/llvm-objdump/ARM/v5t-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v5te-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v5tej-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v6-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v6k-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v6m-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v6t2-subarch.s
    llvm/trunk/test/tools/llvm-objdump/ARM/v7m-subarch.s
    llvm/trunk/unittests/Support/ARMAttributeParser.cpp
Modified:
    llvm/trunk/include/llvm/Object/ELFObjectFile.h
    llvm/trunk/include/llvm/Object/ObjectFile.h
    llvm/trunk/include/llvm/Support/ARMAttributeParser.h
    llvm/trunk/include/llvm/Support/ARMBuildAttributes.h
    llvm/trunk/lib/Object/ELFObjectFile.cpp
    llvm/trunk/lib/Support/ARMAttributeParser.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/unittests/Support/CMakeLists.txt

Modified: llvm/trunk/include/llvm/Object/ELFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFObjectFile.h?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ELFObjectFile.h Wed Jan 18 07:52:12 2017
@@ -26,6 +26,7 @@
 #include "llvm/Object/Error.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/ARMAttributeParser.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Endian.h"
@@ -72,6 +73,8 @@ public:
   static inline bool classof(const Binary *v) { return v->isELF(); }

   SubtargetFeatures getFeatures() const override;
+
+  void setARMSubArch(Triple &TheTriple) const override;
 };

 class ELFSectionRef : public SectionRef {
@@ -356,6 +359,28 @@ public:
     return std::error_code();
   }

+  std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
+    auto SectionsOrErr = EF.sections();
+    if (!SectionsOrErr)
+      return errorToErrorCode(SectionsOrErr.takeError());
+
+    for (const Elf_Shdr &Sec : *SectionsOrErr) {
+      if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
+        auto ErrorOrContents = EF.getSectionContents(&Sec);
+        if (!ErrorOrContents)
+          return errorToErrorCode(ErrorOrContents.takeError());
+
+        auto Contents = ErrorOrContents.get();
+        if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+          return std::error_code();
+
+        Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+        break;
+      }
+    }
+    return std::error_code();
+  }
+
   const ELFFile<ELFT> *getELFFile() const { return &EF; }

   bool isDyldType() const { return isDyldELFObject; }

Modified: llvm/trunk/include/llvm/Object/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ObjectFile.h?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ObjectFile.h Wed Jan 18 07:52:12 2017
@@ -24,6 +24,8 @@
 #include <cstring>

 namespace llvm {
+class ARMAttributeParser;
+
 namespace object {

 class ObjectFile;
@@ -265,6 +267,7 @@ public:
   virtual StringRef getFileFormatName() const = 0;
   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
   virtual SubtargetFeatures getFeatures() const = 0;
+  virtual void setARMSubArch(Triple &TheTriple) const { }

   /// Returns platform-specific object flags, if any.
   virtual std::error_code getPlatformFlags(unsigned &Result) const {
@@ -272,6 +275,11 @@ public:
     return object_error::invalid_file_type;
   }

+  virtual std::error_code
+    getBuildAttributes(ARMAttributeParser &Attributes) const {
+      return std::error_code();
+    }
+
   /// True if this is a relocatable object (.o/.obj).
   virtual bool isRelocatableObject() const = 0;


Modified: llvm/trunk/include/llvm/Support/ARMAttributeParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ARMAttributeParser.h?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ARMAttributeParser.h (original)
+++ llvm/trunk/include/llvm/Support/ARMAttributeParser.h Wed Jan 18 07:52:12 2017
@@ -13,11 +13,15 @@
 #include "ARMBuildAttributes.h"
 #include "ScopedPrinter.h"

+#include <map>
+
 namespace llvm {
 class StringRef;

 class ARMAttributeParser {
-  ScopedPrinter &SW;
+  ScopedPrinter *SW;
+
+  std::map<unsigned, unsigned> Attributes;

   struct DisplayHandler {
     ARMBuildAttrs::AttrType Attribute;
@@ -115,9 +119,19 @@ class ARMAttributeParser {
                       SmallVectorImpl<uint8_t> &IndexList);
   void ParseSubsection(const uint8_t *Data, uint32_t Length);
 public:
-  ARMAttributeParser(ScopedPrinter &SW) : SW(SW) {}
+  ARMAttributeParser(ScopedPrinter *SW) : SW(SW) {}
+
+  ARMAttributeParser() : SW(nullptr) { }
+
+  void Parse(ArrayRef<uint8_t> Section, bool isLittle);
+
+  bool hasAttribute(unsigned Tag) const {
+    return Attributes.count(Tag);
+  }

-  void Parse(ArrayRef<uint8_t> Section);
+  unsigned getAttributeValue(unsigned Tag) const {
+    return Attributes.find(Tag)->second;
+  }
 };

 }

Modified: llvm/trunk/include/llvm/Support/ARMBuildAttributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ARMBuildAttributes.h?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ARMBuildAttributes.h (original)
+++ llvm/trunk/include/llvm/Support/ARMBuildAttributes.h Wed Jan 18 07:52:12 2017
@@ -176,14 +176,25 @@ enum {
   WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
   WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4

+  // Tag_ABI_align_needed, (=24), uleb128
+  Align8Byte = 1,
+  Align4Byte = 2,
+  AlignReserved = 3,
+
+  // Tag_ABI_align_needed, (=25), uleb128
+  AlignNotPreserved = 0,
+  AlignPreserve8Byte = 1,
+  AlignPreserveAll = 2,
+
   // Tag_ABI_FP_denormal, (=20), uleb128
   PositiveZero = 0,
   IEEEDenormals = 1,
   PreserveFPSign = 2, // sign when flushed-to-zero is preserved

   // Tag_ABI_FP_number_model, (=23), uleb128
+  AllowIEEENormal = 1,
   AllowRTABI = 2,  // numbers, infinities, and one quiet NaN (see [RTABI])
-  AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+  AllowIEEE754 = 3, // this code to use all the IEEE 754-defined FP encodings

   // Tag_ABI_enum_size, (=26), uleb128
   EnumProhibited = 0, // The user prohibited the use of enums when building
@@ -208,6 +219,7 @@ enum {

   // Tag_FP_16bit_format, (=38), uleb128
   FP16FormatIEEE = 1,
+  FP16VFP3 = 2,

   // Tag_MPextension_use, (=42), uleb128
   AllowMP = 1, // Allow use of MP extensions

Modified: llvm/trunk/lib/Object/ELFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELFObjectFile.cpp?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/ELFObjectFile.cpp Wed Jan 18 07:52:12 2017
@@ -122,4 +122,71 @@ SubtargetFeatures ELFObjectFileBase::get
   }
 }

+// FIXME Encode from a tablegen description or target parser.
+void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
+  if (TheTriple.getSubArch() != Triple::NoSubArch)
+    return;
+
+  ARMAttributeParser Attributes;
+  std::error_code EC = getBuildAttributes(Attributes);
+  if (EC)
+    return;
+
+  std::string Triple;
+  // Default to ARM, but use the triple if it's been set.
+  if (TheTriple.getArch() == Triple::thumb ||
+      TheTriple.getArch() == Triple::thumbeb)
+    Triple = "thumb";
+  else
+    Triple = "arm";
+
+  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
+    switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
+    case ARMBuildAttrs::v4:
+      Triple += "v4";
+      break;
+    case ARMBuildAttrs::v4T:
+      Triple += "v4t";
+      break;
+    case ARMBuildAttrs::v5T:
+      Triple += "v5t";
+      break;
+    case ARMBuildAttrs::v5TE:
+      Triple += "v5te";
+      break;
+    case ARMBuildAttrs::v5TEJ:
+      Triple += "v5tej";
+      break;
+    case ARMBuildAttrs::v6:
+      Triple += "v6";
+      break;
+    case ARMBuildAttrs::v6KZ:
+      Triple += "v6kz";
+      break;
+    case ARMBuildAttrs::v6T2:
+      Triple += "v6t2";
+      break;
+    case ARMBuildAttrs::v6K:
+      Triple += "v6k";
+      break;
+    case ARMBuildAttrs::v7:
+      Triple += "v7";
+      break;
+    case ARMBuildAttrs::v6_M:
+      Triple += "v6m";
+      break;
+    case ARMBuildAttrs::v6S_M:
+      Triple += "v6sm";
+      break;
+    case ARMBuildAttrs::v7E_M:
+      Triple += "v7em";
+      break;
+    }
+  }
+  if (!isLittleEndian())
+    Triple += "eb";
+
+  TheTriple.setArchName(Triple);
+}
+
 } // end namespace llvm

Modified: llvm/trunk/lib/Support/ARMAttributeParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ARMAttributeParser.cpp?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/lib/Support/ARMAttributeParser.cpp (original)
+++ llvm/trunk/lib/Support/ARMAttributeParser.cpp Wed Jan 18 07:52:12 2017
@@ -89,32 +89,43 @@ StringRef ARMAttributeParser::ParseStrin

 void ARMAttributeParser::IntegerAttribute(AttrType Tag, const uint8_t *Data,
                                           uint32_t &Offset) {
-  SW.printNumber(ARMBuildAttrs::AttrTypeAsString(Tag),
-                 ParseInteger(Data, Offset));
+
+  uint64_t Value = ParseInteger(Data, Offset);
+  Attributes.insert(std::make_pair(Tag, Value));
+
+  if (SW)
+    SW->printNumber(ARMBuildAttrs::AttrTypeAsString(Tag), Value);
 }

 void ARMAttributeParser::StringAttribute(AttrType Tag, const uint8_t *Data,
                                          uint32_t &Offset) {
   StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
+  StringRef ValueDesc = ParseString(Data, Offset);

-  DictScope AS(SW, "Attribute");
-  SW.printNumber("Tag", Tag);
-  if (!TagName.empty())
-    SW.printString("TagName", TagName);
-  SW.printString("Value", ParseString(Data, Offset));
+  if (SW) {
+    DictScope AS(*SW, "Attribute");
+    SW->printNumber("Tag", Tag);
+    if (!TagName.empty())
+      SW->printString("TagName", TagName);
+    SW->printString("Value", ValueDesc);
+  }
 }

 void ARMAttributeParser::PrintAttribute(unsigned Tag, unsigned Value,
                                         StringRef ValueDesc) {
-  StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
+  Attributes.insert(std::make_pair(Tag, Value));

-  DictScope AS(SW, "Attribute");
-  SW.printNumber("Tag", Tag);
-  SW.printNumber("Value", Value);
-  if (!TagName.empty())
-    SW.printString("TagName", TagName);
-  if (!ValueDesc.empty())
-    SW.printString("Description", ValueDesc);
+  if (SW) {
+    StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag,
+                                                        /*TagPrefix*/false);
+    DictScope AS(*SW, "Attribute");
+    SW->printNumber("Tag", Tag);
+    SW->printNumber("Value", Value);
+    if (!TagName.empty())
+      SW->printString("TagName", TagName);
+    if (!ValueDesc.empty())
+      SW->printString("Description", ValueDesc);
+  }
 }

 void ARMAttributeParser::CPU_arch(AttrType Tag, const uint8_t *Data,
@@ -449,20 +460,22 @@ void ARMAttributeParser::compatibility(A
   uint64_t Integer = ParseInteger(Data, Offset);
   StringRef String = ParseString(Data, Offset);

-  DictScope AS(SW, "Attribute");
-  SW.printNumber("Tag", Tag);
-  SW.startLine() << "Value: " << Integer << ", " << String << '\n';
-  SW.printString("TagName", AttrTypeAsString(Tag, /*TagPrefix*/false));
-  switch (Integer) {
-  case 0:
-    SW.printString("Description", StringRef("No Specific Requirements"));
-    break;
-  case 1:
-    SW.printString("Description", StringRef("AEABI Conformant"));
-    break;
-  default:
-    SW.printString("Description", StringRef("AEABI Non-Conformant"));
-    break;
+  if (SW) {
+    DictScope AS(*SW, "Attribute");
+    SW->printNumber("Tag", Tag);
+    SW->startLine() << "Value: " << Integer << ", " << String << '\n';
+    SW->printString("TagName", AttrTypeAsString(Tag, /*TagPrefix*/false));
+    switch (Integer) {
+    case 0:
+      SW->printString("Description", StringRef("No Specific Requirements"));
+      break;
+    case 1:
+      SW->printString("Description", StringRef("AEABI Conformant"));
+      break;
+    default:
+      SW->printString("Description", StringRef("AEABI Non-Conformant"));
+      break;
+    }
   }
 }

@@ -604,27 +617,33 @@ void ARMAttributeParser::ParseAttributeL
 void ARMAttributeParser::ParseSubsection(const uint8_t *Data, uint32_t Length) {
   uint32_t Offset = sizeof(uint32_t); /* SectionLength */

-  SW.printNumber("SectionLength", Length);
-
   const char *VendorName = reinterpret_cast<const char*>(Data + Offset);
   size_t VendorNameLength = std::strlen(VendorName);
-  SW.printString("Vendor", StringRef(VendorName, VendorNameLength));
   Offset = Offset + VendorNameLength + 1;

-  if (StringRef(VendorName, VendorNameLength).lower() != "aeabi")
+  if (SW) {
+    SW->printNumber("SectionLength", Length);
+    SW->printString("Vendor", StringRef(VendorName, VendorNameLength));
+  }
+
+  if (StringRef(VendorName, VendorNameLength).lower() != "aeabi") {
     return;
+  }

   while (Offset < Length) {
     /// Tag_File | Tag_Section | Tag_Symbol   uleb128:byte-size
     uint8_t Tag = Data[Offset];
-    SW.printEnum("Tag", Tag, makeArrayRef(TagNames));
     Offset = Offset + sizeof(Tag);

     uint32_t Size =
       *reinterpret_cast<const support::ulittle32_t*>(Data + Offset);
-    SW.printNumber("Size", Size);
     Offset = Offset + sizeof(Size);

+    if (SW) {
+      SW->printEnum("Tag", Tag, makeArrayRef(TagNames));
+      SW->printNumber("Size", Size);
+    }
+
     if (Size > Length) {
       errs() << "subsection length greater than section length\n";
       return;
@@ -651,31 +670,38 @@ void ARMAttributeParser::ParseSubsection
       return;
     }

-    DictScope ASS(SW, ScopeName);
-
-    if (!Indicies.empty())
-      SW.printList(IndexName, Indicies);
-
-    ParseAttributeList(Data, Offset, Length);
+    if (SW) {
+      DictScope ASS(*SW, ScopeName);
+      if (!Indicies.empty())
+        SW->printList(IndexName, Indicies);
+      ParseAttributeList(Data, Offset, Length);
+    } else {
+      ParseAttributeList(Data, Offset, Length);
+    }
   }
 }

-void ARMAttributeParser::Parse(ArrayRef<uint8_t> Section) {
+void ARMAttributeParser::Parse(ArrayRef<uint8_t> Section, bool isLittle) {
   size_t Offset = 1;
   unsigned SectionNumber = 0;

   while (Offset < Section.size()) {
-    uint32_t SectionLength =
-      *reinterpret_cast<const support::ulittle32_t*>(Section.data() + Offset);
-
-    SW.startLine() << "Section " << ++SectionNumber << " {\n";
-    SW.indent();
+    uint32_t SectionLength = isLittle ?
+      support::endian::read32le(Section.data() + Offset) :
+      support::endian::read32be(Section.data() + Offset);
+
+    if (SW) {
+      SW->startLine() << "Section " << ++SectionNumber << " {\n";
+      SW->indent();
+    }

     ParseSubsection(Section.data() + Offset, SectionLength);
     Offset = Offset + SectionLength;

-    SW.unindent();
-    SW.startLine() << "}\n";
+    if (SW) {
+      SW->unindent();
+      SW->startLine() << "}\n";
+    }
   }
 }
 }

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Wed Jan 18 07:52:12 2017
@@ -841,7 +841,7 @@ void ARMAsmPrinter::emitAttributes() {
                       ARMBuildAttrs::Allowed);
   else
     ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
-                      ARMBuildAttrs::AllowIEE754);
+                      ARMBuildAttrs::AllowIEEE754);

   if (STI.allowsUnalignedMem())
     ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v5t-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v5t-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v5t-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v5t-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc < %s -triple armv5t-elf -filetype=obj | llvm-objdump -triple=arm -d - | FileCheck %s
+
+.arch armv5t
+
+clz:
+clz r0, r1
+
+@ CHECK-LABEL: clz
+@ CHECK: 11 0f 6f e1
+

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v5te-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v5te-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v5te-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v5te-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc < %s -triple armv5te-elf -filetype=obj | llvm-objdump -triple=arm -d - | FileCheck %s
+
+.arch armv5te
+
+strd:
+strd r0, r1, [r2, +r3]
+
+@ CHECK-LABEL strd
+@ CHECK: f3 00 82 e1 strd r0, r1, [r2, r3]
+

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v5tej-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v5tej-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v5tej-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v5tej-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,7 @@
+@ RUN: llvm-mc < %s -triple armv5tej-elf -filetype=obj | llvm-objdump -triple=arm -d - | FileCheck %s
+
+bxj:
+bxj r0
+
+@ CHECK-LABEL: bxj
+@ CHECK: 20 ff 2f e1 bxj r0

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v6-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v6-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v6-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v6-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,9 @@
+@ RUN: llvm-mc < %s -triple armv6-elf -filetype=obj | llvm-objdump -triple=arm -d - | FileCheck %s
+
+.arch armv6
+
+umaal:
+umaal r0, r1, r2, r3
+
+@ CHECK-LABEL:umaal
+@ CHECK: 92 03 41 e0 umaal r0, r1, r2, r3

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v6k-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v6k-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v6k-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v6k-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,9 @@
+@ RUN: llvm-mc < %s -triple armv6k-elf -filetype=obj | llvm-objdump -triple=arm -d - | FileCheck %s
+
+.arch armv6k
+
+clrex:
+clrex
+
+@ CHECK-LABEL: clrex
+@ CHECK: 1f f0 7f f5 clrex

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v6m-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v6m-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v6m-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v6m-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,9 @@
+@ RUN: llvm-mc < %s -triple armv6m-elf -filetype=obj | llvm-objdump -triple=thumb -d - | FileCheck %s
+
+.arch armv6m
+
+dmb:
+dmb
+
+@ CHECK-LABEL: dmb
+@ CHECK: bf f3 5f 8f dmb sy

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v6t2-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v6t2-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v6t2-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v6t2-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc < %s -triple armv6t2-elf -filetype=obj | llvm-objdump -triple=thumb -d - | FileCheck %s
+
+.arch armv6t2
+
+.thumb
+umaalt2:
+umaal r0, r1, r2, r3
+
+@ CHECK-LABEL: umaalt2
+@ CHECK: e2 fb 63 01 umaal r0, r1, r2, r3

Added: llvm/trunk/test/tools/llvm-objdump/ARM/v7m-subarch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/v7m-subarch.s?rev=292366&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/v7m-subarch.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/v7m-subarch.s Wed Jan 18 07:52:12 2017
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc < %s -triple armv7m-elf -filetype=obj | llvm-objdump -triple=thumb -d - | FileCheck %s
+
+.arch armv7m
+
+umlal:
+umlal r0, r1, r2, r3
+
+@ CHECK-LABEL: umlal
+@ CHECK: e2 fb 03 01 umlal r0, r1, r2, r3
+

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Wed Jan 18 07:52:12 2017
@@ -357,7 +357,16 @@ static const Target *getTarget(const Obj
   llvm::Triple TheTriple("unknown-unknown-unknown");
   if (TripleName.empty()) {
     if (Obj) {
-      TheTriple.setArch(Triple::ArchType(Obj->getArch()));
+      auto Arch = Obj->getArch();
+      TheTriple.setArch(Triple::ArchType(Arch));
+
+      // For ARM targets, try to use the build attributes to build determine
+      // the build target. Target features are also added, but later during
+      // disassembly.
+      if (Arch == Triple::arm || Arch == Triple::armeb) {
+        Obj->setARMSubArch(TheTriple);
+      }
+
       // TheTriple defaults to ELF, and COFF doesn't have an environment:
       // the best we can do here is indicate that it is mach-o.
       if (Obj->isMachO())
@@ -369,8 +378,16 @@ static const Target *getTarget(const Obj
           TheTriple.setTriple("thumbv7-windows");
       }
     }
-  } else
+  } else {
     TheTriple.setTriple(Triple::normalize(TripleName));
+    // Use the triple, but also try to combine with ARM build attributes.
+    if (Obj) {
+      auto Arch = Obj->getArch();
+      if (Arch == Triple::arm || Arch == Triple::armeb) {
+        Obj->setARMSubArch(TheTriple);
+      }
+    }
+  }

   // Get the target specific parser.
   std::string Error;

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Jan 18 07:52:12 2017
@@ -1892,7 +1892,7 @@ template <> void ELFDumper<ELFType<suppo
     if (Contents.size() == 1)
       continue;

-    ARMAttributeParser(W).Parse(Contents);
+    ARMAttributeParser(&W).Parse(Contents, true);
   }
 }
 }

Added: llvm/trunk/unittests/Support/ARMAttributeParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ARMAttributeParser.cpp?rev=292366&view=auto
==============================================================================
--- llvm/trunk/unittests/Support/ARMAttributeParser.cpp (added)
+++ llvm/trunk/unittests/Support/ARMAttributeParser.cpp Wed Jan 18 07:52:12 2017
@@ -0,0 +1,384 @@
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/LEB128.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+
+struct AttributeSection {
+  unsigned Tag;
+  unsigned Value;
+
+  AttributeSection(unsigned tag, unsigned value) : Tag(tag), Value(value) { }
+
+  void write(raw_ostream &OS) {
+    OS.flush();
+    // length = length + "aeabi\0" + TagFile + ByteSize + Tag + Value;
+    // length = 17 bytes
+
+    OS << 'A' << (uint8_t)17 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
+    OS << "aeabi" << '\0';
+    OS << (uint8_t)1 << (uint8_t)7 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
+    OS << (uint8_t)Tag << (uint8_t)Value;
+
+  }
+};
+
+bool testBuildAttr(unsigned Tag, unsigned Value,
+                      unsigned ExpectedTag, unsigned ExpectedValue) {
+  std::string buffer;
+  raw_string_ostream OS(buffer);
+  AttributeSection Section(Tag, Value);
+  Section.write(OS);
+  ArrayRef<uint8_t> Bytes((uint8_t*)OS.str().c_str(), OS.str().size());
+
+  ARMAttributeParser Parser;
+  Parser.Parse(Bytes, true);
+
+  return (Parser.hasAttribute(ExpectedTag) &&
+    Parser.getAttributeValue(ExpectedTag) == ExpectedValue);
+}
+
+bool testTagString(unsigned Tag, const char *name) {
+  return ARMBuildAttrs::AttrTypeAsString(Tag).str() == name;
+}
+
+TEST(CPUArchBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(6, "Tag_CPU_arch"));
+
+  EXPECT_TRUE(testBuildAttr(6, 0, ARMBuildAttrs::CPU_arch,
+                            ARMBuildAttrs::Pre_v4));
+  EXPECT_TRUE(testBuildAttr(6, 1, ARMBuildAttrs::CPU_arch,
+                            ARMBuildAttrs::v4));
+  EXPECT_TRUE(testBuildAttr(6, 2, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v4T));
+  EXPECT_TRUE(testBuildAttr(6, 3, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5T));
+  EXPECT_TRUE(testBuildAttr(6, 4, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5TE));
+  EXPECT_TRUE(testBuildAttr(6, 5, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5TEJ));
+  EXPECT_TRUE(testBuildAttr(6, 6, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6));
+  EXPECT_TRUE(testBuildAttr(6, 7, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6KZ));
+  EXPECT_TRUE(testBuildAttr(6, 8, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6T2));
+  EXPECT_TRUE(testBuildAttr(6, 9, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6K));
+  EXPECT_TRUE(testBuildAttr(6, 10, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v7));
+  EXPECT_TRUE(testBuildAttr(6, 11, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6_M));
+  EXPECT_TRUE(testBuildAttr(6, 12, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6S_M));
+  EXPECT_TRUE(testBuildAttr(6, 13, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v7E_M));
+}
+
+TEST(CPUArchProfileBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(7, "Tag_CPU_arch_profile"));
+  EXPECT_TRUE(testBuildAttr(7, 'A', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::ApplicationProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'R', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::RealTimeProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'M', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::MicroControllerProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'S', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::SystemProfile));
+}
+
+TEST(ARMISABuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(8, "Tag_ARM_ISA_use"));
+  EXPECT_TRUE(testBuildAttr(8, 0, ARMBuildAttrs::ARM_ISA_use,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(8, 1, ARMBuildAttrs::ARM_ISA_use,
+                               ARMBuildAttrs::Allowed));
+}
+
+TEST(ThumbISABuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(9, "Tag_THUMB_ISA_use"));
+  EXPECT_TRUE(testBuildAttr(9, 0, ARMBuildAttrs::THUMB_ISA_use,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(9, 1, ARMBuildAttrs::THUMB_ISA_use,
+                               ARMBuildAttrs::Allowed));
+}
+
+TEST(FPArchBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(10, "Tag_FP_arch"));
+  EXPECT_TRUE(testBuildAttr(10, 0, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(10, 1, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::Allowed));
+  EXPECT_TRUE(testBuildAttr(10, 2, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv2));
+  EXPECT_TRUE(testBuildAttr(10, 3, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv3A));
+  EXPECT_TRUE(testBuildAttr(10, 4, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv3B));
+  EXPECT_TRUE(testBuildAttr(10, 5, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv4A));
+  EXPECT_TRUE(testBuildAttr(10, 6, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv4B));
+  EXPECT_TRUE(testBuildAttr(10, 7, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPARMv8A));
+  EXPECT_TRUE(testBuildAttr(10, 8, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPARMv8B));
+}
+
+TEST(WMMXBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(11, "Tag_WMMX_arch"));
+  EXPECT_TRUE(testBuildAttr(11, 0, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(11, 1, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::AllowWMMXv1));
+  EXPECT_TRUE(testBuildAttr(11, 2, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::AllowWMMXv2));
+}
+
+TEST(SIMDBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(12, "Tag_Advanced_SIMD_arch"));
+  EXPECT_TRUE(testBuildAttr(12, 0, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(12, 1, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeon));
+  EXPECT_TRUE(testBuildAttr(12, 2, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeon2));
+  EXPECT_TRUE(testBuildAttr(12, 3, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeonARMv8));
+  EXPECT_TRUE(testBuildAttr(12, 4, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeonARMv8_1a));
+}
+
+TEST(FPHPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(36, "Tag_FP_HP_extension"));
+  EXPECT_TRUE(testBuildAttr(36, 0, ARMBuildAttrs::FP_HP_extension,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(36, 1, ARMBuildAttrs::FP_HP_extension,
+                            ARMBuildAttrs::AllowHPFP));
+}
+
+TEST(CPUAlignBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(34, "Tag_CPU_unaligned_access"));
+  EXPECT_TRUE(testBuildAttr(34, 0, ARMBuildAttrs::CPU_unaligned_access,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(34, 1, ARMBuildAttrs::CPU_unaligned_access,
+                            ARMBuildAttrs::Allowed));
+}
+
+TEST(T2EEBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(66, "Tag_T2EE_use"));
+  EXPECT_TRUE(testBuildAttr(66, 0, ARMBuildAttrs::T2EE_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(66, 1, ARMBuildAttrs::T2EE_use,
+                            ARMBuildAttrs::Allowed));
+}
+
+TEST(VirtualizationBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(68, "Tag_Virtualization_use"));
+  EXPECT_TRUE(testBuildAttr(68, 0, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(68, 1, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowTZ));
+  EXPECT_TRUE(testBuildAttr(68, 2, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowVirtualization));
+  EXPECT_TRUE(testBuildAttr(68, 3, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowTZVirtualization));
+}
+
+TEST(MPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(42, "Tag_MPextension_use"));
+  EXPECT_TRUE(testBuildAttr(42, 0, ARMBuildAttrs::MPextension_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(42, 1, ARMBuildAttrs::MPextension_use,
+                            ARMBuildAttrs::AllowMP));
+}
+
+TEST(DivBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(44, "Tag_DIV_use"));
+  EXPECT_TRUE(testBuildAttr(44, 0, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::AllowDIVIfExists));
+  EXPECT_TRUE(testBuildAttr(44, 1, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::DisallowDIV));
+  EXPECT_TRUE(testBuildAttr(44, 2, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::AllowDIVExt));
+}
+
+TEST(PCS_ConfigBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(13, "Tag_PCS_config"));
+  EXPECT_TRUE(testBuildAttr(13, 0, ARMBuildAttrs::PCS_config, 0));
+  EXPECT_TRUE(testBuildAttr(13, 1, ARMBuildAttrs::PCS_config, 1));
+  EXPECT_TRUE(testBuildAttr(13, 2, ARMBuildAttrs::PCS_config, 2));
+  EXPECT_TRUE(testBuildAttr(13, 3, ARMBuildAttrs::PCS_config, 3));
+  EXPECT_TRUE(testBuildAttr(13, 4, ARMBuildAttrs::PCS_config, 4));
+  EXPECT_TRUE(testBuildAttr(13, 5, ARMBuildAttrs::PCS_config, 5));
+  EXPECT_TRUE(testBuildAttr(13, 6, ARMBuildAttrs::PCS_config, 6));
+  EXPECT_TRUE(testBuildAttr(13, 7, ARMBuildAttrs::PCS_config, 7));
+}
+
+TEST(PCS_R9BuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(14, "Tag_ABI_PCS_R9_use"));
+  EXPECT_TRUE(testBuildAttr(14, 0, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsGPR));
+  EXPECT_TRUE(testBuildAttr(14, 1, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsSB));
+  EXPECT_TRUE(testBuildAttr(14, 2, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsTLSPointer));
+  EXPECT_TRUE(testBuildAttr(14, 3, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9Reserved));
+}
+
+TEST(PCS_RWBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(15, "Tag_ABI_PCS_RW_data"));
+  EXPECT_TRUE(testBuildAttr(15, 0, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(15, 1, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWPCRel));
+  EXPECT_TRUE(testBuildAttr(15, 2, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWSBRel));
+  EXPECT_TRUE(testBuildAttr(15, 3, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWNone));
+}
+
+TEST(PCS_ROBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(16, "Tag_ABI_PCS_RO_data"));
+  EXPECT_TRUE(testBuildAttr(16, 0, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(16, 1, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::AddressROPCRel));
+  EXPECT_TRUE(testBuildAttr(16, 2, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::AddressRONone));
+}
+
+TEST(PCS_GOTBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(17, "Tag_ABI_PCS_GOT_use"));
+  EXPECT_TRUE(testBuildAttr(17, 0, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(17, 1, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::AddressDirect));
+  EXPECT_TRUE(testBuildAttr(17, 2, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::AddressGOT));
+}
+
+TEST(PCS_WCharBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(18, "Tag_ABI_PCS_wchar_t"));
+  EXPECT_TRUE(testBuildAttr(18, 0, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharProhibited));
+  EXPECT_TRUE(testBuildAttr(18, 2, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharWidth2Bytes));
+  EXPECT_TRUE(testBuildAttr(18, 4, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharWidth4Bytes));
+}
+
+TEST(EnumSizeBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(26, "Tag_ABI_enum_size"));
+  EXPECT_TRUE(testBuildAttr(26, 0, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::EnumProhibited));
+  EXPECT_TRUE(testBuildAttr(26, 1, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::EnumSmallest));
+  EXPECT_TRUE(testBuildAttr(26, 2, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::Enum32Bit));
+  EXPECT_TRUE(testBuildAttr(26, 3, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::Enum32BitABI));
+}
+
+TEST(AlignNeededBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(24, "Tag_ABI_align_needed"));
+  EXPECT_TRUE(testBuildAttr(24, 0, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(24, 1, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Align8Byte));
+  EXPECT_TRUE(testBuildAttr(24, 2, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Align4Byte));
+  EXPECT_TRUE(testBuildAttr(24, 3, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::AlignReserved));
+}
+
+TEST(AlignPreservedBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(25, "Tag_ABI_align_preserved"));
+  EXPECT_TRUE(testBuildAttr(25, 0, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignNotPreserved));
+  EXPECT_TRUE(testBuildAttr(25, 1, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignPreserve8Byte));
+  EXPECT_TRUE(testBuildAttr(25, 2, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignPreserveAll));
+  EXPECT_TRUE(testBuildAttr(25, 3, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignReserved));
+}
+
+TEST(FPRoundingBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(19, "Tag_ABI_FP_rounding"));
+  EXPECT_TRUE(testBuildAttr(19, 0, ARMBuildAttrs::ABI_FP_rounding, 0));
+  EXPECT_TRUE(testBuildAttr(19, 1, ARMBuildAttrs::ABI_FP_rounding, 1));
+}
+
+TEST(FPDenormalBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(20, "Tag_ABI_FP_denormal"));
+  EXPECT_TRUE(testBuildAttr(20, 0, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::PositiveZero));
+  EXPECT_TRUE(testBuildAttr(20, 1, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::IEEEDenormals));
+  EXPECT_TRUE(testBuildAttr(20, 2, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::PreserveFPSign));
+}
+
+TEST(FPExceptionsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(21, "Tag_ABI_FP_exceptions"));
+  EXPECT_TRUE(testBuildAttr(21, 0, ARMBuildAttrs::ABI_FP_exceptions, 0));
+  EXPECT_TRUE(testBuildAttr(21, 1, ARMBuildAttrs::ABI_FP_exceptions, 1));
+}
+
+TEST(FPUserExceptionsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(22, "Tag_ABI_FP_user_exceptions"));
+  EXPECT_TRUE(testBuildAttr(22, 0, ARMBuildAttrs::ABI_FP_user_exceptions, 0));
+  EXPECT_TRUE(testBuildAttr(22, 1, ARMBuildAttrs::ABI_FP_user_exceptions, 1));
+}
+
+TEST(FPNumberModelBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(23, "Tag_ABI_FP_number_model"));
+  EXPECT_TRUE(testBuildAttr(23, 0, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(23, 1, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowIEEENormal));
+  EXPECT_TRUE(testBuildAttr(23, 2, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowRTABI));
+  EXPECT_TRUE(testBuildAttr(23, 3, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowIEEE754));
+}
+
+TEST(FP16BuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(38, "Tag_ABI_FP_16bit_format"));
+  EXPECT_TRUE(testBuildAttr(38, 0, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(38, 1, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::FP16FormatIEEE));
+  EXPECT_TRUE(testBuildAttr(38, 2, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::FP16VFP3));
+}
+
+TEST(HardFPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(27, "Tag_ABI_HardFP_use"));
+  EXPECT_TRUE(testBuildAttr(27, 0, ARMBuildAttrs::ABI_HardFP_use,
+                            ARMBuildAttrs::HardFPImplied));
+  EXPECT_TRUE(testBuildAttr(27, 1, ARMBuildAttrs::ABI_HardFP_use,
+                            ARMBuildAttrs::HardFPSinglePrecision));
+  EXPECT_TRUE(testBuildAttr(27, 2, ARMBuildAttrs::ABI_HardFP_use, 2));
+}
+
+TEST(VFPArgsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(28, "Tag_ABI_VFP_args"));
+  EXPECT_TRUE(testBuildAttr(28, 0, ARMBuildAttrs::ABI_VFP_args,
+                            ARMBuildAttrs::BaseAAPCS));
+  EXPECT_TRUE(testBuildAttr(28, 1, ARMBuildAttrs::ABI_VFP_args,
+                            ARMBuildAttrs::HardFPAAPCS));
+  EXPECT_TRUE(testBuildAttr(28, 2, ARMBuildAttrs::ABI_VFP_args, 2));
+  EXPECT_TRUE(testBuildAttr(28, 3, ARMBuildAttrs::ABI_VFP_args, 3));
+}
+
+TEST(WMMXArgsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(29, "Tag_ABI_WMMX_args"));
+  EXPECT_TRUE(testBuildAttr(29, 0, ARMBuildAttrs::ABI_WMMX_args, 0));
+  EXPECT_TRUE(testBuildAttr(29, 1, ARMBuildAttrs::ABI_WMMX_args, 1));
+  EXPECT_TRUE(testBuildAttr(29, 2, ARMBuildAttrs::ABI_WMMX_args, 2));
+}

Modified: llvm/trunk/unittests/Support/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=292366&r1=292365&r2=292366&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Support/CMakeLists.txt Wed Jan 18 07:52:12 2017
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
 add_llvm_unittest(SupportTests
   AlignOfTest.cpp
   AllocatorTest.cpp
+  ARMAttributeParser.cpp
   ArrayRecyclerTest.cpp
   BlockFrequencyTest.cpp
   BranchProbabilityTest.cpp


_______________________________________________
llvm-commits mailing list
llvm-commits at lists.llvm.org<mailto:llvm-commits at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170201/598e6f5c/attachment.html>


More information about the llvm-commits mailing list