summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2013-12-11 17:16:25 +0000
committerLogan Chien <tzuhsiang.chien@gmail.com>2013-12-11 17:16:25 +0000
commit61f848360f4c165ca21d34fc765bb68b25203553 (patch)
tree1595c13484874918b8d7a9c4c418cfe741c9d34b /lib
parent7a4d29e569c5e6aee5054bc1069328c8086b0eb6 (diff)
downloadllvm-61f848360f4c165ca21d34fc765bb68b25203553.tar.gz
llvm-61f848360f4c165ca21d34fc765bb68b25203553.tar.bz2
llvm-61f848360f4c165ca21d34fc765bb68b25203553.tar.xz
[arm] Implement ARM .arch directive.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197052 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp15
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMArchName.def45
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMArchName.h26
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp139
4 files changed, 223 insertions, 2 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 2ad0a51815..bf73ba6ee6 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -12,6 +12,7 @@
#include "ARMFeatures.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "MCTargetDesc/ARMAddressingModes.h"
+#include "MCTargetDesc/ARMArchName.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMMCExpr.h"
#include "llvm/ADT/BitVector.h"
@@ -8006,7 +8007,19 @@ bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
/// parseDirectiveArch
/// ::= .arch token
bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
- return true;
+ StringRef Arch = getParser().parseStringToEndOfStatement().trim();
+
+ unsigned ID = StringSwitch<unsigned>(Arch)
+#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
+ .Case(NAME, ARM::ID)
+#include "MCTargetDesc/ARMArchName.def"
+ .Default(ARM::INVALID_ARCH);
+
+ if (ID == ARM::INVALID_ARCH)
+ return Error(L, "Unknown arch name");
+
+ getTargetStreamer().emitArch(ID);
+ return false;
}
/// parseDirectiveEabiAttr
diff --git a/lib/Target/ARM/MCTargetDesc/ARMArchName.def b/lib/Target/ARM/MCTargetDesc/ARMArchName.def
new file mode 100644
index 0000000000..37e814e072
--- /dev/null
+++ b/lib/Target/ARM/MCTargetDesc/ARMArchName.def
@@ -0,0 +1,45 @@
+//===-- ARMArchName.def - List of the ARM arch 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 architecture names,
+// i.e. the supported value for -march= option.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef ARM_ARCH_NAME
+#error "You must define ARM_ARCH_NAME before including ARMArchName.def"
+#endif
+
+// ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH)
+ARM_ARCH_NAME("armv2", ARMV2, "2", v4)
+ARM_ARCH_NAME("armv2a", ARMV2A, "2A", v4)
+ARM_ARCH_NAME("armv3", ARMV3, "3", v4)
+ARM_ARCH_NAME("armv3m", ARMV3M, "3M", v4)
+ARM_ARCH_NAME("armv4", ARMV4, "4", v4)
+ARM_ARCH_NAME("armv4t", ARMV4T, "4T", v4T)
+ARM_ARCH_NAME("armv5", ARMV5, "5", v5T)
+ARM_ARCH_NAME("armv5t", ARMV5T, "5T", v5T)
+ARM_ARCH_NAME("armv5te", ARMV5TE, "5TE", v5TE)
+ARM_ARCH_NAME("armv6", ARMV6, "6", v6)
+ARM_ARCH_NAME("armv6j", ARMV6J, "6J", v6)
+ARM_ARCH_NAME("armv6t2", ARMV6T2, "6T2", v6T2)
+ARM_ARCH_NAME("armv6z", ARMV6Z, "6Z", v6KZ)
+ARM_ARCH_NAME("armv6zk", ARMV6ZK, "6ZK", v6KZ)
+ARM_ARCH_NAME("armv6-m", ARMV6M, "6-M", v6_M)
+ARM_ARCH_NAME("armv7", ARMV7, "7", v7)
+ARM_ARCH_NAME("armv7-a", ARMV7A, "7-A", v7)
+ARM_ARCH_NAME("armv7-r", ARMV7R, "7-R", v7)
+ARM_ARCH_NAME("armv7-m", ARMV7M, "7-M", v7)
+ARM_ARCH_NAME("armv8-a", ARMV8A, "8-A", v8)
+ARM_ARCH_NAME("iwmmxt", IWMMXT, "iwmmxt", v5TE)
+ARM_ARCH_NAME("iwmmxt2", IWMMXT2, "iwmmxt2", v5TE)
+
+#undef ARM_ARCH_NAME
diff --git a/lib/Target/ARM/MCTargetDesc/ARMArchName.h b/lib/Target/ARM/MCTargetDesc/ARMArchName.h
new file mode 100644
index 0000000000..d0de9ccb8a
--- /dev/null
+++ b/lib/Target/ARM/MCTargetDesc/ARMArchName.h
@@ -0,0 +1,26 @@
+//===-- ARMArchName.h - List of the ARM arch names --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARMARCHNAME_H
+#define ARMARCHNAME_H
+
+namespace llvm {
+namespace ARM {
+
+enum ArchKind {
+ INVALID_ARCH = 0
+
+#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) , ID
+#include "ARMArchName.def"
+};
+
+} // namespace ARM
+} // namespace llvm
+
+#endif // ARMARCHNAME_H
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index 471897de5c..1dc57768f6 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "ARMBuildAttrs.h"
+#include "ARMArchName.h"
#include "ARMFPUName.h"
#include "ARMRegisterInfo.h"
#include "ARMUnwindOp.h"
@@ -61,6 +62,42 @@ static const char *GetFPUName(unsigned ID) {
return NULL;
}
+static const char *GetArchName(unsigned ID) {
+ switch (ID) {
+ default:
+ llvm_unreachable("Unknown ARCH kind");
+ break;
+#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
+ case ARM::ID: return NAME;
+#include "ARMArchName.def"
+ }
+ return NULL;
+}
+
+static const char *GetArchDefaultCPUName(unsigned ID) {
+ switch (ID) {
+ default:
+ llvm_unreachable("Unknown ARCH kind");
+ break;
+#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
+ case ARM::ID: return DEFAULT_CPU_NAME;
+#include "ARMArchName.def"
+ }
+ return NULL;
+}
+
+static unsigned GetArchDefaultCPUArch(unsigned ID) {
+ switch (ID) {
+ default:
+ llvm_unreachable("Unknown ARCH kind");
+ break;
+#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
+ case ARM::ID: return ARMBuildAttrs::DEFAULT_CPU_ARCH;
+#include "ARMArchName.def"
+ }
+ return 0;
+}
+
namespace {
class ARMELFStreamer;
@@ -82,6 +119,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
virtual void switchVendor(StringRef Vendor);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+ virtual void emitArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
virtual void finishAttributeSection();
@@ -143,6 +181,9 @@ void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
break;
}
}
+void ARMTargetAsmStreamer::emitArch(unsigned Arch) {
+ OS << "\t.arch\t" << GetArchName(Arch) << "\n";
+}
void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
}
@@ -171,6 +212,7 @@ private:
StringRef CurrentVendor;
unsigned FPU;
+ unsigned Arch;
SmallVector<AttributeItem, 64> Contents;
const MCSection *AttributeSection;
@@ -233,6 +275,7 @@ private:
Contents.push_back(Item);
}
+ void emitArchDefaultAttributes();
void emitFPUDefaultAttributes();
ARMELFStreamer &getStreamer();
@@ -250,6 +293,7 @@ private:
virtual void switchVendor(StringRef Vendor);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+ virtual void emitArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
virtual void finishAttributeSection();
@@ -258,7 +302,7 @@ private:
public:
ARMTargetELFStreamer()
: ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
- AttributeSection(0) {
+ Arch(ARM::INVALID_ARCH), AttributeSection(0) {
}
};
@@ -491,6 +535,96 @@ void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
StringRef Value) {
setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
}
+void ARMTargetELFStreamer::emitArch(unsigned Value) {
+ Arch = Value;
+}
+void ARMTargetELFStreamer::emitArchDefaultAttributes() {
+ using namespace ARMBuildAttrs;
+ setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
+ setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
+
+ switch (Arch) {
+ case ARM::ARMV2:
+ case ARM::ARMV2A:
+ case ARM::ARMV3:
+ case ARM::ARMV3M:
+ case ARM::ARMV4:
+ case ARM::ARMV5:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ break;
+
+ case ARM::ARMV4T:
+ case ARM::ARMV5T:
+ case ARM::ARMV5TE:
+ case ARM::ARMV6:
+ case ARM::ARMV6J:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, Allowed, false);
+ break;
+
+ case ARM::ARMV6T2:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ break;
+
+ case ARM::ARMV6Z:
+ case ARM::ARMV6ZK:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, Allowed, false);
+ setAttributeItem(Virtualization_use, AllowTZ, false);
+ break;
+
+ case ARM::ARMV6M:
+ setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
+ setAttributeItem(THUMB_ISA_use, Allowed, false);
+ break;
+
+ case ARM::ARMV7:
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ break;
+
+ case ARM::ARMV7A:
+ setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ break;
+
+ case ARM::ARMV7R:
+ setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ break;
+
+ case ARM::ARMV7M:
+ setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ break;
+
+ case ARM::ARMV8A:
+ setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
+ setAttributeItem(MPextension_use, Allowed, false);
+ setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
+ break;
+
+ case ARM::IWMMXT:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, Allowed, false);
+ setAttributeItem(WMMX_arch, AllowWMMXv1, false);
+ break;
+
+ case ARM::IWMMXT2:
+ setAttributeItem(ARM_ISA_use, Allowed, false);
+ setAttributeItem(THUMB_ISA_use, Allowed, false);
+ setAttributeItem(WMMX_arch, AllowWMMXv2, false);
+ break;
+
+ default:
+ report_fatal_error("Unknown Arch: " + Twine(Arch));
+ break;
+ }
+}
void ARMTargetELFStreamer::emitFPU(unsigned Value) {
FPU = Value;
}
@@ -597,6 +731,9 @@ void ARMTargetELFStreamer::finishAttributeSection() {
if (FPU != ARM::INVALID_FPU)
emitFPUDefaultAttributes();
+ if (Arch != ARM::INVALID_ARCH)
+ emitArchDefaultAttributes();
+
if (Contents.empty())
return;