mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
[ARM] Enable objdump to construct triple for ARM
Now that The ARMAttributeParser has been moved into the library, it has been modified so that it can parse the attributes without printing them and stores them in a map. ELFObjectFile now queries the attributes to fill out the architecture details of a provided triple for 'arm' and 'thumb' targets. llvm-objdump uses this new functionality. Differential Revision: https://reviews.llvm.org/D28281 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291898 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e2892e1556
commit
6968dd2f43
@ -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; }
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {}
|
||||
|
||||
void Parse(ArrayRef<uint8_t> Section);
|
||||
ARMAttributeParser() : SW(nullptr) { }
|
||||
|
||||
void Parse(ArrayRef<uint8_t> Section, bool isLittle);
|
||||
|
||||
bool hasAttribute(unsigned Tag) const {
|
||||
return Attributes.count(Tag);
|
||||
}
|
||||
|
||||
unsigned getAttributeValue(unsigned Tag) const {
|
||||
return Attributes.find(Tag)->second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -122,4 +122,69 @@ SubtargetFeatures ELFObjectFileBase::getFeatures() const {
|
||||
}
|
||||
}
|
||||
|
||||
// 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";
|
||||
|
||||
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
|
||||
|
@ -89,32 +89,43 @@ StringRef ARMAttributeParser::ParseString(const uint8_t *Data,
|
||||
|
||||
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 (SW) {
|
||||
DictScope AS(*SW, "Attribute");
|
||||
SW->printNumber("Tag", Tag);
|
||||
if (!TagName.empty())
|
||||
SW.printString("TagName", TagName);
|
||||
SW.printString("Value", ParseString(Data, Offset));
|
||||
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 (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);
|
||||
SW->printString("TagName", TagName);
|
||||
if (!ValueDesc.empty())
|
||||
SW.printString("Description", ValueDesc);
|
||||
SW->printString("Description", ValueDesc);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMAttributeParser::CPU_arch(AttrType Tag, const uint8_t *Data,
|
||||
@ -449,21 +460,23 @@ void ARMAttributeParser::compatibility(AttrType Tag, const uint8_t *Data,
|
||||
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));
|
||||
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"));
|
||||
SW->printString("Description", StringRef("No Specific Requirements"));
|
||||
break;
|
||||
case 1:
|
||||
SW.printString("Description", StringRef("AEABI Conformant"));
|
||||
SW->printString("Description", StringRef("AEABI Conformant"));
|
||||
break;
|
||||
default:
|
||||
SW.printString("Description", StringRef("AEABI Non-Conformant"));
|
||||
SW->printString("Description", StringRef("AEABI Non-Conformant"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMAttributeParser::CPU_unaligned_access(AttrType Tag, const uint8_t *Data,
|
||||
@ -604,27 +617,33 @@ void ARMAttributeParser::ParseAttributeList(const uint8_t *Data,
|
||||
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,37 @@ void ARMAttributeParser::ParseSubsection(const uint8_t *Data, uint32_t Length) {
|
||||
return;
|
||||
}
|
||||
|
||||
DictScope ASS(SW, ScopeName);
|
||||
|
||||
if (SW) {
|
||||
DictScope ASS(*SW, ScopeName);
|
||||
if (!Indicies.empty())
|
||||
SW.printList(IndexName, Indicies);
|
||||
SW->printList(IndexName, Indicies);
|
||||
}
|
||||
|
||||
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);
|
||||
uint32_t SectionLength = isLittle ?
|
||||
*reinterpret_cast<const support::ulittle32_t*>(Section.data() + Offset) :
|
||||
*reinterpret_cast<const support::ubig32_t*>(Section.data() + Offset);
|
||||
|
||||
SW.startLine() << "Section " << ++SectionNumber << " {\n";
|
||||
SW.indent();
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
10
test/tools/llvm-objdump/ARM/v5t-subarch.s
Normal file
10
test/tools/llvm-objdump/ARM/v5t-subarch.s
Normal file
@ -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
|
||||
|
10
test/tools/llvm-objdump/ARM/v5te-subarch.s
Normal file
10
test/tools/llvm-objdump/ARM/v5te-subarch.s
Normal file
@ -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]
|
||||
|
7
test/tools/llvm-objdump/ARM/v5tej-subarch.s
Normal file
7
test/tools/llvm-objdump/ARM/v5tej-subarch.s
Normal file
@ -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
|
9
test/tools/llvm-objdump/ARM/v6-subarch.s
Normal file
9
test/tools/llvm-objdump/ARM/v6-subarch.s
Normal file
@ -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
|
9
test/tools/llvm-objdump/ARM/v6k-subarch.s
Normal file
9
test/tools/llvm-objdump/ARM/v6k-subarch.s
Normal file
@ -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
|
9
test/tools/llvm-objdump/ARM/v6m-subarch.s
Normal file
9
test/tools/llvm-objdump/ARM/v6m-subarch.s
Normal file
@ -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
|
10
test/tools/llvm-objdump/ARM/v6t2-subarch.s
Normal file
10
test/tools/llvm-objdump/ARM/v6t2-subarch.s
Normal file
@ -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
|
10
test/tools/llvm-objdump/ARM/v7m-subarch.s
Normal file
10
test/tools/llvm-objdump/ARM/v7m-subarch.s
Normal file
@ -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
|
||||
|
@ -357,7 +357,16 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) {
|
||||
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 ObjectFile *Obj = nullptr) {
|
||||
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;
|
||||
|
@ -1892,7 +1892,7 @@ template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
|
||||
if (Contents.size() == 1)
|
||||
continue;
|
||||
|
||||
ARMAttributeParser(W).Parse(Contents);
|
||||
ARMAttributeParser(&W).Parse(Contents, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
384
unittests/Support/ARMAttributeParser.cpp
Normal file
384
unittests/Support/ARMAttributeParser.cpp
Normal file
@ -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));
|
||||
}
|
@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
add_llvm_unittest(SupportTests
|
||||
AlignOfTest.cpp
|
||||
AllocatorTest.cpp
|
||||
ARMAttributeParser.cpp
|
||||
ArrayRecyclerTest.cpp
|
||||
BlockFrequencyTest.cpp
|
||||
BranchProbabilityTest.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user