mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-26 12:20:42 +00:00
[ARM] Add knowledge of FPU subtarget features to TargetParser
Add getFPUFeatures to TargetParser, which gets the list of subtarget features that are enabled/disabled for each FPU, and use it when handling the .fpu directive. No functional change in this commit, though clang will start behaving differently once it starts using this. Differential Revision: http://reviews.llvm.org/D10237 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239150 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
+110
-15
@@ -22,27 +22,33 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
// List of canonical FPU names (use getFPUSynonym).
|
||||
// List of canonical FPU names (use getFPUSynonym) and which architectural
|
||||
// features they correspond to (use getFPUFeatures).
|
||||
// FIXME: TableGen this.
|
||||
struct {
|
||||
const char * Name;
|
||||
ARM::FPUKind ID;
|
||||
unsigned FPUVersion; //< Corresponds directly to the FP arch version number.
|
||||
ARM::NeonSupportLevel NeonSupport;
|
||||
ARM::FPURestriction Restriction;
|
||||
} FPUNames[] = {
|
||||
{ "invalid", ARM::FK_INVALID },
|
||||
{ "vfp", ARM::FK_VFP },
|
||||
{ "vfpv2", ARM::FK_VFPV2 },
|
||||
{ "vfpv3", ARM::FK_VFPV3 },
|
||||
{ "vfpv3-d16", ARM::FK_VFPV3_D16 },
|
||||
{ "vfpv4", ARM::FK_VFPV4 },
|
||||
{ "vfpv4-d16", ARM::FK_VFPV4_D16 },
|
||||
{ "fpv5-d16", ARM::FK_FPV5_D16 },
|
||||
{ "fp-armv8", ARM::FK_FP_ARMV8 },
|
||||
{ "neon", ARM::FK_NEON },
|
||||
{ "neon-vfpv4", ARM::FK_NEON_VFPV4 },
|
||||
{ "neon-fp-armv8", ARM::FK_NEON_FP_ARMV8 },
|
||||
{ "crypto-neon-fp-armv8", ARM::FK_CRYPTO_NEON_FP_ARMV8 },
|
||||
{ "softvfp", ARM::FK_SOFTVFP }
|
||||
{ "invalid", ARM::FK_INVALID, 0, ARM::NS_None, ARM::FR_None},
|
||||
{ "vfp", ARM::FK_VFP, 2, ARM::NS_None, ARM::FR_None},
|
||||
{ "vfpv2", ARM::FK_VFPV2, 2, ARM::NS_None, ARM::FR_None},
|
||||
{ "vfpv3", ARM::FK_VFPV3, 3, ARM::NS_None, ARM::FR_None},
|
||||
{ "vfpv3-d16", ARM::FK_VFPV3_D16, 3, ARM::NS_None, ARM::FR_D16},
|
||||
{ "vfpv4", ARM::FK_VFPV4, 4, ARM::NS_None, ARM::FR_None},
|
||||
{ "vfpv4-d16", ARM::FK_VFPV4_D16, 4, ARM::NS_None, ARM::FR_D16},
|
||||
{ "fpv5-d16", ARM::FK_FPV5_D16, 5, ARM::NS_None, ARM::FR_D16},
|
||||
{ "fp-armv8", ARM::FK_FP_ARMV8, 5, ARM::NS_None, ARM::FR_None},
|
||||
{ "neon", ARM::FK_NEON, 3, ARM::NS_Neon, ARM::FR_None},
|
||||
{ "neon-vfpv4", ARM::FK_NEON_VFPV4, 4, ARM::NS_Neon, ARM::FR_None},
|
||||
{ "neon-fp-armv8", ARM::FK_NEON_FP_ARMV8, 5, ARM::NS_Neon, ARM::FR_None},
|
||||
{ "crypto-neon-fp-armv8",
|
||||
ARM::FK_CRYPTO_NEON_FP_ARMV8, 5, ARM::NS_Crypto, ARM::FR_None},
|
||||
{ "softvfp", ARM::FK_SOFTVFP, 0, ARM::NS_None, ARM::FR_None},
|
||||
};
|
||||
|
||||
// List of canonical arch names (use getArchSynonym).
|
||||
// This table also provides the build attribute fields for CPU arch
|
||||
// and Arch ID, according to the Addenda to the ARM ABI, chapters
|
||||
@@ -226,6 +232,95 @@ const char *ARMTargetParser::getFPUName(unsigned FPUKind) {
|
||||
return FPUNames[FPUKind].Name;
|
||||
}
|
||||
|
||||
unsigned ARMTargetParser::getFPUVersion(unsigned FPUKind) {
|
||||
if (FPUKind >= ARM::FK_LAST)
|
||||
return 0;
|
||||
return FPUNames[FPUKind].FPUVersion;
|
||||
}
|
||||
|
||||
unsigned getFPUNeonSupportLevel(unsigned FPUKind) {
|
||||
if (FPUKind >= ARM::FK_LAST)
|
||||
return 0;
|
||||
return FPUNames[FPUKind].NeonSupport;
|
||||
}
|
||||
|
||||
unsigned getFPURestriction(unsigned FPUKind) {
|
||||
if (FPUKind >= ARM::FK_LAST)
|
||||
return 0;
|
||||
return FPUNames[FPUKind].Restriction;
|
||||
}
|
||||
|
||||
bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
|
||||
std::vector<const char *> &Features) {
|
||||
|
||||
if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
|
||||
return false;
|
||||
|
||||
// fp-only-sp and d16 subtarget features are independent of each other, so we
|
||||
// must enable/disable both.
|
||||
switch (FPUNames[FPUKind].Restriction) {
|
||||
case ARM::FR_SP_D16:
|
||||
Features.push_back("+fp-only-sp");
|
||||
Features.push_back("+d16");
|
||||
break;
|
||||
case ARM::FR_D16:
|
||||
Features.push_back("-fp-only-sp");
|
||||
Features.push_back("+d16");
|
||||
break;
|
||||
case ARM::FR_None:
|
||||
Features.push_back("-fp-only-sp");
|
||||
Features.push_back("-d16");
|
||||
break;
|
||||
}
|
||||
|
||||
// FPU version subtarget features are inclusive of lower-numbered ones, so
|
||||
// enable the one corresponding to this version and disable all that are
|
||||
// higher.
|
||||
switch (FPUNames[FPUKind].FPUVersion) {
|
||||
case 5:
|
||||
Features.push_back("+fp-armv8");
|
||||
break;
|
||||
case 4:
|
||||
Features.push_back("+vfp4");
|
||||
Features.push_back("-fp-armv8");
|
||||
break;
|
||||
case 3:
|
||||
Features.push_back("+vfp3");
|
||||
Features.push_back("-vfp4");
|
||||
Features.push_back("-fp-armv8");
|
||||
break;
|
||||
case 2:
|
||||
Features.push_back("+vfp2");
|
||||
Features.push_back("-vfp3");
|
||||
Features.push_back("-vfp4");
|
||||
Features.push_back("-fp-armv8");
|
||||
break;
|
||||
case 0:
|
||||
Features.push_back("-vfp2");
|
||||
Features.push_back("-vfp3");
|
||||
Features.push_back("-vfp4");
|
||||
Features.push_back("-fp-armv8");
|
||||
break;
|
||||
}
|
||||
|
||||
// crypto includes neon, so we handle this similarly to FPU version.
|
||||
switch (FPUNames[FPUKind].NeonSupport) {
|
||||
case ARM::NS_Crypto:
|
||||
Features.push_back("+crypto");
|
||||
break;
|
||||
case ARM::NS_Neon:
|
||||
Features.push_back("+neon");
|
||||
Features.push_back("-crypto");
|
||||
break;
|
||||
case ARM::NS_None:
|
||||
Features.push_back("-neon");
|
||||
Features.push_back("-crypto");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *ARMTargetParser::getArchName(unsigned ArchKind) {
|
||||
if (ArchKind >= ARM::AK_LAST)
|
||||
return nullptr;
|
||||
|
||||
Reference in New Issue
Block a user