Index: llvm/trunk/lib/Target/PowerPC/PPC.td =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPC.td +++ llvm/trunk/lib/Target/PowerPC/PPC.td @@ -50,6 +50,8 @@ 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", Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h @@ -428,6 +428,8 @@ /// DAG node. const char *getTargetNodeName(unsigned Opcode) const override; + bool useSoftFloat() const override; + MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { return MVT::i32; } Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -42,10 +42,6 @@ using namespace llvm; -// FIXME: Remove this once soft-float is supported. -static cl::opt DisablePPCFloatInVariadic("disable-ppc-float-in-variadic", -cl::desc("disable saving float registers for va_start on PPC"), cl::Hidden); - static cl::opt DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden); @@ -72,8 +68,10 @@ // 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()) { @@ -979,6 +977,10 @@ 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; @@ -2945,8 +2947,9 @@ 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)); Index: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h @@ -83,6 +83,7 @@ bool Has64BitSupport; bool Use64BitRegs; bool UseCRBits; + bool UseSoftFloat; bool IsPPC64; bool HasAltivec; bool HasSPE; @@ -189,6 +190,8 @@ /// 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 Index: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp @@ -62,6 +62,7 @@ Has64BitSupport = false; Use64BitRegs = false; UseCRBits = false; + UseSoftFloat = false; HasAltivec = false; HasSPE = false; HasQPX = false; Index: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -239,6 +239,19 @@ ? 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 Index: llvm/trunk/test/CodeGen/PowerPC/ppcsoftops.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppcsoftops.ll +++ llvm/trunk/test/CodeGen/PowerPC/ppcsoftops.ll @@ -0,0 +1,50 @@ +; 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" }