[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:
Nemanja Ivanovic 2021-01-12 09:46:11 -06:00
parent dd07d60ec3
commit 3f7b4ce960
9 changed files with 1352 additions and 730 deletions

View File

@ -3145,6 +3145,8 @@ PowerPC
.. option:: -mdirect-move, -mno-direct-move
.. option:: -mefpu2
.. option:: -mfloat128, -mno-float128
.. option:: -mfprnd, -mno-fprnd

View File

@ -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 mspe : Flag<["-"], "mspe">, 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]>,
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]>,

View File

@ -56,7 +56,7 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasP10Vector = true;
} else if (Feature == "+pcrelative-memops") {
HasPCRelativeMemops = true;
} else if (Feature == "+spe") {
} else if (Feature == "+spe" || Feature == "+efpu2") {
HasSPE = true;
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
@ -402,6 +402,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
StringRef Name, bool Enabled) const {
if (Enabled) {
if (Name == "efpu2")
Features["spe"] = true;
// If we're enabling any of the vsx based features then enable vsx and
// altivec. We'll diagnose any problems later.
bool FeatureHasVSX = llvm::StringSwitch<bool>(Name)
@ -425,6 +427,8 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
else
Features[Name] = true;
} else {
if (Name == "spe")
Features["efpu2"] = false;
// If we're disabling altivec or vsx go ahead and disable all of the vsx
// features.
if ((Name == "altivec") || (Name == "vsx"))

View File

@ -155,6 +155,9 @@
// CHECK-SPE: "-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
// 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"

View File

@ -72,6 +72,9 @@ def FeatureAltivec : SubtargetFeature<"altivec","HasAltivec", "true",
def FeatureSPE : SubtargetFeature<"spe","HasSPE", "true",
"Enable SPE instructions",
[FeatureHardFloat]>;
def FeatureEFPU2 : SubtargetFeature<"efpu2", "HasEFPU2", "true",
"Enable Embedded Floating-Point APU 2 instructions",
[FeatureSPE]>;
def FeatureMFOCRF : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
"Enable the MFOCRF instruction">;
def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true",

View File

@ -151,7 +151,9 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
if (!useSoftFloat()) {
if (hasSPE()) {
addRegisterClass(MVT::f32, &PPC::GPRCRegClass);
addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
// EFPU2 APU only supports f32
if (!Subtarget.hasEFPU2())
addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
} else {
addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
addRegisterClass(MVT::f64, &PPC::F8RCRegClass);

View File

@ -77,6 +77,7 @@ void PPCSubtarget::initializeEnvironment() {
HasHardFloat = false;
HasAltivec = false;
HasSPE = false;
HasEFPU2 = false;
HasFPU = false;
HasVSX = false;
NeedsTwoConstNR = false;

View File

@ -100,6 +100,7 @@ protected:
bool HasAltivec;
bool HasFPU;
bool HasSPE;
bool HasEFPU2;
bool HasVSX;
bool NeedsTwoConstNR;
bool HasP8Vector;
@ -257,6 +258,7 @@ public:
bool hasFPCVT() const { return HasFPCVT; }
bool hasAltivec() const { return HasAltivec; }
bool hasSPE() const { return HasSPE; }
bool hasEFPU2() const { return HasEFPU2; }
bool hasFPU() const { return HasFPU; }
bool hasVSX() const { return HasVSX; }
bool needsTwoConstNR() const { return NeedsTwoConstNR; }

File diff suppressed because it is too large Load Diff