forked from OSchip/llvm-project
[PowerPC] Add support for embedded devices with EFPU2
PowerPC cores like e200z759n3 [1] using an efpu2 only support single precision hardware floating point instructions. The single precision instructions efs* and evfs* are identical to the spe float instructions while efd* and evfd* instructions trigger a not implemented exception. This patch introduces a new command line option -mefpu2 which leads to single-hardware / double-software code generation. [1] Core reference: https://www.nxp.com/files-static/32bit/doc/ref_manual/e200z759CRM.pdf Differential revision: https://reviews.llvm.org/D92935
This commit is contained in:
parent
dd07d60ec3
commit
3f7b4ce960
|
@ -3145,6 +3145,8 @@ PowerPC
|
||||||
|
|
||||||
.. option:: -mdirect-move, -mno-direct-move
|
.. option:: -mdirect-move, -mno-direct-move
|
||||||
|
|
||||||
|
.. option:: -mefpu2
|
||||||
|
|
||||||
.. option:: -mfloat128, -mno-float128
|
.. option:: -mfloat128, -mno-float128
|
||||||
|
|
||||||
.. option:: -mfprnd, -mno-fprnd
|
.. option:: -mfprnd, -mno-fprnd
|
||||||
|
|
|
@ -3040,6 +3040,7 @@ def mpcrel: Flag<["-"], "mpcrel">, Group<m_ppc_Features_Group>;
|
||||||
def mno_pcrel: Flag<["-"], "mno-pcrel">, Group<m_ppc_Features_Group>;
|
def mno_pcrel: Flag<["-"], "mno-pcrel">, Group<m_ppc_Features_Group>;
|
||||||
def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
|
def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
|
||||||
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
|
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
|
||||||
|
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
|
||||||
def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">, Group<m_Group>, Flags<[CC1Option]>,
|
def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">, Group<m_Group>, Flags<[CC1Option]>,
|
||||||
HelpText<"Enable the extended Altivec ABI on AIX (AIX only). Uses volatile and nonvolatile vector registers">;
|
HelpText<"Enable the extended Altivec ABI on AIX (AIX only). Uses volatile and nonvolatile vector registers">;
|
||||||
def mabi_EQ_vec_default : Flag<["-"], "mabi=vec-default">, Group<m_Group>, Flags<[CC1Option]>,
|
def mabi_EQ_vec_default : Flag<["-"], "mabi=vec-default">, Group<m_Group>, Flags<[CC1Option]>,
|
||||||
|
|
|
@ -56,7 +56,7 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||||
HasP10Vector = true;
|
HasP10Vector = true;
|
||||||
} else if (Feature == "+pcrelative-memops") {
|
} else if (Feature == "+pcrelative-memops") {
|
||||||
HasPCRelativeMemops = true;
|
HasPCRelativeMemops = true;
|
||||||
} else if (Feature == "+spe") {
|
} else if (Feature == "+spe" || Feature == "+efpu2") {
|
||||||
HasSPE = true;
|
HasSPE = true;
|
||||||
LongDoubleWidth = LongDoubleAlign = 64;
|
LongDoubleWidth = LongDoubleAlign = 64;
|
||||||
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
|
||||||
|
@ -402,6 +402,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
|
||||||
void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
||||||
StringRef Name, bool Enabled) const {
|
StringRef Name, bool Enabled) const {
|
||||||
if (Enabled) {
|
if (Enabled) {
|
||||||
|
if (Name == "efpu2")
|
||||||
|
Features["spe"] = true;
|
||||||
// If we're enabling any of the vsx based features then enable vsx and
|
// If we're enabling any of the vsx based features then enable vsx and
|
||||||
// altivec. We'll diagnose any problems later.
|
// altivec. We'll diagnose any problems later.
|
||||||
bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
|
bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
|
||||||
|
@ -425,6 +427,8 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
||||||
else
|
else
|
||||||
Features[Name] = true;
|
Features[Name] = true;
|
||||||
} else {
|
} else {
|
||||||
|
if (Name == "spe")
|
||||||
|
Features["efpu2"] = false;
|
||||||
// If we're disabling altivec or vsx go ahead and disable all of the vsx
|
// If we're disabling altivec or vsx go ahead and disable all of the vsx
|
||||||
// features.
|
// features.
|
||||||
if ((Name == "altivec") || (Name == "vsx"))
|
if ((Name == "altivec") || (Name == "vsx"))
|
||||||
|
|
|
@ -155,6 +155,9 @@
|
||||||
// CHECK-SPE: "-target-feature" "+spe"
|
// CHECK-SPE: "-target-feature" "+spe"
|
||||||
// CHECK-NOSPE: "-target-feature" "-spe"
|
// CHECK-NOSPE: "-target-feature" "-spe"
|
||||||
|
|
||||||
|
// RUN: %clang -target powerpc %s -mefpu2 -c -### 2>&1 | FileCheck -check-prefix=CHECK-EFPU2 %s
|
||||||
|
// CHECK-EFPU2: "-target-feature" "+efpu2"
|
||||||
|
|
||||||
// Assembler features
|
// Assembler features
|
||||||
// RUN: %clang -target powerpc-unknown-linux-gnu %s -### -o %t.o -no-integrated-as 2>&1 | FileCheck -check-prefix=CHECK_32_BE_AS_ARGS %s
|
// RUN: %clang -target powerpc-unknown-linux-gnu %s -### -o %t.o -no-integrated-as 2>&1 | FileCheck -check-prefix=CHECK_32_BE_AS_ARGS %s
|
||||||
// CHECK_32_BE_AS_ARGS: "-mppc"
|
// CHECK_32_BE_AS_ARGS: "-mppc"
|
||||||
|
|
|
@ -72,6 +72,9 @@ def FeatureAltivec : SubtargetFeature<"altivec","HasAltivec", "true",
|
||||||
def FeatureSPE : SubtargetFeature<"spe","HasSPE", "true",
|
def FeatureSPE : SubtargetFeature<"spe","HasSPE", "true",
|
||||||
"Enable SPE instructions",
|
"Enable SPE instructions",
|
||||||
[FeatureHardFloat]>;
|
[FeatureHardFloat]>;
|
||||||
|
def FeatureEFPU2 : SubtargetFeature<"efpu2", "HasEFPU2", "true",
|
||||||
|
"Enable Embedded Floating-Point APU 2 instructions",
|
||||||
|
[FeatureSPE]>;
|
||||||
def FeatureMFOCRF : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
|
def FeatureMFOCRF : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
|
||||||
"Enable the MFOCRF instruction">;
|
"Enable the MFOCRF instruction">;
|
||||||
def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true",
|
def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true",
|
||||||
|
|
|
@ -151,6 +151,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
|
||||||
if (!useSoftFloat()) {
|
if (!useSoftFloat()) {
|
||||||
if (hasSPE()) {
|
if (hasSPE()) {
|
||||||
addRegisterClass(MVT::f32, &PPC::GPRCRegClass);
|
addRegisterClass(MVT::f32, &PPC::GPRCRegClass);
|
||||||
|
// EFPU2 APU only supports f32
|
||||||
|
if (!Subtarget.hasEFPU2())
|
||||||
addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
|
addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
|
||||||
} else {
|
} else {
|
||||||
addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
|
addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
|
||||||
|
|
|
@ -77,6 +77,7 @@ void PPCSubtarget::initializeEnvironment() {
|
||||||
HasHardFloat = false;
|
HasHardFloat = false;
|
||||||
HasAltivec = false;
|
HasAltivec = false;
|
||||||
HasSPE = false;
|
HasSPE = false;
|
||||||
|
HasEFPU2 = false;
|
||||||
HasFPU = false;
|
HasFPU = false;
|
||||||
HasVSX = false;
|
HasVSX = false;
|
||||||
NeedsTwoConstNR = false;
|
NeedsTwoConstNR = false;
|
||||||
|
|
|
@ -100,6 +100,7 @@ protected:
|
||||||
bool HasAltivec;
|
bool HasAltivec;
|
||||||
bool HasFPU;
|
bool HasFPU;
|
||||||
bool HasSPE;
|
bool HasSPE;
|
||||||
|
bool HasEFPU2;
|
||||||
bool HasVSX;
|
bool HasVSX;
|
||||||
bool NeedsTwoConstNR;
|
bool NeedsTwoConstNR;
|
||||||
bool HasP8Vector;
|
bool HasP8Vector;
|
||||||
|
@ -257,6 +258,7 @@ public:
|
||||||
bool hasFPCVT() const { return HasFPCVT; }
|
bool hasFPCVT() const { return HasFPCVT; }
|
||||||
bool hasAltivec() const { return HasAltivec; }
|
bool hasAltivec() const { return HasAltivec; }
|
||||||
bool hasSPE() const { return HasSPE; }
|
bool hasSPE() const { return HasSPE; }
|
||||||
|
bool hasEFPU2() const { return HasEFPU2; }
|
||||||
bool hasFPU() const { return HasFPU; }
|
bool hasFPU() const { return HasFPU; }
|
||||||
bool hasVSX() const { return HasVSX; }
|
bool hasVSX() const { return HasVSX; }
|
||||||
bool needsTwoConstNR() const { return NeedsTwoConstNR; }
|
bool needsTwoConstNR() const { return NeedsTwoConstNR; }
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue