Factor ARM triple parsing out of ARMSubtarget. Another step towards making ARM subtarget info available to MC.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2011-07-07 00:08:19 +00:00
parent a4acb008cb
commit 94ca42ff04
7 changed files with 84 additions and 91 deletions

View File

@ -27,7 +27,7 @@ def FeatureVFP3 : SubtargetFeature<"vfp3", "ARMFPUType", "VFPv3",
"Enable VFP3 instructions">; "Enable VFP3 instructions">;
def FeatureNEON : SubtargetFeature<"neon", "ARMFPUType", "NEON", def FeatureNEON : SubtargetFeature<"neon", "ARMFPUType", "NEON",
"Enable NEON instructions">; "Enable NEON instructions">;
def FeatureThumb2 : SubtargetFeature<"thumb2", "ThumbMode", "Thumb2", def FeatureThumb2 : SubtargetFeature<"thumb2", "HasThumb2", "true",
"Enable Thumb2 instructions">; "Enable Thumb2 instructions">;
def FeatureNoARM : SubtargetFeature<"noarm", "NoARM", "true", def FeatureNoARM : SubtargetFeature<"noarm", "NoARM", "true",
"Does not support ARM mode execution">; "Does not support ARM mode execution">;

View File

@ -37,7 +37,7 @@ StrictAlign("arm-strict-align", cl::Hidden,
cl::desc("Disallow all unaligned memory accesses")); cl::desc("Disallow all unaligned memory accesses"));
ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, bool isT) const std::string &FS)
: ARMGenSubtargetInfo() : ARMGenSubtargetInfo()
, ARMArchVersion(V4) , ARMArchVersion(V4)
, ARMProcFamily(Others) , ARMProcFamily(Others)
@ -46,8 +46,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
, SlowFPVMLx(false) , SlowFPVMLx(false)
, HasVMLxForwarding(false) , HasVMLxForwarding(false)
, SlowFPBrcc(false) , SlowFPBrcc(false)
, IsThumb(isT) , IsThumb(false)
, ThumbMode(Thumb1) , HasThumb2(false)
, NoARM(false) , NoARM(false)
, PostRAScheduler(false) , PostRAScheduler(false)
, IsR9Reserved(ReserveR9) , IsR9Reserved(ReserveR9)
@ -68,65 +68,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
, TargetTriple(TT) , TargetTriple(TT)
, TargetABI(ARM_ABI_APCS) { , TargetABI(ARM_ABI_APCS) {
// Determine default and user specified characteristics // Determine default and user specified characteristics
// When no arch is specified either by CPU or by attributes, make the default
// ARMv4T.
const char *ARMArchFeature = "";
if (CPUString.empty()) if (CPUString.empty())
CPUString = "generic"; CPUString = "generic";
if (CPUString == "generic" && (FS.empty() || FS == "generic")) {
ARMArchVersion = V4T;
ARMArchFeature = "+v4t";
}
// Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true.
unsigned Len = TT.length();
unsigned Idx = 0;
if (Len >= 5 && TT.substr(0, 4) == "armv")
Idx = 4;
else if (Len >= 6 && TT.substr(0, 5) == "thumb") {
IsThumb = true;
if (Len >= 7 && TT[5] == 'v')
Idx = 6;
}
if (Idx) {
unsigned SubVer = TT[Idx];
if (SubVer >= '7' && SubVer <= '9') {
ARMArchVersion = V7A;
ARMArchFeature = "+v7a";
if (Len >= Idx+2 && TT[Idx+1] == 'm') {
ARMArchVersion = V7M;
ARMArchFeature = "+v7m";
} else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
ARMArchVersion = V7EM;
ARMArchFeature = "+v7em";
}
} else if (SubVer == '6') {
ARMArchVersion = V6;
ARMArchFeature = "+v6";
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') {
ARMArchVersion = V6T2;
ARMArchFeature = "+v6t2";
}
} else if (SubVer == '5') {
ARMArchVersion = V5T;
ARMArchFeature = "+v5t";
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') {
ARMArchVersion = V5TE;
ARMArchFeature = "+v5te";
}
} else if (SubVer == '4') {
if (Len >= Idx+2 && TT[Idx+1] == 't') {
ARMArchVersion = V4T;
ARMArchFeature = "+v4t";
} else {
ARMArchVersion = V4;
ARMArchFeature = "";
}
}
}
if (TT.find("eabi") != std::string::npos) if (TT.find("eabi") != std::string::npos)
TargetABI = ARM_ABI_AAPCS; TargetABI = ARM_ABI_AAPCS;
@ -134,12 +77,20 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
// Insert the architecture feature derived from the target triple into the // Insert the architecture feature derived from the target triple into the
// feature string. This is important for setting features that are implied // feature string. This is important for setting features that are implied
// based on the architecture version. // based on the architecture version.
std::string FSWithArch = std::string(ARMArchFeature); std::string ArchFS = ARM_MC::ParseARMTriple(TT, IsThumb);
if (FSWithArch.empty()) if (!FS.empty()) {
FSWithArch = FS; if (!ArchFS.empty())
else if (!FS.empty()) ArchFS = ArchFS + "," + FS;
FSWithArch = FSWithArch + "," + FS; else
ParseSubtargetFeatures(FSWithArch, CPUString); ArchFS = FS;
}
ParseSubtargetFeatures(ArchFS, CPUString);
// Thumb2 implies at least V6T2. FIXME: Fix tests to explicitly specify a
// ARM version or CPU and then remove this.
if (ARMArchVersion < V6T2 && hasThumb2())
ARMArchVersion = V6T2;
// Initialize scheduling itinerary for the specified CPU. // Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(CPUString); InstrItins = getInstrItineraryForCPU(CPUString);
@ -147,12 +98,6 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
// After parsing Itineraries, set ItinData.IssueWidth. // After parsing Itineraries, set ItinData.IssueWidth.
computeIssueWidth(); computeIssueWidth();
// Thumb2 implies at least V6T2.
if (ARMArchVersion >= V6T2)
ThumbMode = Thumb2;
else if (ThumbMode >= Thumb2)
ARMArchVersion = V6T2;
if (isAAPCS_ABI()) if (isAAPCS_ABI())
stackAlignment = 8; stackAlignment = 8;

View File

@ -14,6 +14,7 @@
#ifndef ARMSUBTARGET_H #ifndef ARMSUBTARGET_H
#define ARMSUBTARGET_H #define ARMSUBTARGET_H
#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCInstrItineraries.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
@ -39,11 +40,6 @@ protected:
None, VFPv2, VFPv3, NEON None, VFPv2, VFPv3, NEON
}; };
enum ThumbTypeEnum {
Thumb1,
Thumb2
};
/// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE, /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
/// V6, V6T2, V7A, V7M, V7EM. /// V6, V6T2, V7A, V7M, V7EM.
ARMArchEnum ARMArchVersion; ARMArchEnum ARMArchVersion;
@ -73,8 +69,8 @@ protected:
/// IsThumb - True if we are in thumb mode, false if in ARM mode. /// IsThumb - True if we are in thumb mode, false if in ARM mode.
bool IsThumb; bool IsThumb;
/// ThumbMode - Indicates supported Thumb version. /// HasThumb2 - True if Thumb2 instructions are supported.
ThumbTypeEnum ThumbMode; bool HasThumb2;
/// NoARM - True if subtarget does not support ARM mode execution. /// NoARM - True if subtarget does not support ARM mode execution.
bool NoARM; bool NoARM;
@ -161,7 +157,7 @@ protected:
/// of the specified triple. /// of the specified triple.
/// ///
ARMSubtarget(const std::string &TT, const std::string &CPU, ARMSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, bool isThumb); const std::string &FS);
/// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
/// that still makes it profitable to inline the call. /// that still makes it profitable to inline the call.
@ -217,9 +213,9 @@ protected:
bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; } bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; }
bool isThumb() const { return IsThumb; } bool isThumb() const { return IsThumb; }
bool isThumb1Only() const { return IsThumb && (ThumbMode == Thumb1); } bool isThumb1Only() const { return IsThumb && !HasThumb2; }
bool isThumb2() const { return IsThumb && (ThumbMode == Thumb2); } bool isThumb2() const { return IsThumb && HasThumb2; }
bool hasThumb2() const { return ThumbMode >= Thumb2; } bool hasThumb2() const { return HasThumb2; }
bool isR9Reserved() const { return IsR9Reserved; } bool isR9Reserved() const { return IsR9Reserved; }

View File

@ -79,10 +79,9 @@ extern "C" void LLVMInitializeARMTarget() {
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
const std::string &TT, const std::string &TT,
const std::string &CPU, const std::string &CPU,
const std::string &FS, const std::string &FS)
bool isThumb)
: LLVMTargetMachine(T, TT), : LLVMTargetMachine(T, TT),
Subtarget(TT, CPU, FS, isThumb), Subtarget(TT, CPU, FS),
JITInfo(), JITInfo(),
InstrItins(Subtarget.getInstrItineraryData()) { InstrItins(Subtarget.getInstrItineraryData()) {
DefRelocModel = getRelocationModel(); DefRelocModel = getRelocationModel();
@ -95,7 +94,7 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT, ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
const std::string &CPU, const std::string &CPU,
const std::string &FS) const std::string &FS)
: ARMBaseTargetMachine(T, TT, CPU, FS, false), InstrInfo(Subtarget), : ARMBaseTargetMachine(T, TT, CPU, FS), InstrInfo(Subtarget),
DataLayout(Subtarget.isAPCS_ABI() ? DataLayout(Subtarget.isAPCS_ABI() ?
std::string("e-p:32:32-f64:32:64-i64:32:64-" std::string("e-p:32:32-f64:32:64-i64:32:64-"
"v128:32:128-v64:32:64-n32") : "v128:32:128-v64:32:64-n32") :
@ -113,7 +112,7 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT, ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
const std::string &CPU, const std::string &CPU,
const std::string &FS) const std::string &FS)
: ARMBaseTargetMachine(T, TT, CPU, FS, true), : ARMBaseTargetMachine(T, TT, CPU, FS),
InstrInfo(Subtarget.hasThumb2() InstrInfo(Subtarget.hasThumb2()
? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget)) ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
: ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))), : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),

View File

@ -41,8 +41,7 @@ private:
public: public:
ARMBaseTargetMachine(const Target &T, const std::string &TT, ARMBaseTargetMachine(const Target &T, const std::string &TT,
const std::string &CPU, const std::string &FS, const std::string &CPU, const std::string &FS);
bool isThumb);
virtual ARMJITInfo *getJITInfo() { return &JITInfo; } virtual ARMJITInfo *getJITInfo() { return &JITInfo; }
virtual const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; } virtual const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; }

View File

@ -72,3 +72,49 @@ extern "C" void LLVMInitializeARMMCSubtargetInfo() {
TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget,
createARMMCSubtargetInfo); createARMMCSubtargetInfo);
} }
std::string ARM_MC::ParseARMTriple(StringRef TT, bool &IsThumb) {
// Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true.
unsigned Len = TT.size();
unsigned Idx = 0;
if (Len >= 5 && TT.substr(0, 4) == "armv")
Idx = 4;
else if (Len >= 6 && TT.substr(0, 5) == "thumb") {
IsThumb = true;
if (Len >= 7 && TT[5] == 'v')
Idx = 6;
}
std::string ARMArchFeature;
if (Idx) {
unsigned SubVer = TT[Idx];
if (SubVer >= '7' && SubVer <= '9') {
ARMArchFeature = "+v7a";
if (Len >= Idx+2 && TT[Idx+1] == 'm') {
ARMArchFeature = "+v7m";
} else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
ARMArchFeature = "+v7em";
}
} else if (SubVer == '6') {
ARMArchFeature = "+v6";
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') {
ARMArchFeature = "+v6t2";
}
} else if (SubVer == '5') {
ARMArchFeature = "+v5t";
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') {
ARMArchFeature = "+v5te";
}
} else if (SubVer == '4') {
if (Len >= Idx+2 && TT[Idx+1] == 't') {
ARMArchFeature = "+v4t";
} else {
ARMArchFeature = "";
}
}
}
return ARMArchFeature;
}

View File

@ -14,10 +14,18 @@
#ifndef ARMMCTARGETDESC_H #ifndef ARMMCTARGETDESC_H
#define ARMMCTARGETDESC_H #define ARMMCTARGETDESC_H
#include <string>
namespace llvm { namespace llvm {
class Target; class Target;
class StringRef;
extern Target TheARMTarget, TheThumbTarget; extern Target TheARMTarget, TheThumbTarget;
namespace ARM_MC {
std::string ParseARMTriple(StringRef TT, bool &IsThumb);
}
} // End llvm namespace } // End llvm namespace
// Defines symbolic names for ARM registers. This defines a mapping from // Defines symbolic names for ARM registers. This defines a mapping from