Skip to content

Commit

Permalink
[arm] Implement ARM .arch directive.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197052 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
loganchien committed Dec 11, 2013
1 parent 7a4d29e commit 61f8483
Show file tree
Hide file tree
Showing 27 changed files with 886 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class ARMTargetStreamer : public MCTargetStreamer {
virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
virtual void emitFPU(unsigned FPU) = 0;
virtual void emitArch(unsigned Arch) = 0;
virtual void finishAttributeSection() = 0;
};

Expand Down
15 changes: 14 additions & 1 deletion lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
45 changes: 45 additions & 0 deletions lib/Target/ARM/MCTargetDesc/ARMArchName.def
Original file line number Diff line number Diff line change
@@ -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
26 changes: 26 additions & 0 deletions lib/Target/ARM/MCTargetDesc/ARMArchName.h
Original file line number Diff line number Diff line change
@@ -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
139 changes: 138 additions & 1 deletion lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//

#include "ARMBuildAttrs.h"
#include "ARMArchName.h"
#include "ARMFPUName.h"
#include "ARMRegisterInfo.h"
#include "ARMUnwindOp.h"
Expand Down Expand Up @@ -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;
Expand All @@ -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();

Expand Down Expand Up @@ -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";
}
Expand Down Expand Up @@ -171,6 +212,7 @@ class ARMTargetELFStreamer : public ARMTargetStreamer {

StringRef CurrentVendor;
unsigned FPU;
unsigned Arch;
SmallVector<AttributeItem, 64> Contents;

const MCSection *AttributeSection;
Expand Down Expand Up @@ -233,6 +275,7 @@ class ARMTargetELFStreamer : public ARMTargetStreamer {
Contents.push_back(Item);
}

void emitArchDefaultAttributes();
void emitFPUDefaultAttributes();

ARMELFStreamer &getStreamer();
Expand All @@ -250,6 +293,7 @@ class ARMTargetELFStreamer : 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();

Expand All @@ -258,7 +302,7 @@ class ARMTargetELFStreamer : public ARMTargetStreamer {
public:
ARMTargetELFStreamer()
: ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
AttributeSection(0) {
Arch(ARM::INVALID_ARCH), AttributeSection(0) {
}
};

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -597,6 +731,9 @@ void ARMTargetELFStreamer::finishAttributeSection() {
if (FPU != ARM::INVALID_FPU)
emitFPUDefaultAttributes();

if (Arch != ARM::INVALID_ARCH)
emitArchDefaultAttributes();

if (Contents.empty())
return;

Expand Down
30 changes: 30 additions & 0 deletions test/MC/ARM/directive-arch-armv2.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@ Test the .arch directive for armv2

@ This test case will check the default .ARM.attributes value for the
@ armv2 architecture.

@ RUN: llvm-mc < %s -arch=arm -filetype=asm \
@ RUN: | FileCheck %s --check-prefix=CHECK-ASM
@ RUN: llvm-mc < %s -arch=arm -filetype=obj \
@ RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CHECK-OBJ

.syntax unified
.arch armv2

@ CHECK-ASM: .arch armv2

@ CHECK-OBJ: Name: .ARM.attributes
@ CHECK-OBJ: Type: SHT_ARM_ATTRIBUTES (0x70000003)
@ CHECK-OBJ: Flags [ (0x0)
@ CHECK-OBJ: ]
@ CHECK-OBJ: Address: 0x0
@ CHECK-OBJ: Offset: 0x34
@ CHECK-OBJ: Size: 23
@ CHECK-OBJ: Link: 0
@ CHECK-OBJ: Info: 0
@ CHECK-OBJ: AddressAlignment: 1
@ CHECK-OBJ: EntrySize: 0
@ CHECK-OBJ: SectionData (
@ CHECK-OBJ: 0000: 41160000 00616561 62690001 0C000000 |A....aeabi......|
@ CHECK-OBJ: 0010: 05320006 010801 |.2.....|
@ CHECK-OBJ: )
30 changes: 30 additions & 0 deletions test/MC/ARM/directive-arch-armv2a.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@ Test the .arch directive for armv2a

@ This test case will check the default .ARM.attributes value for the
@ armv2a architecture.

@ RUN: llvm-mc < %s -arch=arm -filetype=asm \
@ RUN: | FileCheck %s --check-prefix=CHECK-ASM
@ RUN: llvm-mc < %s -arch=arm -filetype=obj \
@ RUN: | llvm-readobj -s -sd | FileCheck %s --check-prefix=CHECK-OBJ

.syntax unified
.arch armv2a

@ CHECK-ASM: .arch armv2a

@ CHECK-OBJ: Name: .ARM.attributes
@ CHECK-OBJ: Type: SHT_ARM_ATTRIBUTES (0x70000003)
@ CHECK-OBJ: Flags [ (0x0)
@ CHECK-OBJ: ]
@ CHECK-OBJ: Address: 0x0
@ CHECK-OBJ: Offset: 0x34
@ CHECK-OBJ: Size: 24
@ CHECK-OBJ: Link: 0
@ CHECK-OBJ: Info: 0
@ CHECK-OBJ: AddressAlignment: 1
@ CHECK-OBJ: EntrySize: 0
@ CHECK-OBJ: SectionData (
@ CHECK-OBJ: 0000: 41170000 00616561 62690001 0D000000 |A....aeabi......|
@ CHECK-OBJ: 0010: 05324100 06010801 |.2A.....|
@ CHECK-OBJ: )
Loading

0 comments on commit 61f8483

Please sign in to comment.