def Feature64Bit : SubtargetFeature<"64bit","Has64BitSupport", "true",
"Enable 64-bit instructions">;
+def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
+ "Use software emulation for floating point">;
def Feature64BitRegs : SubtargetFeature<"64bitregs","Use64BitRegs", "true",
"Enable 64-bit registers usage for ppc32 [beta]">;
def FeatureCRBits : SubtargetFeature<"crbits", "UseCRBits", "true",
using namespace llvm;
-// FIXME: Remove this once soft-float is supported.
-static cl::opt<bool> DisablePPCFloatInVariadic("disable-ppc-float-in-variadic",
-cl::desc("disable saving float registers for va_start on PPC"), cl::Hidden);
-
static cl::opt<bool> DisablePPCPreinc("disable-ppc-preinc",
cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden);
// Set up the register classes.
addRegisterClass(MVT::i32, &PPC::GPRCRegClass);
- addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
- addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
+ if (!Subtarget.useSoftFloat()) {
+ addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
+ addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
+ }
// PowerPC has an i16 but no i8 (or i1) SEXTLOAD
for (MVT VT : MVT::integer_valuetypes()) {
return Align;
}
+bool PPCTargetLowering::useSoftFloat() const {
+ return Subtarget.useSoftFloat();
+}
+
const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch ((PPCISD::NodeType)Opcode) {
case PPCISD::FIRST_NUMBER: break;
PPC::F8
};
unsigned NumFPArgRegs = array_lengthof(FPArgRegs);
- if (DisablePPCFloatInVariadic)
- NumFPArgRegs = 0;
+
+ if (Subtarget.useSoftFloat())
+ NumFPArgRegs = 0;
FuncInfo->setVarArgsNumGPR(CCInfo.getFirstUnallocated(GPArgRegs));
FuncInfo->setVarArgsNumFPR(CCInfo.getFirstUnallocated(FPArgRegs));
/// DAG node.
const char *getTargetNodeName(unsigned Opcode) const override;
+ bool useSoftFloat() const override;
+
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
return MVT::i32;
}
Has64BitSupport = false;
Use64BitRegs = false;
UseCRBits = false;
+ UseSoftFloat = false;
HasAltivec = false;
HasSPE = false;
HasQPX = false;
bool Has64BitSupport;
bool Use64BitRegs;
bool UseCRBits;
+ bool UseSoftFloat;
bool IsPPC64;
bool HasAltivec;
bool HasSPE;
/// has64BitSupport - Return true if the selected CPU supports 64-bit
/// instructions, regardless of whether we are in 32-bit or 64-bit mode.
bool has64BitSupport() const { return Has64BitSupport; }
+ // useSoftFloat - Return true if soft-float option is turned on.
+ bool useSoftFloat() const { return UseSoftFloat; }
/// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit
/// registers in 32-bit mode when possible. This can only true if
? FSAttr.getValueAsString().str()
: TargetFS;
+ // FIXME: This is related to the code below to reset the target options,
+ // we need to know whether or not the soft float flag is set on the
+ // function before we can generate a subtarget. We also need to use
+ // it as a key for the subtarget since that can be the only difference
+ // between two functions.
+ bool SoftFloat =
+ F.hasFnAttribute("use-soft-float") &&
+ F.getFnAttribute("use-soft-float").getValueAsString() == "true";
+ // If the soft float attribute is set on the function turn on the soft float
+ // subtarget feature.
+ if (SoftFloat)
+ FS += FS.empty() ? "+soft-float" : ",+soft-float";
+
auto &I = SubtargetMap[CPU + FS];
if (!I) {
// This needs to be done before we create a new subtarget since any
--- /dev/null
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu -O0 < %s | FileCheck %s
+define double @foo() #0 {
+entry:
+ %a = alloca double, align 8
+ %b = alloca double, align 8
+ %0 = load double, double* %a, align 8
+ %1 = load double, double* %b, align 8
+ %add = fadd double %0, %1
+ ret double %add
+
+ ; CHECK-LABEL: __adddf3
+}
+
+define double @foo1() #0 {
+entry:
+ %a = alloca double, align 8
+ %b = alloca double, align 8
+ %0 = load double, double* %a, align 8
+ %1 = load double, double* %b, align 8
+ %mul = fmul double %0, %1
+ ret double %mul
+
+ ; CHECK-LABEL: __muldf3
+}
+
+define double @foo2() #0 {
+entry:
+ %a = alloca double, align 8
+ %b = alloca double, align 8
+ %0 = load double, double* %a, align 8
+ %1 = load double, double* %b, align 8
+ %sub = fsub double %0, %1
+ ret double %sub
+
+ ; CHECK-LABEL: __subdf3
+}
+
+define double @foo3() #0 {
+entry:
+ %a = alloca double, align 8
+ %b = alloca double, align 8
+ %0 = load double, double* %a, align 8
+ %1 = load double, double* %b, align 8
+ %div = fdiv double %0, %1
+ ret double %div
+
+ ; CHECK-LABEL: __divdf3
+}
+
+attributes #0 = {"use-soft-float"="true" }