mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
[arm] Implement eabi_attribute, cpu, and fpu directives.
This commit allows the ARM integrated assembler to parse and assemble the code with .eabi_attribute, .cpu, and .fpu directives. To implement the feature, this commit moves the code from AttrEmitter to ARMTargetStreamers, and several new test cases related to cortex-m4, cortex-r5, and cortex-a15 are added. Besides, this commit also change the Subtarget->isFPOnlySP() to Subtarget->hasD16() to match the usage of .fpu directive. This commit changes the test cases: * Several .eabi_attribute directives in 2010-09-29-mc-asm-header-test.ll are removed because the .fpu directive already cover the functionality. * In the Cortex-A15 test case, the value for Tag_Advanced_SIMD_arch has be changed from 1 to 2, which is more precise. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193524 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
790b973f80
commit
23125d02d9
@ -87,6 +87,12 @@ public:
|
||||
virtual void emitPad(int64_t Offset) = 0;
|
||||
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
|
||||
bool isVector) = 0;
|
||||
|
||||
virtual void switchVendor(StringRef Vendor) = 0;
|
||||
virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
|
||||
virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
|
||||
virtual void emitFPU(unsigned FPU) = 0;
|
||||
virtual void finishAttributeSection() = 0;
|
||||
};
|
||||
|
||||
/// MCStreamer - Streaming machine code generation interface. This interface
|
||||
|
@ -309,7 +309,7 @@ def : ProcessorModel<"cortex-r5", CortexA8Model,
|
||||
[ProcR5, HasV7Ops, FeatureDB,
|
||||
FeatureVFP3, FeatureDSPThumb2,
|
||||
FeatureHasRAS, FeatureVFPOnlySP,
|
||||
FeatureRClass]>;
|
||||
FeatureD16, FeatureRClass]>;
|
||||
|
||||
// V7M Processors.
|
||||
def : ProcNoItin<"cortex-m3", [HasV7Ops,
|
||||
@ -321,7 +321,8 @@ def : ProcNoItin<"cortex-m4", [HasV7Ops,
|
||||
FeatureThumb2, FeatureNoARM, FeatureDB,
|
||||
FeatureHWDiv, FeatureDSPThumb2,
|
||||
FeatureT2XtPk, FeatureVFP4,
|
||||
FeatureVFPOnlySP, FeatureMClass]>;
|
||||
FeatureVFPOnlySP, FeatureD16,
|
||||
FeatureMClass]>;
|
||||
|
||||
// Swift uArch Processors.
|
||||
def : ProcessorModel<"swift", SwiftModel,
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "ARM.h"
|
||||
#include "ARMBuildAttrs.h"
|
||||
#include "ARMConstantPoolValue.h"
|
||||
#include "ARMFPUName.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
#include "ARMTargetMachine.h"
|
||||
#include "ARMTargetObjectFile.h"
|
||||
@ -55,164 +56,6 @@
|
||||
#include <cctype>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
// Per section and per symbol attributes are not supported.
|
||||
// To implement them we would need the ability to delay this emission
|
||||
// until the assembly file is fully parsed/generated as only then do we
|
||||
// know the symbol and section numbers.
|
||||
class AttributeEmitter {
|
||||
public:
|
||||
virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
|
||||
virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
|
||||
virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
|
||||
virtual void Finish() = 0;
|
||||
virtual ~AttributeEmitter() {}
|
||||
};
|
||||
|
||||
class AsmAttributeEmitter : public AttributeEmitter {
|
||||
MCStreamer &Streamer;
|
||||
|
||||
public:
|
||||
AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
|
||||
void MaybeSwitchVendor(StringRef Vendor) { }
|
||||
|
||||
void EmitAttribute(unsigned Attribute, unsigned Value) {
|
||||
Streamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(Attribute) + ", " + Twine(Value));
|
||||
}
|
||||
|
||||
void EmitTextAttribute(unsigned Attribute, StringRef String) {
|
||||
switch (Attribute) {
|
||||
default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
|
||||
case ARMBuildAttrs::CPU_name:
|
||||
Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower());
|
||||
break;
|
||||
/* GAS requires .fpu to be emitted regardless of EABI attribute */
|
||||
case ARMBuildAttrs::Advanced_SIMD_arch:
|
||||
case ARMBuildAttrs::VFP_arch:
|
||||
Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Finish() { }
|
||||
};
|
||||
|
||||
class ObjectAttributeEmitter : public AttributeEmitter {
|
||||
// This structure holds all attributes, accounting for
|
||||
// their string/numeric value, so we can later emmit them
|
||||
// in declaration order, keeping all in the same vector
|
||||
struct AttributeItemType {
|
||||
enum {
|
||||
HiddenAttribute = 0,
|
||||
NumericAttribute,
|
||||
TextAttribute
|
||||
} Type;
|
||||
unsigned Tag;
|
||||
unsigned IntValue;
|
||||
StringRef StringValue;
|
||||
};
|
||||
|
||||
MCObjectStreamer &Streamer;
|
||||
StringRef CurrentVendor;
|
||||
SmallVector<AttributeItemType, 64> Contents;
|
||||
|
||||
// Account for the ULEB/String size of each item,
|
||||
// not just the number of items
|
||||
size_t ContentsSize;
|
||||
// FIXME: this should be in a more generic place, but
|
||||
// getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
|
||||
size_t getULEBSize(int Value) {
|
||||
size_t Size = 0;
|
||||
do {
|
||||
Value >>= 7;
|
||||
Size += sizeof(int8_t); // Is this really necessary?
|
||||
} while (Value);
|
||||
return Size;
|
||||
}
|
||||
|
||||
public:
|
||||
ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
|
||||
Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
|
||||
|
||||
void MaybeSwitchVendor(StringRef Vendor) {
|
||||
assert(!Vendor.empty() && "Vendor cannot be empty.");
|
||||
|
||||
if (CurrentVendor.empty())
|
||||
CurrentVendor = Vendor;
|
||||
else if (CurrentVendor == Vendor)
|
||||
return;
|
||||
else
|
||||
Finish();
|
||||
|
||||
CurrentVendor = Vendor;
|
||||
|
||||
assert(Contents.size() == 0);
|
||||
}
|
||||
|
||||
void EmitAttribute(unsigned Attribute, unsigned Value) {
|
||||
AttributeItemType attr = {
|
||||
AttributeItemType::NumericAttribute,
|
||||
Attribute,
|
||||
Value,
|
||||
StringRef("")
|
||||
};
|
||||
ContentsSize += getULEBSize(Attribute);
|
||||
ContentsSize += getULEBSize(Value);
|
||||
Contents.push_back(attr);
|
||||
}
|
||||
|
||||
void EmitTextAttribute(unsigned Attribute, StringRef String) {
|
||||
AttributeItemType attr = {
|
||||
AttributeItemType::TextAttribute,
|
||||
Attribute,
|
||||
0,
|
||||
String
|
||||
};
|
||||
ContentsSize += getULEBSize(Attribute);
|
||||
// String + \0
|
||||
ContentsSize += String.size()+1;
|
||||
|
||||
Contents.push_back(attr);
|
||||
}
|
||||
|
||||
void Finish() {
|
||||
// Vendor size + Vendor name + '\0'
|
||||
const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
|
||||
|
||||
// Tag + Tag Size
|
||||
const size_t TagHeaderSize = 1 + 4;
|
||||
|
||||
Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
|
||||
Streamer.EmitBytes(CurrentVendor);
|
||||
Streamer.EmitIntValue(0, 1); // '\0'
|
||||
|
||||
Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
|
||||
Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
|
||||
|
||||
// Size should have been accounted for already, now
|
||||
// emit each field as its type (ULEB or String)
|
||||
for (unsigned int i=0; i<Contents.size(); ++i) {
|
||||
AttributeItemType item = Contents[i];
|
||||
Streamer.EmitULEB128IntValue(item.Tag);
|
||||
switch (item.Type) {
|
||||
default: llvm_unreachable("Invalid attribute type");
|
||||
case AttributeItemType::NumericAttribute:
|
||||
Streamer.EmitULEB128IntValue(item.IntValue);
|
||||
break;
|
||||
case AttributeItemType::TextAttribute:
|
||||
Streamer.EmitBytes(item.StringValue.upper());
|
||||
Streamer.EmitIntValue(0, 1); // '\0'
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Contents.clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
/// EmitDwarfRegOp - Emit dwarf register operation.
|
||||
void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
|
||||
bool Indirect) const {
|
||||
@ -768,149 +611,102 @@ static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU,
|
||||
}
|
||||
|
||||
void ARMAsmPrinter::emitAttributes() {
|
||||
MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
|
||||
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
|
||||
|
||||
emitARMAttributeSection();
|
||||
|
||||
/* GAS expect .fpu to be emitted, regardless of VFP build attribute */
|
||||
bool emitFPU = false;
|
||||
AttributeEmitter *AttrEmitter;
|
||||
if (OutStreamer.hasRawTextSupport()) {
|
||||
AttrEmitter = new AsmAttributeEmitter(OutStreamer);
|
||||
emitFPU = true;
|
||||
} else {
|
||||
MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
|
||||
AttrEmitter = new ObjectAttributeEmitter(O);
|
||||
}
|
||||
|
||||
AttrEmitter->MaybeSwitchVendor("aeabi");
|
||||
ATS.switchVendor("aeabi");
|
||||
|
||||
std::string CPUString = Subtarget->getCPUString();
|
||||
|
||||
if (CPUString != "generic")
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
|
||||
ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
|
||||
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch,
|
||||
getArchForCPU(CPUString, Subtarget));
|
||||
ATS.emitAttribute(ARMBuildAttrs::CPU_arch,
|
||||
getArchForCPU(CPUString, Subtarget));
|
||||
|
||||
if (Subtarget->isAClass()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::ApplicationProfile);
|
||||
ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::ApplicationProfile);
|
||||
} else if (Subtarget->isRClass()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::RealTimeProfile);
|
||||
ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::RealTimeProfile);
|
||||
} else if (Subtarget->isMClass()){
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::MicroControllerProfile);
|
||||
ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
|
||||
ARMBuildAttrs::MicroControllerProfile);
|
||||
}
|
||||
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?
|
||||
ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?
|
||||
ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);
|
||||
if (Subtarget->isThumb1Only()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
|
||||
ARMBuildAttrs::Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
|
||||
ARMBuildAttrs::Allowed);
|
||||
} else if (Subtarget->hasThumb2()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
|
||||
ARMBuildAttrs::AllowThumb32);
|
||||
ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
|
||||
ARMBuildAttrs::AllowThumb32);
|
||||
}
|
||||
|
||||
if (Subtarget->hasNEON() && emitFPU) {
|
||||
if (Subtarget->hasNEON()) {
|
||||
/* NEON is not exactly a VFP architecture, but GAS emit one of
|
||||
* neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
|
||||
if (Subtarget->hasFPARMv8()) {
|
||||
if (Subtarget->hasCrypto())
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
"crypto-neon-fp-armv8");
|
||||
ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8);
|
||||
else
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
"neon-fp-armv8");
|
||||
ATS.emitFPU(ARM::NEON_FP_ARMV8);
|
||||
}
|
||||
else if (Subtarget->hasVFP4())
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
"neon-vfpv4");
|
||||
ATS.emitFPU(ARM::NEON_VFPV4);
|
||||
else
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
|
||||
/* If emitted for NEON, omit from VFP below, since you can have both
|
||||
* NEON and VFP in build attributes but only one .fpu */
|
||||
emitFPU = false;
|
||||
}
|
||||
|
||||
/* FPARMv8 + .fpu */
|
||||
if (Subtarget->hasFPARMv8()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPARMv8A);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "fp-armv8");
|
||||
/* VFPv4 + .fpu */
|
||||
} else if (Subtarget->hasVFP4()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
Subtarget->isFPOnlySP() ? ARMBuildAttrs::AllowFPv4B :
|
||||
ARMBuildAttrs::AllowFPv4A);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
|
||||
|
||||
/* VFPv3 + .fpu */
|
||||
} else if (Subtarget->hasVFP3()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
Subtarget->isFPOnlySP() ? ARMBuildAttrs::AllowFPv3B :
|
||||
ARMBuildAttrs::AllowFPv3A);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
|
||||
|
||||
/* VFPv2 + .fpu */
|
||||
} else if (Subtarget->hasVFP2()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv2);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
|
||||
}
|
||||
|
||||
/* TODO: ARMBuildAttrs::Allowed is not completely accurate,
|
||||
* since NEON can have 1 (allowed) or 2 (MAC operations) */
|
||||
if (Subtarget->hasNEON()) {
|
||||
ATS.emitFPU(ARM::NEON);
|
||||
// Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
|
||||
if (Subtarget->hasV8Ops())
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::AllowedNeonV8);
|
||||
else
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::AllowNeonARMv8);
|
||||
} else {
|
||||
if (Subtarget->hasFPARMv8())
|
||||
ATS.emitFPU(ARM::FP_ARMV8);
|
||||
else if (Subtarget->hasVFP4())
|
||||
ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
|
||||
else if (Subtarget->hasVFP3())
|
||||
ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
|
||||
else if (Subtarget->hasVFP2())
|
||||
ATS.emitFPU(ARM::VFPV2);
|
||||
}
|
||||
|
||||
// Signal various FP modes.
|
||||
if (!TM.Options.UnsafeFPMath) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
|
||||
ARMBuildAttrs::Allowed);
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
|
||||
ARMBuildAttrs::Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
|
||||
ARMBuildAttrs::Allowed);
|
||||
}
|
||||
|
||||
if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
|
||||
ARMBuildAttrs::Allowed);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
|
||||
ARMBuildAttrs::Allowed);
|
||||
else
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
|
||||
ARMBuildAttrs::AllowIEE754);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
|
||||
ARMBuildAttrs::AllowIEE754);
|
||||
|
||||
// FIXME: add more flags to ARMBuildAttrs.h
|
||||
// 8-bytes alignment stuff.
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
|
||||
|
||||
// Hard float. Use both S and D registers and conform to AAPCS-VFP.
|
||||
if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
|
||||
ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
|
||||
}
|
||||
// FIXME: Should we signal R9 usage?
|
||||
|
||||
if (Subtarget->hasDivide()) {
|
||||
// Check if hardware divide is only available in thumb2 or ARM as well.
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use,
|
||||
ATS.emitAttribute(ARMBuildAttrs::DIV_use,
|
||||
Subtarget->hasDivideInARMMode() ? ARMBuildAttrs::AllowDIVExt :
|
||||
ARMBuildAttrs::AllowDIVIfExists);
|
||||
}
|
||||
|
||||
AttrEmitter->Finish();
|
||||
delete AttrEmitter;
|
||||
ATS.finishAttributeSection();
|
||||
}
|
||||
|
||||
void ARMAsmPrinter::emitARMAttributeSection() {
|
||||
|
@ -15,11 +15,13 @@
|
||||
#ifndef __TARGET_ARMBUILDATTRS_H__
|
||||
#define __TARGET_ARMBUILDATTRS_H__
|
||||
|
||||
namespace llvm {
|
||||
namespace ARMBuildAttrs {
|
||||
|
||||
enum SpecialAttr {
|
||||
// This is for the .cpu asm attr. It translates into one or more
|
||||
// AttrType (below) entries in the .ARM.attributes section in the ELF.
|
||||
SEL_CPU
|
||||
SEL_CPU
|
||||
};
|
||||
|
||||
enum AttrType {
|
||||
@ -93,7 +95,7 @@ namespace ARMBuildAttrs {
|
||||
v8 = 14 // v8, AArch32
|
||||
};
|
||||
|
||||
enum CPUArchProfile { // (=7), uleb128
|
||||
enum CPUArchProfile { // (=7), uleb128
|
||||
Not_Applicable = 0, // pre v7, or cross-profile code
|
||||
ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
|
||||
RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
|
||||
@ -102,40 +104,50 @@ namespace ARMBuildAttrs {
|
||||
};
|
||||
|
||||
// The following have a lot of common use cases
|
||||
enum {
|
||||
enum {
|
||||
//ARMISAUse (=8), uleb128 and THUMBISAUse (=9), uleb128
|
||||
Not_Allowed = 0,
|
||||
Allowed = 1,
|
||||
AllowedNeonV8 = 3,
|
||||
|
||||
// FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
|
||||
AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
|
||||
AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
|
||||
AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
|
||||
AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
|
||||
AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
|
||||
AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
|
||||
AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
|
||||
AllowFPARMv8A = 7, // Use of the ARM v8-A FP ISA was permitted
|
||||
AllowFPARMv8B = 8, // Use of the ARM v8-A FP ISA was permitted, but only D0-D15, S0-S31
|
||||
|
||||
// Tag_WMMX_arch, (=11), uleb128
|
||||
AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
|
||||
|
||||
|
||||
// Tag_WMMX_arch, (=11), uleb128
|
||||
AllowWMMXv1 = 2, // The user permitted this entity to use WMMX v2
|
||||
|
||||
// Tag_ABI_FP_denormal, (=20), uleb128
|
||||
// Tag_Advanced_SIMD_arch, (=12), uleb128
|
||||
AllowNeon = 1, // SIMDv1 was permitted
|
||||
AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
|
||||
AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
|
||||
|
||||
// Tag_ABI_FP_denormal, (=20), uleb128
|
||||
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
|
||||
|
||||
// Tag_ABI_FP_number_model, (=23), uleb128
|
||||
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
|
||||
AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
|
||||
|
||||
// Tag_ABI_HardFP_use, (=27), uleb128
|
||||
HardFPSinglePrecision = 1, // Single-precision only
|
||||
HardFPImplied = 3, // FP use should be implied by Tag_FP_arch
|
||||
|
||||
// Tag_DIV_use, (=44), uleb128
|
||||
AllowDIVIfExists = 0, // Allow hardware divide if available in arch, or no info exists.
|
||||
DisallowDIV = 1, // Hardware divide explicitly disallowed
|
||||
AllowDIVExt = 2 // Allow hardware divide as optional architecture extension above
|
||||
// the base arch specified by Tag_CPU_arch and Tag_CPU_arch_profile.
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace ARMBuildAttrs
|
||||
} // namespace llvm
|
||||
|
||||
#endif // __TARGET_ARMBUILDATTRS_H__
|
||||
|
32
lib/Target/ARM/ARMFPUName.def
Normal file
32
lib/Target/ARM/ARMFPUName.def
Normal file
@ -0,0 +1,32 @@
|
||||
//===-- ARMFPUName.def - List of the ARM FPU names --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the list of the supported ARM FPU names.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// NOTE: NO INCLUDE GUARD DESIRED!
|
||||
|
||||
#ifndef ARM_FPU_NAME
|
||||
#error "You must define ARM_FPU_NAME(NAME, ID) before including ARMFPUName.h"
|
||||
#endif
|
||||
|
||||
ARM_FPU_NAME("vfp", VFP)
|
||||
ARM_FPU_NAME("vfpv2", VFPV2)
|
||||
ARM_FPU_NAME("vfpv3", VFPV3)
|
||||
ARM_FPU_NAME("vfpv3-d16", VFPV3_D16)
|
||||
ARM_FPU_NAME("vfpv4", VFPV4)
|
||||
ARM_FPU_NAME("vfpv4-d16", VFPV4_D16)
|
||||
ARM_FPU_NAME("fp-armv8", FP_ARMV8)
|
||||
ARM_FPU_NAME("neon", NEON)
|
||||
ARM_FPU_NAME("neon-vfpv4", NEON_VFPV4)
|
||||
ARM_FPU_NAME("neon-fp-armv8", NEON_FP_ARMV8)
|
||||
ARM_FPU_NAME("crypto-neon-fp-armv8", CRYPTO_NEON_FP_ARMV8)
|
||||
|
||||
#undef ARM_FPU_NAME
|
26
lib/Target/ARM/ARMFPUName.h
Normal file
26
lib/Target/ARM/ARMFPUName.h
Normal file
@ -0,0 +1,26 @@
|
||||
//===-- ARMFPUName.h - List of the ARM FPU names ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ARMFPUNAME_H
|
||||
#define ARMFPUNAME_H
|
||||
|
||||
namespace llvm {
|
||||
namespace ARM {
|
||||
|
||||
enum FPUKind {
|
||||
INVALID_FPU = 0
|
||||
|
||||
#define ARM_FPU_NAME(NAME, ID) , ID
|
||||
#include "ARMFPUName.def"
|
||||
};
|
||||
|
||||
} // namespace ARM
|
||||
} // namespace llvm
|
||||
|
||||
#endif // ARMFPUNAME_H
|
@ -7,6 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ARMBuildAttrs.h"
|
||||
#include "ARMFPUName.h"
|
||||
#include "ARMFeatures.h"
|
||||
#include "llvm/MC/MCTargetAsmParser.h"
|
||||
#include "MCTargetDesc/ARMAddressingModes.h"
|
||||
@ -137,6 +139,8 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
bool parseDirectiveUnreq(SMLoc L);
|
||||
bool parseDirectiveArch(SMLoc L);
|
||||
bool parseDirectiveEabiAttr(SMLoc L);
|
||||
bool parseDirectiveCPU(SMLoc L);
|
||||
bool parseDirectiveFPU(SMLoc L);
|
||||
bool parseDirectiveFnStart(SMLoc L);
|
||||
bool parseDirectiveFnEnd(SMLoc L);
|
||||
bool parseDirectiveCantUnwind(SMLoc L);
|
||||
@ -7765,6 +7769,10 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
return parseDirectiveArch(DirectiveID.getLoc());
|
||||
else if (IDVal == ".eabi_attribute")
|
||||
return parseDirectiveEabiAttr(DirectiveID.getLoc());
|
||||
else if (IDVal == ".cpu")
|
||||
return parseDirectiveCPU(DirectiveID.getLoc());
|
||||
else if (IDVal == ".fpu")
|
||||
return parseDirectiveFPU(DirectiveID.getLoc());
|
||||
else if (IDVal == ".fnstart")
|
||||
return parseDirectiveFnStart(DirectiveID.getLoc());
|
||||
else if (IDVal == ".fnend")
|
||||
@ -7987,7 +7995,48 @@ bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
|
||||
/// parseDirectiveEabiAttr
|
||||
/// ::= .eabi_attribute int, int
|
||||
bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
|
||||
return true;
|
||||
if (Parser.getTok().isNot(AsmToken::Integer))
|
||||
return Error(L, "integer expected");
|
||||
int64_t Tag = Parser.getTok().getIntVal();
|
||||
Parser.Lex(); // eat tag integer
|
||||
|
||||
if (Parser.getTok().isNot(AsmToken::Comma))
|
||||
return Error(L, "comma expected");
|
||||
Parser.Lex(); // skip comma
|
||||
|
||||
L = Parser.getTok().getLoc();
|
||||
if (Parser.getTok().isNot(AsmToken::Integer))
|
||||
return Error(L, "integer expected");
|
||||
int64_t Value = Parser.getTok().getIntVal();
|
||||
Parser.Lex(); // eat value integer
|
||||
|
||||
getTargetStreamer().emitAttribute(Tag, Value);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveCPU
|
||||
/// ::= .cpu str
|
||||
bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
|
||||
StringRef CPU = getParser().parseStringToEndOfStatement().trim();
|
||||
getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveFPU
|
||||
/// ::= .fpu str
|
||||
bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
|
||||
StringRef FPU = getParser().parseStringToEndOfStatement().trim();
|
||||
|
||||
unsigned ID = StringSwitch<unsigned>(FPU)
|
||||
#define ARM_FPU_NAME(NAME, ID) .Case(NAME, ARM::ID)
|
||||
#include "ARMFPUName.def"
|
||||
.Default(ARM::INVALID_FPU);
|
||||
|
||||
if (ID == ARM::INVALID_FPU)
|
||||
return Error(L, "Unknown FPU name");
|
||||
|
||||
getTargetStreamer().emitFPU(ID);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveFnStart
|
||||
|
@ -13,6 +13,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ARMBuildAttrs.h"
|
||||
#include "ARMFPUName.h"
|
||||
#include "ARMRegisterInfo.h"
|
||||
#include "ARMUnwindOp.h"
|
||||
#include "ARMUnwindOpAsm.h"
|
||||
@ -39,6 +41,7 @@
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -47,6 +50,17 @@ static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
|
||||
return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
|
||||
}
|
||||
|
||||
static const char *GetFPUName(unsigned ID) {
|
||||
switch (ID) {
|
||||
default:
|
||||
llvm_unreachable("Unknown FPU kind");
|
||||
break;
|
||||
#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME;
|
||||
#include "ARMFPUName.def"
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class ARMELFStreamer;
|
||||
@ -65,6 +79,12 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
|
||||
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
|
||||
bool isVector);
|
||||
|
||||
virtual void switchVendor(StringRef Vendor);
|
||||
virtual void emitAttribute(unsigned Attribute, unsigned Value);
|
||||
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
|
||||
virtual void emitFPU(unsigned FPU);
|
||||
virtual void finishAttributeSection();
|
||||
|
||||
public:
|
||||
ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter);
|
||||
};
|
||||
@ -109,9 +129,114 @@ void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
|
||||
|
||||
OS << "}\n";
|
||||
}
|
||||
void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
|
||||
}
|
||||
void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
|
||||
OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
|
||||
}
|
||||
void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
|
||||
StringRef String) {
|
||||
switch (Attribute) {
|
||||
default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
|
||||
case ARMBuildAttrs::CPU_name:
|
||||
OS << "\t.cpu\t" << String.lower() << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
|
||||
OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
|
||||
}
|
||||
void ARMTargetAsmStreamer::finishAttributeSection() {
|
||||
}
|
||||
|
||||
class ARMTargetELFStreamer : public ARMTargetStreamer {
|
||||
private:
|
||||
// This structure holds all attributes, accounting for
|
||||
// their string/numeric value, so we can later emmit them
|
||||
// in declaration order, keeping all in the same vector
|
||||
struct AttributeItem {
|
||||
enum {
|
||||
HiddenAttribute = 0,
|
||||
NumericAttribute,
|
||||
TextAttribute
|
||||
} Type;
|
||||
unsigned Tag;
|
||||
unsigned IntValue;
|
||||
StringRef StringValue;
|
||||
|
||||
static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
|
||||
return (LHS.Tag < RHS.Tag);
|
||||
}
|
||||
};
|
||||
|
||||
StringRef CurrentVendor;
|
||||
unsigned FPU;
|
||||
SmallVector<AttributeItem, 64> Contents;
|
||||
|
||||
const MCSection *AttributeSection;
|
||||
|
||||
// FIXME: this should be in a more generic place, but
|
||||
// getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
|
||||
static size_t getULEBSize(int Value) {
|
||||
size_t Size = 0;
|
||||
do {
|
||||
Value >>= 7;
|
||||
Size += sizeof(int8_t); // Is this really necessary?
|
||||
} while (Value);
|
||||
return Size;
|
||||
}
|
||||
|
||||
AttributeItem *getAttributeItem(unsigned Attribute) {
|
||||
for (size_t i = 0; i < Contents.size(); ++i)
|
||||
if (Contents[i].Tag == Attribute)
|
||||
return &Contents[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setAttributeItem(unsigned Attribute, unsigned Value,
|
||||
bool OverwriteExisting) {
|
||||
// Look for existing attribute item
|
||||
if (AttributeItem *Item = getAttributeItem(Attribute)) {
|
||||
if (!OverwriteExisting)
|
||||
return;
|
||||
Item->IntValue = Value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new attribute item
|
||||
AttributeItem Item = {
|
||||
AttributeItem::NumericAttribute,
|
||||
Attribute,
|
||||
Value,
|
||||
StringRef("")
|
||||
};
|
||||
Contents.push_back(Item);
|
||||
}
|
||||
|
||||
void setAttributeItem(unsigned Attribute, StringRef Value,
|
||||
bool OverwriteExisting) {
|
||||
// Look for existing attribute item
|
||||
if (AttributeItem *Item = getAttributeItem(Attribute)) {
|
||||
if (!OverwriteExisting)
|
||||
return;
|
||||
Item->StringValue = Value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new attribute item
|
||||
AttributeItem Item = {
|
||||
AttributeItem::TextAttribute,
|
||||
Attribute,
|
||||
0,
|
||||
Value
|
||||
};
|
||||
Contents.push_back(Item);
|
||||
}
|
||||
|
||||
void emitFPUDefaultAttributes();
|
||||
|
||||
ARMELFStreamer &getStreamer();
|
||||
|
||||
virtual void emitFnStart();
|
||||
virtual void emitFnEnd();
|
||||
virtual void emitCantUnwind();
|
||||
@ -121,6 +246,20 @@ class ARMTargetELFStreamer : public ARMTargetStreamer {
|
||||
virtual void emitPad(int64_t Offset);
|
||||
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
|
||||
bool isVector);
|
||||
|
||||
virtual void switchVendor(StringRef Vendor);
|
||||
virtual void emitAttribute(unsigned Attribute, unsigned Value);
|
||||
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
|
||||
virtual void emitFPU(unsigned FPU);
|
||||
virtual void finishAttributeSection();
|
||||
|
||||
size_t calculateContentSize() const;
|
||||
|
||||
public:
|
||||
ARMTargetELFStreamer()
|
||||
: ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
|
||||
AttributeSection(0) {
|
||||
}
|
||||
};
|
||||
|
||||
/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
|
||||
@ -149,6 +288,8 @@ public:
|
||||
|
||||
~ARMELFStreamer() {}
|
||||
|
||||
virtual void FinishImpl();
|
||||
|
||||
// ARM exception handling directives
|
||||
void emitFnStart();
|
||||
void emitFnEnd();
|
||||
@ -329,6 +470,198 @@ void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
|
||||
bool isVector) {
|
||||
getStreamer().emitRegSave(RegList, isVector);
|
||||
}
|
||||
void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
|
||||
assert(!Vendor.empty() && "Vendor cannot be empty.");
|
||||
|
||||
if (CurrentVendor == Vendor)
|
||||
return;
|
||||
|
||||
if (!CurrentVendor.empty())
|
||||
finishAttributeSection();
|
||||
|
||||
assert(Contents.empty() &&
|
||||
".ARM.attributes should be flushed before changing vendor");
|
||||
CurrentVendor = Vendor;
|
||||
|
||||
}
|
||||
void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
|
||||
setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
|
||||
}
|
||||
void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
|
||||
StringRef Value) {
|
||||
setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
|
||||
}
|
||||
void ARMTargetELFStreamer::emitFPU(unsigned Value) {
|
||||
FPU = Value;
|
||||
}
|
||||
void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
|
||||
switch (FPU) {
|
||||
case ARM::VFP:
|
||||
case ARM::VFPV2:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv2,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::VFPV3:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv3A,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::VFPV3_D16:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv3B,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::VFPV4:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv4A,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::VFPV4_D16:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv4B,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::FP_ARMV8:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPARMv8A,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::NEON:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv3A,
|
||||
/* OverwriteExisting= */ false);
|
||||
setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::AllowNeon,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::NEON_VFPV4:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPv4A,
|
||||
/* OverwriteExisting= */ false);
|
||||
setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::AllowNeon2,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
case ARM::NEON_FP_ARMV8:
|
||||
case ARM::CRYPTO_NEON_FP_ARMV8:
|
||||
setAttributeItem(ARMBuildAttrs::VFP_arch,
|
||||
ARMBuildAttrs::AllowFPARMv8A,
|
||||
/* OverwriteExisting= */ false);
|
||||
setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
|
||||
ARMBuildAttrs::AllowNeonARMv8,
|
||||
/* OverwriteExisting= */ false);
|
||||
break;
|
||||
|
||||
default:
|
||||
report_fatal_error("Unknown FPU: " + Twine(FPU));
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t ARMTargetELFStreamer::calculateContentSize() const {
|
||||
size_t Result = 0;
|
||||
for (size_t i = 0; i < Contents.size(); ++i) {
|
||||
AttributeItem item = Contents[i];
|
||||
switch (item.Type) {
|
||||
case AttributeItem::HiddenAttribute:
|
||||
break;
|
||||
case AttributeItem::NumericAttribute:
|
||||
Result += getULEBSize(item.Tag);
|
||||
Result += getULEBSize(item.IntValue);
|
||||
break;
|
||||
case AttributeItem::TextAttribute:
|
||||
Result += getULEBSize(item.Tag);
|
||||
Result += item.StringValue.size() + 1; // string + '\0'
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
void ARMTargetELFStreamer::finishAttributeSection() {
|
||||
// <format-version>
|
||||
// [ <section-length> "vendor-name"
|
||||
// [ <file-tag> <size> <attribute>*
|
||||
// | <section-tag> <size> <section-number>* 0 <attribute>*
|
||||
// | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
|
||||
// ]+
|
||||
// ]*
|
||||
|
||||
if (FPU != ARM::INVALID_FPU)
|
||||
emitFPUDefaultAttributes();
|
||||
|
||||
if (Contents.empty())
|
||||
return;
|
||||
|
||||
std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
|
||||
|
||||
ARMELFStreamer &Streamer = getStreamer();
|
||||
|
||||
// Switch to .ARM.attributes section
|
||||
if (AttributeSection) {
|
||||
Streamer.SwitchSection(AttributeSection);
|
||||
} else {
|
||||
AttributeSection =
|
||||
Streamer.getContext().getELFSection(".ARM.attributes",
|
||||
ELF::SHT_ARM_ATTRIBUTES,
|
||||
0,
|
||||
SectionKind::getMetadata());
|
||||
Streamer.SwitchSection(AttributeSection);
|
||||
|
||||
// Format version
|
||||
Streamer.EmitIntValue(0x41, 1);
|
||||
}
|
||||
|
||||
// Vendor size + Vendor name + '\0'
|
||||
const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
|
||||
|
||||
// Tag + Tag Size
|
||||
const size_t TagHeaderSize = 1 + 4;
|
||||
|
||||
const size_t ContentsSize = calculateContentSize();
|
||||
|
||||
Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
|
||||
Streamer.EmitBytes(CurrentVendor);
|
||||
Streamer.EmitIntValue(0, 1); // '\0'
|
||||
|
||||
Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
|
||||
Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
|
||||
|
||||
// Size should have been accounted for already, now
|
||||
// emit each field as its type (ULEB or String)
|
||||
for (size_t i = 0; i < Contents.size(); ++i) {
|
||||
AttributeItem item = Contents[i];
|
||||
Streamer.EmitULEB128IntValue(item.Tag);
|
||||
switch (item.Type) {
|
||||
default: llvm_unreachable("Invalid attribute type");
|
||||
case AttributeItem::NumericAttribute:
|
||||
Streamer.EmitULEB128IntValue(item.IntValue);
|
||||
break;
|
||||
case AttributeItem::TextAttribute:
|
||||
Streamer.EmitBytes(item.StringValue.upper());
|
||||
Streamer.EmitIntValue(0, 1); // '\0'
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Contents.clear();
|
||||
FPU = ARM::INVALID_FPU;
|
||||
}
|
||||
|
||||
void ARMELFStreamer::FinishImpl() {
|
||||
MCTargetStreamer &TS = getTargetStreamer();
|
||||
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
|
||||
ATS.finishAttributeSection();
|
||||
|
||||
MCELFStreamer::FinishImpl();
|
||||
}
|
||||
|
||||
inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
|
||||
unsigned Type,
|
||||
|
@ -1,3 +1,6 @@
|
||||
; This tests that MC/asm header conversion is smooth and that the
|
||||
; build attributes are correct
|
||||
|
||||
; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s --check-prefix=V6
|
||||
; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi | FileCheck %s --check-prefix=V6M
|
||||
; RUN: llc < %s -mtriple=armv6-linux-gnueabi -mcpu=arm1156t2f-s | FileCheck %s --check-prefix=ARM1156T2F-S
|
||||
@ -10,13 +13,12 @@
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mattr=-crypto | FileCheck %s --check-prefix=V8-FPARMv8-NEON
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi | FileCheck %s --check-prefix=V8-FPARMv8-NEON-CRYPTO
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 | FileCheck %s --check-prefix=CORTEX-A9
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 | FileCheck %s --check-prefix=CORTEX-A15
|
||||
; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi -mcpu=cortex-m0 | FileCheck %s --check-prefix=CORTEX-M0
|
||||
; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 | FileCheck %s --check-prefix=CORTEX-M4
|
||||
; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r5 | FileCheck %s --check-prefix=CORTEX-R5
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a53 | FileCheck %s --check-prefix=CORTEX-A53
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a57 | FileCheck %s --check-prefix=CORTEX-A57
|
||||
; This tests that MC/asm header conversion is smooth and that build attributes are correct
|
||||
;
|
||||
|
||||
; V6: .eabi_attribute 6, 6
|
||||
; V6: .eabi_attribute 8, 1
|
||||
@ -34,7 +36,6 @@
|
||||
; ARM1156T2F-S: .eabi_attribute 6, 8
|
||||
; ARM1156T2F-S: .eabi_attribute 8, 1
|
||||
; ARM1156T2F-S: .eabi_attribute 9, 2
|
||||
; ARM1156T2F-S: .eabi_attribute 10, 2
|
||||
; ARM1156T2F-S: .fpu vfpv2
|
||||
; ARM1156T2F-S: .eabi_attribute 20, 1
|
||||
; ARM1156T2F-S: .eabi_attribute 21, 1
|
||||
@ -66,7 +67,6 @@
|
||||
|
||||
; V8-FPARMv8: .syntax unified
|
||||
; V8-FPARMv8: .eabi_attribute 6, 14
|
||||
; V8-FPARMv8: .eabi_attribute 10, 7
|
||||
; V8-FPARMv8: .fpu fp-armv8
|
||||
|
||||
; V8-NEON: .syntax unified
|
||||
@ -77,13 +77,11 @@
|
||||
; V8-FPARMv8-NEON: .syntax unified
|
||||
; V8-FPARMv8-NEON: .eabi_attribute 6, 14
|
||||
; V8-FPARMv8-NEON: .fpu neon-fp-armv8
|
||||
; V8-FPARMv8-NEON: .eabi_attribute 10, 7
|
||||
; V8-FPARMv8-NEON: .eabi_attribute 12, 3
|
||||
|
||||
; V8-FPARMv8-NEON-CRYPTO: .syntax unified
|
||||
; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 6, 14
|
||||
; V8-FPARMv8-NEON-CRYPTO: .fpu crypto-neon-fp-armv8
|
||||
; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 10, 7
|
||||
; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 12, 3
|
||||
|
||||
; CORTEX-A9: .cpu cortex-a9
|
||||
@ -92,14 +90,25 @@
|
||||
; CORTEX-A9: .eabi_attribute 8, 1
|
||||
; CORTEX-A9: .eabi_attribute 9, 2
|
||||
; CORTEX-A9: .fpu neon
|
||||
; CORTEX-A9: .eabi_attribute 10, 3
|
||||
; CORTEX-A9: .eabi_attribute 12, 1
|
||||
; CORTEX-A9: .eabi_attribute 20, 1
|
||||
; CORTEX-A9: .eabi_attribute 21, 1
|
||||
; CORTEX-A9: .eabi_attribute 23, 3
|
||||
; CORTEX-A9: .eabi_attribute 24, 1
|
||||
; CORTEX-A9: .eabi_attribute 25, 1
|
||||
|
||||
; CORTEX-A15: .cpu cortex-a15
|
||||
; CORTEX-A15: .eabi_attribute 6, 10
|
||||
; CORTEX-A15: .eabi_attribute 7, 65
|
||||
; CORTEX-A15: .eabi_attribute 8, 1
|
||||
; CORTEX-A15: .eabi_attribute 9, 2
|
||||
; CORTEX-A15: .fpu neon-vfpv4
|
||||
; CORTEX-A15: .eabi_attribute 20, 1
|
||||
; CORTEX-A15: .eabi_attribute 21, 1
|
||||
; CORTEX-A15: .eabi_attribute 23, 3
|
||||
; CORTEX-A15: .eabi_attribute 24, 1
|
||||
; CORTEX-A15: .eabi_attribute 25, 1
|
||||
; CORTEX-A15: .eabi_attribute 44, 2
|
||||
|
||||
; CORTEX-M0: .cpu cortex-m0
|
||||
; CORTEX-M0: .eabi_attribute 6, 12
|
||||
; CORTEX-M0: .eabi_attribute 7, 77
|
||||
@ -113,8 +122,7 @@
|
||||
; CORTEX-M4: .eabi_attribute 7, 77
|
||||
; CORTEX-M4: .eabi_attribute 8, 0
|
||||
; CORTEX-M4: .eabi_attribute 9, 2
|
||||
; CORTEX-M4: .eabi_attribute 10, 6
|
||||
; CORTEX-M4: .fpu vfpv4
|
||||
; CORTEX-M4: .fpu vfpv4-d16
|
||||
; CORTEX-M4: .eabi_attribute 20, 1
|
||||
; CORTEX-M4: .eabi_attribute 21, 1
|
||||
; CORTEX-M4: .eabi_attribute 23, 3
|
||||
@ -127,8 +135,7 @@
|
||||
; CORTEX-R5: .eabi_attribute 7, 82
|
||||
; CORTEX-R5: .eabi_attribute 8, 1
|
||||
; CORTEX-R5: .eabi_attribute 9, 2
|
||||
; CORTEX-R5: .eabi_attribute 10, 4
|
||||
; CORTEX-R5: .fpu vfpv3
|
||||
; CORTEX-R5: .fpu vfpv3-d16
|
||||
; CORTEX-R5: .eabi_attribute 20, 1
|
||||
; CORTEX-R5: .eabi_attribute 21, 1
|
||||
; CORTEX-R5: .eabi_attribute 23, 3
|
||||
@ -142,7 +149,6 @@
|
||||
; CORTEX-A53: .eabi_attribute 8, 1
|
||||
; CORTEX-A53: .eabi_attribute 9, 2
|
||||
; CORTEX-A53: .fpu crypto-neon-fp-armv8
|
||||
; CORTEX-A53: .eabi_attribute 10, 7
|
||||
; CORTEX-A53: .eabi_attribute 12, 3
|
||||
; CORTEX-A53: .eabi_attribute 24, 1
|
||||
; CORTEX-A53: .eabi_attribute 25, 1
|
||||
@ -154,7 +160,6 @@
|
||||
; CORTEX-A57: .eabi_attribute 8, 1
|
||||
; CORTEX-A57: .eabi_attribute 9, 2
|
||||
; CORTEX-A57: .fpu crypto-neon-fp-armv8
|
||||
; CORTEX-A57: .eabi_attribute 10, 7
|
||||
; CORTEX-A57: .eabi_attribute 12, 3
|
||||
; CORTEX-A57: .eabi_attribute 24, 1
|
||||
; CORTEX-A57: .eabi_attribute 25, 1
|
||||
|
@ -1,13 +1,36 @@
|
||||
; RUN: llc %s -mtriple=arm-linux-gnueabi -filetype=obj -o - | \
|
||||
; RUN: llvm-readobj -s -sd | FileCheck -check-prefix=BASIC %s
|
||||
; RUN: llc %s -mtriple=armv7-linux-gnueabi -march=arm -mcpu=cortex-a8 \
|
||||
; RUN: -mattr=-neon,-vfp3,+vfp2 \
|
||||
; RUN: -arm-reserve-r9 -filetype=obj -o - | \
|
||||
; RUN: llvm-readobj -s -sd | FileCheck -check-prefix=CORTEXA8 %s
|
||||
; This tests that the expected ARM attributes are emitted.
|
||||
|
||||
; RUN: llc < %s -mtriple=arm-linux-gnueabi -filetype=obj -o - \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=BASIC
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -march=arm -mcpu=cortex-a8 \
|
||||
; RUN: -mattr=-neon,-vfp3,+vfp2 -arm-reserve-r9 -filetype=obj -o - \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A8
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=V7
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8
|
||||
; RUN: llc < %s -mtriple=thumbv8-linux-gnueabi -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=Vt8
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
|
||||
; RUN: -mattr=-neon,-crypto -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-FPARMv8
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
|
||||
; RUN: -mattr=-fp-armv8,-crypto -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-NEON
|
||||
; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
|
||||
; RUN: -mattr=-crypto -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-FPARMv8-NEON
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A9
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A15
|
||||
; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi -mcpu=cortex-m0 -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-M0
|
||||
; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-M4
|
||||
; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r5 -filetype=obj \
|
||||
; RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-R5
|
||||
|
||||
; This tests that the extpected ARM attributes are emitted.
|
||||
;
|
||||
; BASIC: Section {
|
||||
; BASIC: Name: .ARM.attributes
|
||||
; BASIC-NEXT: Type: SHT_ARM_ATTRIBUTES
|
||||
@ -25,22 +48,215 @@
|
||||
; BASIC-NEXT: 0010: 06010801 14011501 17031801 1901
|
||||
; BASIC-NEXT: )
|
||||
|
||||
; CORTEXA8: Name: .ARM.attributes
|
||||
; CORTEXA8-NEXT: Type: SHT_ARM_ATTRIBUTES
|
||||
; CORTEXA8-NEXT: Flags [ (0x0)
|
||||
; CORTEXA8-NEXT: ]
|
||||
; CORTEXA8-NEXT: Address: 0x0
|
||||
; CORTEXA8-NEXT: Offset: 0x3C
|
||||
; CORTEXA8-NEXT: Size: 47
|
||||
; CORTEXA8-NEXT: Link: 0
|
||||
; CORTEXA8-NEXT: Info: 0
|
||||
; CORTEXA8-NEXT: AddressAlignment: 1
|
||||
; CORTEXA8-NEXT: EntrySize: 0
|
||||
; CORTEXA8-NEXT: SectionData (
|
||||
; CORTEXA8-NEXT: 0000: 412E0000 00616561 62690001 24000000
|
||||
; CORTEXA8-NEXT: 0010: 05434F52 5445582D 41380006 0A074108
|
||||
; CORTEXA8-NEXT: 0020: 0109020A 02140115 01170318 011901
|
||||
; CORTEXA8-NEXT: )
|
||||
; CORTEX-A8: Name: .ARM.attributes
|
||||
; CORTEX-A8-NEXT: Type: SHT_ARM_ATTRIBUTES
|
||||
; CORTEX-A8-NEXT: Flags [ (0x0)
|
||||
; CORTEX-A8-NEXT: ]
|
||||
; CORTEX-A8-NEXT: Address: 0x0
|
||||
; CORTEX-A8-NEXT: Offset: 0x3C
|
||||
; CORTEX-A8-NEXT: Size: 47
|
||||
; CORTEX-A8-NEXT: Link: 0
|
||||
; CORTEX-A8-NEXT: Info: 0
|
||||
; CORTEX-A8-NEXT: AddressAlignment: 1
|
||||
; CORTEX-A8-NEXT: EntrySize: 0
|
||||
; CORTEX-A8-NEXT: SectionData (
|
||||
; CORTEX-A8-NEXT: 0000: 412E0000 00616561 62690001 24000000
|
||||
; CORTEX-A8-NEXT: 0010: 05434F52 5445582D 41380006 0A074108
|
||||
; CORTEX-A8-NEXT: 0020: 0109020A 02140115 01170318 011901
|
||||
; CORTEX-A8-NEXT: )
|
||||
|
||||
; V7: Name: .ARM.attributes
|
||||
; V7-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; V7-NEXT: Flags [ (0x0)
|
||||
; V7-NEXT: ]
|
||||
; V7-NEXT: Address: 0x0
|
||||
; V7-NEXT: Offset: 0x3C
|
||||
; V7-NEXT: Size: 36
|
||||
; V7-NEXT: Link: 0
|
||||
; V7-NEXT: Info: 0
|
||||
; V7-NEXT: AddressAlignment: 1
|
||||
; V7-NEXT: EntrySize: 0
|
||||
; V7-NEXT: SectionData (
|
||||
; V7-NEXT: 0000: 41230000 00616561 62690001 19000000
|
||||
; V7-NEXT: 0010: 060A0801 09020A03 0C011401 15011703
|
||||
; V7-NEXT: 0020: 18011901
|
||||
; V7-NEXT: )
|
||||
|
||||
; V8: Name: .ARM.attributes
|
||||
; V8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; V8-NEXT: Flags [ (0x0)
|
||||
; V8-NEXT: ]
|
||||
; V8-NEXT: Address: 0x0
|
||||
; V8-NEXT: Offset: 0x3C
|
||||
; V8-NEXT: Size: 38
|
||||
; V8-NEXT: Link: 0
|
||||
; V8-NEXT: Info: 0
|
||||
; V8-NEXT: AddressAlignment: 1
|
||||
; V8-NEXT: EntrySize: 0
|
||||
; V8-NEXT: SectionData (
|
||||
; V8-NEXT: 0000: 41250000 00616561 62690001 1B000000
|
||||
; V8-NEXT: 0010: 060E0801 09020A07 0C031401 15011703
|
||||
; V8-NEXT: 0020: 18011901 2C02
|
||||
; V8-NEXT: )
|
||||
|
||||
; Vt8: Name: .ARM.attributes
|
||||
; Vt8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; Vt8-NEXT: Flags [ (0x0)
|
||||
; Vt8-NEXT: ]
|
||||
; Vt8-NEXT: Address: 0x0
|
||||
; Vt8-NEXT: Offset: 0x38
|
||||
; Vt8-NEXT: Size: 38
|
||||
; Vt8-NEXT: Link: 0
|
||||
; Vt8-NEXT: Info: 0
|
||||
; Vt8-NEXT: AddressAlignment: 1
|
||||
; Vt8-NEXT: EntrySize: 0
|
||||
; Vt8-NEXT: SectionData (
|
||||
; Vt8-NEXT: 0000: 41250000 00616561 62690001 1B000000
|
||||
; Vt8-NEXT: 0010: 060E0801 09020A07 0C031401 15011703
|
||||
; Vt8-NEXT: 0020: 18011901 2C02
|
||||
; Vt8-NEXT: )
|
||||
|
||||
|
||||
; V8-FPARMv8: Name: .ARM.attributes
|
||||
; V8-FPARMv8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; V8-FPARMv8-NEXT: Flags [ (0x0)
|
||||
; V8-FPARMv8-NEXT: ]
|
||||
; V8-FPARMv8-NEXT: Address: 0x0
|
||||
; V8-FPARMv8-NEXT: Offset: 0x3C
|
||||
; V8-FPARMv8-NEXT: Size: 36
|
||||
; V8-FPARMv8-NEXT: Link: 0
|
||||
; V8-FPARMv8-NEXT: Info: 0
|
||||
; V8-FPARMv8-NEXT: AddressAlignment: 1
|
||||
; V8-FPARMv8-NEXT: EntrySize: 0
|
||||
; V8-FPARMv8-NEXT: SectionData (
|
||||
; V8-FPARMv8-NEXT: 0000: 41230000 00616561 62690001 19000000
|
||||
; V8-FPARMv8-NEXT: 0010: 060E0801 09020A07 14011501 17031801
|
||||
; V8-FPARMv8-NEXT: 0020: 19012C02
|
||||
; V8-FPARMv8-NEXT: )
|
||||
|
||||
|
||||
; V8-NEON: Name: .ARM.attributes
|
||||
; V8-NEON-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; V8-NEON-NEXT: Flags [ (0x0)
|
||||
; V8-NEON-NEXT: ]
|
||||
; V8-NEON-NEXT: Address: 0x0
|
||||
; V8-NEON-NEXT: Offset: 0x3C
|
||||
; V8-NEON-NEXT: Size: 38
|
||||
; V8-NEON-NEXT: Link: 0
|
||||
; V8-NEON-NEXT: Info: 0
|
||||
; V8-NEON-NEXT: AddressAlignment: 1
|
||||
; V8-NEON-NEXT: EntrySize: 0
|
||||
; V8-NEON-NEXT: SectionData (
|
||||
; V8-NEON-NEXT: 0000: 41250000 00616561 62690001 1B000000
|
||||
; V8-NEON-NEXT: 0010: 060E0801 09020A05 0C031401 15011703
|
||||
; V8-NEON-NEXT: 0020: 18011901 2C02
|
||||
; V8-NEON-NEXT: )
|
||||
|
||||
; V8-FPARMv8-NEON: Name: .ARM.attributes
|
||||
; V8-FPARMv8-NEON-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; V8-FPARMv8-NEON-NEXT: Flags [ (0x0)
|
||||
; V8-FPARMv8-NEON-NEXT: ]
|
||||
; V8-FPARMv8-NEON-NEXT: Address: 0x0
|
||||
; V8-FPARMv8-NEON-NEXT: Offset: 0x3C
|
||||
; V8-FPARMv8-NEON-NEXT: Size: 38
|
||||
; V8-FPARMv8-NEON-NEXT: Link: 0
|
||||
; V8-FPARMv8-NEON-NEXT: Info: 0
|
||||
; V8-FPARMv8-NEON-NEXT: AddressAlignment: 1
|
||||
; V8-FPARMv8-NEON-NEXT: EntrySize: 0
|
||||
; V8-FPARMv8-NEON-NEXT: SectionData (
|
||||
; V8-FPARMv8-NEON-NEXT: 0000: 41250000 00616561 62690001 1B000000
|
||||
; V8-FPARMv8-NEON-NEXT: 0010: 060E0801 09020A07 0C031401 15011703
|
||||
; V8-FPARMv8-NEON-NEXT: 0020: 18011901 2C02
|
||||
; V8-FPARMv8-NEON-NEXT: )
|
||||
|
||||
; CORTEX-A9: Name: .ARM.attributes
|
||||
; CORTEX-A9-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; CORTEX-A9-NEXT: Flags [ (0x0)
|
||||
; CORTEX-A9-NEXT: ]
|
||||
; CORTEX-A9-NEXT: Address: 0x0
|
||||
; CORTEX-A9-NEXT: Offset: 0x3C
|
||||
; CORTEX-A9-NEXT: Size: 49
|
||||
; CORTEX-A9-NEXT: Link: 0
|
||||
; CORTEX-A9-NEXT: Info: 0
|
||||
; CORTEX-A9-NEXT: AddressAlignment: 1
|
||||
; CORTEX-A9-NEXT: EntrySize: 0
|
||||
; CORTEX-A9-NEXT: SectionData (
|
||||
; CORTEX-A9-NEXT: 0000: 41300000 00616561 62690001 26000000
|
||||
; CORTEX-A9-NEXT: 0010: 05434F52 5445582D 41390006 0A074108
|
||||
; CORTEX-A9-NEXT: 0020: 0109020A 030C0114 01150117 03180119
|
||||
; CORTEX-A9-NEXT: 0030: 01
|
||||
; CORTEX-A9-NEXT: )
|
||||
|
||||
; CORTEX-A15: Name: .ARM.attributes
|
||||
; CORTEX-A15-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; CORTEX-A15-NEXT: Flags [ (0x0)
|
||||
; CORTEX-A15-NEXT: ]
|
||||
; CORTEX-A15-NEXT: Address: 0x0
|
||||
; CORTEX-A15-NEXT: Offset: 0x3C
|
||||
; CORTEX-A15-NEXT: Size: 52
|
||||
; CORTEX-A15-NEXT: Link: 0
|
||||
; CORTEX-A15-NEXT: Info: 0
|
||||
; CORTEX-A15-NEXT: AddressAlignment: 1
|
||||
; CORTEX-A15-NEXT: EntrySize: 0
|
||||
; CORTEX-A15-NEXT: SectionData (
|
||||
; CORTEX-A15-NEXT: 0000: 41330000 00616561 62690001 29000000
|
||||
; CORTEX-A15-NEXT: 0010: 05434F52 5445582D 41313500 060A0741
|
||||
; CORTEX-A15-NEXT: 0020: 08010902 0A050C02 14011501 17031801
|
||||
; CORTEX-A15-NEXT: 0030: 19012C02
|
||||
; CORTEX-A15-NEXT: )
|
||||
|
||||
; CORTEX-M0: Name: .ARM.attributes
|
||||
; CORTEX-M0-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; CORTEX-M0-NEXT: Flags [ (0x0)
|
||||
; CORTEX-M0-NEXT: ]
|
||||
; CORTEX-M0-NEXT: Address: 0x0
|
||||
; CORTEX-M0-NEXT: Offset: 0x38
|
||||
; CORTEX-M0-NEXT: Size: 45
|
||||
; CORTEX-M0-NEXT: Link: 0
|
||||
; CORTEX-M0-NEXT: Info: 0
|
||||
; CORTEX-M0-NEXT: AddressAlignment: 1
|
||||
; CORTEX-M0-NEXT: EntrySize: 0
|
||||
; CORTEX-M0-NEXT: SectionData (
|
||||
; CORTEX-M0-NEXT: 0000: 412C0000 00616561 62690001 22000000
|
||||
; CORTEX-M0-NEXT: 0010: 05434F52 5445582D 4D300006 0C074D08
|
||||
; CORTEX-M0-NEXT: 0020: 00090114 01150117 03180119 01
|
||||
; CORTEX-M0-NEXT: )
|
||||
|
||||
; CORTEX-M4: Name: .ARM.attributes
|
||||
; CORTEX-M4-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; CORTEX-M4-NEXT: Flags [ (0x0)
|
||||
; CORTEX-M4-NEXT: ]
|
||||
; CORTEX-M4-NEXT: Address: 0x0
|
||||
; CORTEX-M4-NEXT: Offset: 0x38
|
||||
; CORTEX-M4-NEXT: Size: 49
|
||||
; CORTEX-M4-NEXT: Link: 0
|
||||
; CORTEX-M4-NEXT: Info: 0
|
||||
; CORTEX-M4-NEXT: AddressAlignment: 1
|
||||
; CORTEX-M4-NEXT: EntrySize: 0
|
||||
; CORTEX-M4-NEXT: SectionData (
|
||||
; CORTEX-M4-NEXT: 0000: 41300000 00616561 62690001 26000000
|
||||
; CORTEX-M4-NEXT: 0010: 05434F52 5445582D 4D340006 0D074D08
|
||||
; CORTEX-M4-NEXT: 0020: 0009020A 06140115 01170318 0119012C
|
||||
; CORTEX-M4-NEXT: 0030: 00
|
||||
; CORTEX-M4-NEXT: )
|
||||
|
||||
; CORTEX-R5: Name: .ARM.attributes
|
||||
; CORTEX-R5-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
; CORTEX-R5-NEXT: Flags [ (0x0)
|
||||
; CORTEX-R5-NEXT: ]
|
||||
; CORTEX-R5-NEXT: Address: 0x0
|
||||
; CORTEX-R5-NEXT: Offset: 0x3C
|
||||
; CORTEX-R5-NEXT: Size: 49
|
||||
; CORTEX-R5-NEXT: Link: 0
|
||||
; CORTEX-R5-NEXT: Info: 0
|
||||
; CORTEX-R5-NEXT: AddressAlignment: 1
|
||||
; CORTEX-R5-NEXT: EntrySize: 0
|
||||
; CORTEX-R5-NEXT: SectionData (
|
||||
; CORTEX-R5-NEXT: 0000: 41300000 00616561 62690001 26000000
|
||||
; CORTEX-R5-NEXT: 0010: 05434F52 5445582D 52350006 0A075208
|
||||
; CORTEX-R5-NEXT: 0020: 0109020A 04140115 01170318 0119012C
|
||||
; CORTEX-R5-NEXT: 0030: 02
|
||||
; CORTEX-R5-NEXT: )
|
||||
|
||||
define i32 @f(i64 %z) {
|
||||
ret i32 0
|
||||
|
26
test/MC/ARM/directive-cpu.s
Normal file
26
test/MC/ARM/directive-cpu.s
Normal file
@ -0,0 +1,26 @@
|
||||
@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o - \
|
||||
@ RUN: | llvm-readobj -s -sd | FileCheck %s
|
||||
|
||||
@ CHECK: Name: .ARM.attribute
|
||||
@ CHECK: SectionData (
|
||||
|
||||
@ <format-version>
|
||||
@ CHECK: 41
|
||||
|
||||
@ <section-length>
|
||||
@ CHECK: 1A0000 00
|
||||
|
||||
@ <vendor-name> "aeabi\0"
|
||||
@ CHECK: 616561 626900
|
||||
|
||||
@ <file-tag>
|
||||
@ CHECK: 01
|
||||
|
||||
@ <size>
|
||||
@ CHECK: 10000000
|
||||
|
||||
.cpu cortex-a8
|
||||
@ CHECK: 05
|
||||
@ CHECK: 434F52 5445582D 413800
|
||||
|
||||
@ CHECK: )
|
56
test/MC/ARM/directive-eabi_attribute.s
Normal file
56
test/MC/ARM/directive-eabi_attribute.s
Normal file
@ -0,0 +1,56 @@
|
||||
@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o - \
|
||||
@ RUN: | llvm-readobj -s -sd | FileCheck %s
|
||||
|
||||
@ CHECK: Name: .ARM.attribute
|
||||
@ CHECK: SectionData (
|
||||
|
||||
@ <format-version>
|
||||
@ CHECK: 41
|
||||
|
||||
@ <section-length>
|
||||
@ CHECK: 250000 00
|
||||
|
||||
@ <vendor-name> "aeabi\0"
|
||||
@ CHECK: 616561 626900
|
||||
|
||||
@ <file-tag>
|
||||
@ CHECK: 01
|
||||
|
||||
@ <size>
|
||||
@ CHECK: 1B000000
|
||||
|
||||
@ <attribute>*
|
||||
|
||||
.eabi_attribute 6, 10
|
||||
@ CHECK: 060A
|
||||
|
||||
.eabi_attribute 7, 65
|
||||
@ CHECK: 0741
|
||||
|
||||
.eabi_attribute 8, 1
|
||||
@ CHECK: 0801
|
||||
|
||||
.eabi_attribute 9, 2
|
||||
@ CHECK: 0902
|
||||
|
||||
.eabi_attribute 10, 3
|
||||
@ CHECK: 0A03
|
||||
|
||||
.eabi_attribute 12, 1
|
||||
@ CHECK: 0C01
|
||||
|
||||
.eabi_attribute 20, 1
|
||||
@ CHECK: 1401
|
||||
|
||||
.eabi_attribute 21, 1
|
||||
@ CHECK: 1501
|
||||
|
||||
.eabi_attribute 23, 3
|
||||
@ CHECK: 1703
|
||||
|
||||
.eabi_attribute 24, 1
|
||||
@ CHECK: 1801
|
||||
|
||||
.eabi_attribute 25, 1
|
||||
@ CHECK: 1901
|
||||
@ CHECK: )
|
26
test/MC/ARM/directive-fpu-multiple.s
Normal file
26
test/MC/ARM/directive-fpu-multiple.s
Normal file
@ -0,0 +1,26 @@
|
||||
@ Check multiple .fpu directives.
|
||||
|
||||
@ The later .fpu directive should overwrite the earlier one.
|
||||
@ See also: directive-fpu-multiple2.s.
|
||||
|
||||
@ RUN: llvm-mc < %s -triple arm-unknown-linux-gnueabi -filetype=obj \
|
||||
@ RUN: | llvm-readobj -s -sd | FileCheck %s
|
||||
|
||||
.fpu neon
|
||||
.fpu vfpv4
|
||||
|
||||
@ CHECK: Name: .ARM.attributes
|
||||
@ CHECK-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
|
||||
@ CHECK-NEXT: Flags [ (0x0)
|
||||
@ CHECK-NEXT: ]
|
||||
@ CHECK-NEXT: Address: 0x0
|
||||
@ CHECK-NEXT: Offset: 0x34
|
||||
@ CHECK-NEXT: Size: 18
|
||||
@ CHECK-NEXT: Link: 0
|
||||
@ CHECK-NEXT: Info: 0
|
||||
@ CHECK-NEXT: AddressAlignment: 1
|
||||
@ CHECK-NEXT: EntrySize: 0
|
||||
@ CHECK-NEXT: SectionData (
|
||||
@ CHECK-NEXT: 0000: 41110000 00616561 62690001 07000000
|
||||
@ CHECK-NEXT: 0010: 0A05
|
||||
@ CHECK-NEXT: )
|
26
test/MC/ARM/directive-fpu.s
Normal file
26
test/MC/ARM/directive-fpu.s
Normal file
@ -0,0 +1,26 @@
|
||||
@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o - \
|
||||
@ RUN: | llvm-readobj -s -sd | FileCheck %s
|
||||
|
||||
@ CHECK: Name: .ARM.attribute
|
||||
@ CHECK: SectionData (
|
||||
|
||||
@ <format-version>
|
||||
@ CHECK: 41
|
||||
|
||||
@ <section-length>
|
||||
@ CHECK: 130000 00
|
||||
|
||||
@ <vendor-name> "aeabi\0"
|
||||
@ CHECK: 616561 626900
|
||||
|
||||
@ <file-tag>
|
||||
@ CHECK: 01
|
||||
|
||||
@ <size>
|
||||
@ CHECK: 09000000
|
||||
|
||||
.fpu neon
|
||||
@ CHECK: 0A03
|
||||
@ CHECK: 0C01
|
||||
|
||||
@ CHECK: )
|
Loading…
Reference in New Issue
Block a user