summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCStreamer.h1
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp42
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp20
-rw-r--r--test/MC/ARM/directive-object_arch-2.s22
-rw-r--r--test/MC/ARM/directive-object_arch-3.s11
-rw-r--r--test/MC/ARM/directive-object_arch-diagnostics.s23
-rw-r--r--test/MC/ARM/directive-object_arch.s22
7 files changed, 138 insertions, 3 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index f272572bb6..4950197840 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -107,6 +107,7 @@ public:
StringRef StringValue = "") = 0;
virtual void emitFPU(unsigned FPU) = 0;
virtual void emitArch(unsigned Arch) = 0;
+ virtual void emitObjectArch(unsigned Arch) = 0;
virtual void finishAttributeSection() = 0;
virtual void emitInst(uint32_t Inst, char Suffix = '\0') = 0;
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 531e2cc906..74e4e66c6e 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -298,6 +298,7 @@ class ARMAsmParser : public MCTargetAsmParser {
bool parseDirectiveUnwindRaw(SMLoc L);
bool parseDirectiveTLSDescSeq(SMLoc L);
bool parseDirectiveMovSP(SMLoc L);
+ bool parseDirectiveObjectArch(SMLoc L);
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
bool &CarrySetting, unsigned &ProcessorIMod,
@@ -8090,6 +8091,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
else if (IDVal == ".movsp")
return parseDirectiveMovSP(DirectiveID.getLoc());
+ else if (IDVal == ".object_arch")
+ return parseDirectiveObjectArch(DirectiveID.getLoc());
return true;
}
@@ -9094,6 +9097,45 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
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.
extern "C" void LLVMInitializeARMAsmParser() {
RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index 151d48df63..44b56fbe19 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -136,6 +136,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
StringRef StrinValue);
virtual void emitArch(unsigned Arch);
+ virtual void emitObjectArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
@@ -249,6 +250,9 @@ void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
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) {
OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
}
@@ -300,6 +304,7 @@ private:
StringRef CurrentVendor;
unsigned FPU;
unsigned Arch;
+ unsigned EmittedArch;
SmallVector<AttributeItem, 64> Contents;
const MCSection *AttributeSection;
@@ -411,6 +416,7 @@ private:
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
StringRef StringValue);
virtual void emitArch(unsigned Arch);
+ virtual void emitObjectArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
@@ -421,8 +427,9 @@ private:
public:
ARMTargetELFStreamer(MCStreamer &S)
- : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
- Arch(ARM::INVALID_ARCH), AttributeSection(0) {}
+ : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
+ Arch(ARM::INVALID_ARCH), EmittedArch(ARM::INVALID_ARCH),
+ AttributeSection(0) {}
};
/// 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) {
Arch = Value;
}
+void ARMTargetELFStreamer::emitObjectArch(unsigned Value) {
+ EmittedArch = Value;
+}
void ARMTargetELFStreamer::emitArchDefaultAttributes() {
using namespace ARMBuildAttrs;
+
setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
- setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
+ if (EmittedArch == ARM::INVALID_ARCH)
+ setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
+ else
+ setAttributeItem(CPU_arch, GetArchDefaultCPUArch(EmittedArch), false);
switch (Arch) {
case ARM::ARMV2:
diff --git a/test/MC/ARM/directive-object_arch-2.s b/test/MC/ARM/directive-object_arch-2.s
new file mode 100644
index 0000000000..3aca434a1e
--- /dev/null
+++ b/test/MC/ARM/directive-object_arch-2.s
@@ -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: }
+
diff --git a/test/MC/ARM/directive-object_arch-3.s b/test/MC/ARM/directive-object_arch-3.s
new file mode 100644
index 0000000000..5dd26197ab
--- /dev/null
+++ b/test/MC/ARM/directive-object_arch-3.s
@@ -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
+
diff --git a/test/MC/ARM/directive-object_arch-diagnostics.s b/test/MC/ARM/directive-object_arch-diagnostics.s
new file mode 100644
index 0000000000..91b15c8d2d
--- /dev/null
+++ b/test/MC/ARM/directive-object_arch-diagnostics.s
@@ -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: ^
+
diff --git a/test/MC/ARM/directive-object_arch.s b/test/MC/ARM/directive-object_arch.s
new file mode 100644
index 0000000000..0707077630
--- /dev/null
+++ b/test/MC/ARM/directive-object_arch.s
@@ -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: }
+