mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-22 20:20:03 +00:00
ARM IAS: support .object_arch
The .object_arch directive indicates an alternative architecture to be specified in the object file. The directive does *not* effect the enabled feature bits for the object file generation. This is particularly useful when the code performs runtime detection and would like to indicate a lower architecture as the requirements than the actual instructions used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200451 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
459c949777
commit
09f38a0ef1
@ -107,6 +107,7 @@ public:
|
|||||||
StringRef StringValue = "") = 0;
|
StringRef StringValue = "") = 0;
|
||||||
virtual void emitFPU(unsigned FPU) = 0;
|
virtual void emitFPU(unsigned FPU) = 0;
|
||||||
virtual void emitArch(unsigned Arch) = 0;
|
virtual void emitArch(unsigned Arch) = 0;
|
||||||
|
virtual void emitObjectArch(unsigned Arch) = 0;
|
||||||
virtual void finishAttributeSection() = 0;
|
virtual void finishAttributeSection() = 0;
|
||||||
virtual void emitInst(uint32_t Inst, char Suffix = '\0') = 0;
|
virtual void emitInst(uint32_t Inst, char Suffix = '\0') = 0;
|
||||||
|
|
||||||
|
@ -298,6 +298,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
|||||||
bool parseDirectiveUnwindRaw(SMLoc L);
|
bool parseDirectiveUnwindRaw(SMLoc L);
|
||||||
bool parseDirectiveTLSDescSeq(SMLoc L);
|
bool parseDirectiveTLSDescSeq(SMLoc L);
|
||||||
bool parseDirectiveMovSP(SMLoc L);
|
bool parseDirectiveMovSP(SMLoc L);
|
||||||
|
bool parseDirectiveObjectArch(SMLoc L);
|
||||||
|
|
||||||
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
|
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
|
||||||
bool &CarrySetting, unsigned &ProcessorIMod,
|
bool &CarrySetting, unsigned &ProcessorIMod,
|
||||||
@ -8090,6 +8091,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
|
|||||||
return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
|
return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
|
||||||
else if (IDVal == ".movsp")
|
else if (IDVal == ".movsp")
|
||||||
return parseDirectiveMovSP(DirectiveID.getLoc());
|
return parseDirectiveMovSP(DirectiveID.getLoc());
|
||||||
|
else if (IDVal == ".object_arch")
|
||||||
|
return parseDirectiveObjectArch(DirectiveID.getLoc());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9094,6 +9097,45 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// parseDirectiveObjectArch
|
||||||
|
/// ::= .object_arch name
|
||||||
|
bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
|
||||||
|
if (getLexer().isNot(AsmToken::Identifier)) {
|
||||||
|
Error(getLexer().getLoc(), "unexpected token");
|
||||||
|
Parser.eatToEndOfStatement();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef Arch = Parser.getTok().getString();
|
||||||
|
SMLoc ArchLoc = Parser.getTok().getLoc();
|
||||||
|
getLexer().Lex();
|
||||||
|
|
||||||
|
unsigned ID = StringSwitch<unsigned>(Arch)
|
||||||
|
#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
|
||||||
|
.Case(NAME, ARM::ID)
|
||||||
|
#define ARM_ARCH_ALIAS(NAME, ID) \
|
||||||
|
.Case(NAME, ARM::ID)
|
||||||
|
#include "MCTargetDesc/ARMArchName.def"
|
||||||
|
#undef ARM_ARCH_NAME
|
||||||
|
#undef ARM_ARCH_ALIAS
|
||||||
|
.Default(ARM::INVALID_ARCH);
|
||||||
|
|
||||||
|
if (ID == ARM::INVALID_ARCH) {
|
||||||
|
Error(ArchLoc, "unknown architecture '" + Arch + "'");
|
||||||
|
Parser.eatToEndOfStatement();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTargetStreamer().emitObjectArch(ID);
|
||||||
|
|
||||||
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||||
|
Error(getLexer().getLoc(), "unexpected token");
|
||||||
|
Parser.eatToEndOfStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Force static initialization.
|
/// Force static initialization.
|
||||||
extern "C" void LLVMInitializeARMAsmParser() {
|
extern "C" void LLVMInitializeARMAsmParser() {
|
||||||
RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
|
RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
|
||||||
|
@ -136,6 +136,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
|
|||||||
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
|
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
|
||||||
StringRef StrinValue);
|
StringRef StrinValue);
|
||||||
virtual void emitArch(unsigned Arch);
|
virtual void emitArch(unsigned Arch);
|
||||||
|
virtual void emitObjectArch(unsigned Arch);
|
||||||
virtual void emitFPU(unsigned FPU);
|
virtual void emitFPU(unsigned FPU);
|
||||||
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
|
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
|
||||||
virtual void finishAttributeSection();
|
virtual void finishAttributeSection();
|
||||||
@ -249,6 +250,9 @@ void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
|
|||||||
void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
|
void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
|
||||||
OS << "\t.arch\t" << GetArchName(Arch) << "\n";
|
OS << "\t.arch\t" << GetArchName(Arch) << "\n";
|
||||||
}
|
}
|
||||||
|
void ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) {
|
||||||
|
OS << "\t.object_arch\t" << GetArchName(Arch) << '\n';
|
||||||
|
}
|
||||||
void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
|
void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
|
||||||
OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
|
OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
|
||||||
}
|
}
|
||||||
@ -300,6 +304,7 @@ private:
|
|||||||
StringRef CurrentVendor;
|
StringRef CurrentVendor;
|
||||||
unsigned FPU;
|
unsigned FPU;
|
||||||
unsigned Arch;
|
unsigned Arch;
|
||||||
|
unsigned EmittedArch;
|
||||||
SmallVector<AttributeItem, 64> Contents;
|
SmallVector<AttributeItem, 64> Contents;
|
||||||
|
|
||||||
const MCSection *AttributeSection;
|
const MCSection *AttributeSection;
|
||||||
@ -411,6 +416,7 @@ private:
|
|||||||
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
|
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
|
||||||
StringRef StringValue);
|
StringRef StringValue);
|
||||||
virtual void emitArch(unsigned Arch);
|
virtual void emitArch(unsigned Arch);
|
||||||
|
virtual void emitObjectArch(unsigned Arch);
|
||||||
virtual void emitFPU(unsigned FPU);
|
virtual void emitFPU(unsigned FPU);
|
||||||
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
|
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
|
||||||
virtual void finishAttributeSection();
|
virtual void finishAttributeSection();
|
||||||
@ -422,7 +428,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
ARMTargetELFStreamer(MCStreamer &S)
|
ARMTargetELFStreamer(MCStreamer &S)
|
||||||
: ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
|
: ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
|
||||||
Arch(ARM::INVALID_ARCH), AttributeSection(0) {}
|
Arch(ARM::INVALID_ARCH), EmittedArch(ARM::INVALID_ARCH),
|
||||||
|
AttributeSection(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
|
/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
|
||||||
@ -714,10 +721,17 @@ void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
|
|||||||
void ARMTargetELFStreamer::emitArch(unsigned Value) {
|
void ARMTargetELFStreamer::emitArch(unsigned Value) {
|
||||||
Arch = Value;
|
Arch = Value;
|
||||||
}
|
}
|
||||||
|
void ARMTargetELFStreamer::emitObjectArch(unsigned Value) {
|
||||||
|
EmittedArch = Value;
|
||||||
|
}
|
||||||
void ARMTargetELFStreamer::emitArchDefaultAttributes() {
|
void ARMTargetELFStreamer::emitArchDefaultAttributes() {
|
||||||
using namespace ARMBuildAttrs;
|
using namespace ARMBuildAttrs;
|
||||||
|
|
||||||
setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
|
setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
|
||||||
|
if (EmittedArch == ARM::INVALID_ARCH)
|
||||||
setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
|
setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
|
||||||
|
else
|
||||||
|
setAttributeItem(CPU_arch, GetArchDefaultCPUArch(EmittedArch), false);
|
||||||
|
|
||||||
switch (Arch) {
|
switch (Arch) {
|
||||||
case ARM::ARMV2:
|
case ARM::ARMV2:
|
||||||
|
22
test/MC/ARM/directive-object_arch-2.s
Normal file
22
test/MC/ARM/directive-object_arch-2.s
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s \
|
||||||
|
@ RUN: | llvm-readobj -arm-attributes | FileCheck %s
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.object_arch armv4
|
||||||
|
.arch armv7
|
||||||
|
|
||||||
|
@ CHECK: FileAttributes {
|
||||||
|
@ CHECK: Attribute {
|
||||||
|
@ CHECK: Tag: 5
|
||||||
|
@ CHECK: TagName: CPU_name
|
||||||
|
@ CHECK: Value: 7
|
||||||
|
@ CHECK: }
|
||||||
|
@ CHECK: Attribute {
|
||||||
|
@ CHECK: Tag: 6
|
||||||
|
@ CHEKC: Value: 1
|
||||||
|
@ CHECK: TagName: CPU_arch
|
||||||
|
@ CHECK: Description: ARM v4
|
||||||
|
@ CHECK: }
|
||||||
|
@ CHECK: }
|
||||||
|
|
11
test/MC/ARM/directive-object_arch-3.s
Normal file
11
test/MC/ARM/directive-object_arch-3.s
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@ RUN: llvm-mc -triple armv7-eabi -filetype asm -o - %s | FileCheck %s
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.arch armv7
|
||||||
|
.object_arch armv4
|
||||||
|
|
||||||
|
@ CHECK: .text
|
||||||
|
@ CHECK: .arch armv7
|
||||||
|
@ CHECK: .object_arch armv4
|
||||||
|
|
23
test/MC/ARM/directive-object_arch-diagnostics.s
Normal file
23
test/MC/ARM/directive-object_arch-diagnostics.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null %s 2>&1 \
|
||||||
|
@ RUN: | FileCheck %s
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.object_arch i686
|
||||||
|
|
||||||
|
@ CHECK: error: unknown architecture 'i686'
|
||||||
|
@ CHECK: .object_arch i686
|
||||||
|
@ CHECK: ^
|
||||||
|
|
||||||
|
.object_arch armv4!
|
||||||
|
|
||||||
|
@ CHECK: error: unexpected token
|
||||||
|
@ CHECK: .object_arch armv4!
|
||||||
|
@ CHECK: ^
|
||||||
|
|
||||||
|
.object_arch, invalid
|
||||||
|
|
||||||
|
@ CHECK: error: unexpected token
|
||||||
|
@ CHECK: .object_arch, invalid
|
||||||
|
@ CHECK: ^
|
||||||
|
|
22
test/MC/ARM/directive-object_arch.s
Normal file
22
test/MC/ARM/directive-object_arch.s
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s \
|
||||||
|
@ RUN: | llvm-readobj -arm-attributes | FileCheck %s
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.arch armv7
|
||||||
|
.object_arch armv4
|
||||||
|
|
||||||
|
@ CHECK: FileAttributes {
|
||||||
|
@ CHECK: Attribute {
|
||||||
|
@ CHECK: Tag: 5
|
||||||
|
@ CHECK: TagName: CPU_name
|
||||||
|
@ CHECK: Value: 7
|
||||||
|
@ CHECK: }
|
||||||
|
@ CHECK: Attribute {
|
||||||
|
@ CHECK: Tag: 6
|
||||||
|
@ CHEKC: Value: 1
|
||||||
|
@ CHECK: TagName: CPU_arch
|
||||||
|
@ CHECK: Description: ARM v4
|
||||||
|
@ CHECK: }
|
||||||
|
@ CHECK: }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user