Skip to content

Commit

Permalink
- Added support for parsing HWDiv features using Target Parser.
Browse files Browse the repository at this point in the history
- Architecture extensions are represented as a bitmap.

Phabricator: http://reviews.llvm.org/D11457

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243335 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
labrinea committed Jul 27, 2015
1 parent f78e199 commit 10da90a
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 36 deletions.
36 changes: 21 additions & 15 deletions include/llvm/Support/TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,23 @@ namespace ARM {

// Arch extension modifiers for CPUs.
enum ArchExtKind {
AEK_INVALID = 0,
AEK_CRC,
AEK_CRYPTO,
AEK_FP,
AEK_HWDIV,
AEK_MP,
AEK_SIMD,
AEK_SEC,
AEK_VIRT,
AEK_INVALID = 0x0,
AEK_NONE = 0x1,
AEK_CRC = 0x2,
AEK_CRYPTO = 0x4,
AEK_FP = 0x8,
AEK_HWDIV = 0x10,
AEK_HWDIVARM = 0x20,
AEK_MP = 0x40,
AEK_SIMD = 0x80,
AEK_SEC = 0x100,
AEK_VIRT = 0x200,
// Unsupported extensions.
AEK_OS,
AEK_IWMMXT,
AEK_IWMMXT2,
AEK_MAVERICK,
AEK_XSCALE,
AEK_LAST
AEK_OS = 0x8000000,
AEK_IWMMXT = 0x10000000,
AEK_IWMMXT2 = 0x20000000,
AEK_MAVERICK = 0x40000000,
AEK_XSCALE = 0x80000000,
};

// ISA kinds.
Expand Down Expand Up @@ -167,6 +168,7 @@ namespace ARM {

// Target Parsers, one per architecture.
class ARMTargetParser {
static StringRef getHWDivSynonym(StringRef HWDiv);
static StringRef getFPUSynonym(StringRef FPU);
static StringRef getArchSynonym(StringRef Arch);

Expand All @@ -182,14 +184,18 @@ class ARMTargetParser {
// FIXME: This should be moved to TargetTuple once it exists
static bool getFPUFeatures(unsigned FPUKind,
std::vector<const char*> &Features);
static bool getHWDivFeatures(unsigned HWDivKind,
std::vector<const char*> &Features);
static const char * getArchName(unsigned ArchKind);
static unsigned getArchAttr(unsigned ArchKind);
static const char * getCPUAttr(unsigned ArchKind);
static const char * getSubArch(unsigned ArchKind);
static const char * getArchExtName(unsigned ArchExtKind);
static const char * getHWDivName(unsigned HWDivKind);
static const char * getDefaultCPU(StringRef Arch);

// Parser
static unsigned parseHWDiv(StringRef HWDiv);
static unsigned parseFPU(StringRef FPU);
static unsigned parseArch(StringRef Arch);
static unsigned parseArchExt(StringRef ArchExt);
Expand Down
94 changes: 76 additions & 18 deletions lib/Support/TargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,36 @@ struct {
// FIXME: TableGen this.
struct {
const char *Name;
ARM::ArchExtKind ID;
unsigned ID;
} ARCHExtNames[] = {
{ "invalid", ARM::AEK_INVALID },
{ "crc", ARM::AEK_CRC },
{ "crypto", ARM::AEK_CRYPTO },
{ "fp", ARM::AEK_FP },
{ "idiv", ARM::AEK_HWDIV },
{ "mp", ARM::AEK_MP },
{ "simd", ARM::AEK_SIMD },
{ "sec", ARM::AEK_SEC },
{ "virt", ARM::AEK_VIRT },
{ "os", ARM::AEK_OS },
{ "iwmmxt", ARM::AEK_IWMMXT },
{ "iwmmxt2", ARM::AEK_IWMMXT2 },
{ "maverick", ARM::AEK_MAVERICK },
{ "xscale", ARM::AEK_XSCALE }
{ "invalid", ARM::AEK_INVALID },
{ "none", ARM::AEK_NONE },
{ "crc", ARM::AEK_CRC },
{ "crypto", ARM::AEK_CRYPTO },
{ "fp", ARM::AEK_FP },
{ "idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV) },
{ "mp", ARM::AEK_MP },
{ "simd", ARM::AEK_SIMD },
{ "sec", ARM::AEK_SEC },
{ "virt", ARM::AEK_VIRT },
{ "os", ARM::AEK_OS },
{ "iwmmxt", ARM::AEK_IWMMXT },
{ "iwmmxt2", ARM::AEK_IWMMXT2 },
{ "maverick", ARM::AEK_MAVERICK },
{ "xscale", ARM::AEK_XSCALE }
};
// List of HWDiv names (use getHWDivSynonym) and which architectural
// features they correspond to (use getHWDivFeatures).
// FIXME: TableGen this.
struct {
const char *Name;
unsigned ID;
} HWDivNames[] = {
{ "invalid", ARM::AEK_INVALID },
{ "none", ARM::AEK_NONE },
{ "thumb", ARM::AEK_HWDIV },
{ "arm", ARM::AEK_HWDIVARM },
{ "arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV) }
};
// List of CPU names and their arches.
// The same CPU can have multiple arches and can be default on multiple arches.
Expand Down Expand Up @@ -266,6 +280,25 @@ unsigned ARMTargetParser::getDefaultFPU(StringRef CPU) {
return ARM::FK_INVALID;
}

bool ARMTargetParser::getHWDivFeatures(unsigned HWDivKind,
std::vector<const char *> &Features) {

if (HWDivKind == ARM::AEK_INVALID)
return false;

if (HWDivKind & ARM::AEK_HWDIVARM)
Features.push_back("+hwdiv-arm");
else
Features.push_back("-hwdiv-arm");

if (HWDivKind & ARM::AEK_HWDIV)
Features.push_back("+hwdiv");
else
Features.push_back("-hwdiv");

return true;
}

bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
std::vector<const char *> &Features) {

Expand Down Expand Up @@ -372,9 +405,19 @@ unsigned ARMTargetParser::getArchAttr(unsigned ArchKind) {
}

const char *ARMTargetParser::getArchExtName(unsigned ArchExtKind) {
if (ArchExtKind >= ARM::AEK_LAST)
return nullptr;
return ARCHExtNames[ArchExtKind].Name;
for (const auto AE : ARCHExtNames) {
if (ArchExtKind == AE.ID)
return AE.Name;
}
return nullptr;
}

const char *ARMTargetParser::getHWDivName(unsigned HWDivKind) {
for (const auto D : HWDivNames) {
if (HWDivKind == D.ID)
return D.Name;
}
return nullptr;
}

const char *ARMTargetParser::getDefaultCPU(StringRef Arch) {
Expand All @@ -394,6 +437,12 @@ const char *ARMTargetParser::getDefaultCPU(StringRef Arch) {
// Parsers
// ======================================================= //

StringRef ARMTargetParser::getHWDivSynonym(StringRef HWDiv) {
return StringSwitch<StringRef>(HWDiv)
.Case("thumb,arm", "arm,thumb")
.Default(HWDiv);
}

StringRef ARMTargetParser::getFPUSynonym(StringRef FPU) {
return StringSwitch<StringRef>(FPU)
.Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
Expand Down Expand Up @@ -477,6 +526,15 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
return A;
}

unsigned ARMTargetParser::parseHWDiv(StringRef HWDiv) {
StringRef Syn = getHWDivSynonym(HWDiv);
for (const auto D : HWDivNames) {
if (Syn == D.Name)
return D.ID;
}
return ARM::AEK_INVALID;
}

unsigned ARMTargetParser::parseFPU(StringRef FPU) {
StringRef Syn = getFPUSynonym(FPU);
for (const auto F : FPUNames) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/ARM/ARMAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ void ARMAsmPrinter::emitAttributes() {
// We consider krait as a "cortex-a9" + hwdiv CPU
// Enable hwdiv through ".arch_extension idiv"
if (STI.hasDivide() || STI.hasDivideInARMMode())
ATS.emitArchExtension(ARM::AEK_HWDIV);
ATS.emitArchExtension(ARM::AEK_HWDIV | ARM::AEK_HWDIVARM);
} else
ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9971,15 +9971,15 @@ extern "C" void LLVMInitializeARMAsmParser() {
// when we start to table-generate them, and we can use the ARM
// flags below, that were generated by table-gen.
static const struct {
const ARM::ArchExtKind Kind;
const unsigned Kind;
const unsigned ArchCheck;
const FeatureBitset Features;
} Extensions[] = {
{ ARM::AEK_CRC, Feature_HasV8, {ARM::FeatureCRC} },
{ ARM::AEK_CRYPTO, Feature_HasV8,
{ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
{ ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
{ ARM::AEK_HWDIV, Feature_HasV7 | Feature_IsNotMClass,
{ (ARM::AEK_HWDIV | ARM::AEK_HWDIVARM), Feature_HasV7 | Feature_IsNotMClass,
{ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
{ ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
{ ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
Expand Down

0 comments on commit 10da90a

Please sign in to comment.