diff options
Diffstat (limited to 'lib/Target/X86/X86FloatingPoint.cpp')
| -rw-r--r-- | lib/Target/X86/X86FloatingPoint.cpp | 34 | 
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 6eed6abd43e2..e3461c82c7a6 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -260,6 +260,21 @@ namespace {        BuildMI(*MBB, I, dl, TII->get(X86::LD_Frr)).addReg(STReg);      } +    /// duplicatePendingSTBeforeKill - The instruction at I is about to kill +    /// RegNo. If any PendingST registers still need the RegNo value, duplicate +    /// them to new scratch registers. +    void duplicatePendingSTBeforeKill(unsigned RegNo, MachineInstr *I) { +      for (unsigned i = 0; i != NumPendingSTs; ++i) { +        if (PendingST[i] != RegNo) +          continue; +        unsigned SR = getScratchReg(); +        DEBUG(dbgs() << "Duplicating pending ST" << i +                     << " in FP" << RegNo << " to FP" << SR << '\n'); +        duplicateToTop(RegNo, SR, I); +        PendingST[i] = SR; +      } +    } +      /// popStackAfter - Pop the current value off of the top of the FP stack      /// after the specified instruction.      void popStackAfter(MachineBasicBlock::iterator &I); @@ -406,6 +421,10 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {      if (MI->isCopy() && isFPCopy(MI))        FPInstClass = X86II::SpecialFP; +    if (MI->isImplicitDef() && +        X86::RFP80RegClass.contains(MI->getOperand(0).getReg())) +      FPInstClass = X86II::SpecialFP; +      if (FPInstClass == X86II::NotFP)        continue;  // Efficiently ignore non-fp insts! @@ -461,6 +480,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {        }        dumpStack();      ); +    (void)PrevMI;      Changed = true;    } @@ -969,6 +989,9 @@ void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {    unsigned Reg = getFPReg(MI->getOperand(NumOps-1));    bool KillsSrc = MI->killsRegister(X86::FP0+Reg); +  if (KillsSrc) +    duplicatePendingSTBeforeKill(Reg, I); +    // FISTP64m is strange because there isn't a non-popping versions.    // If we have one _and_ we don't want to pop the operand, duplicate the value    // on the stack instead of moving it.  This ensure that popping the value is @@ -1032,6 +1055,7 @@ void FPS::handleOneArgFPRW(MachineBasicBlock::iterator &I) {    bool KillsSrc = MI->killsRegister(X86::FP0+Reg);    if (KillsSrc) { +    duplicatePendingSTBeforeKill(Reg, I);      // If this is the last use of the source register, just make sure it's on      // the top of the stack.      moveToTop(Reg, I); @@ -1318,6 +1342,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {        // When the source is killed, allocate a scratch FP register.        if (KillsSrc) { +        duplicatePendingSTBeforeKill(SrcFP, I);          unsigned Slot = getSlot(SrcFP);          unsigned SR = getScratchReg();          PendingST[DstST] = SR; @@ -1369,6 +1394,15 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {      break;    } +  case TargetOpcode::IMPLICIT_DEF: { +    // All FP registers must be explicitly defined, so load a 0 instead. +    unsigned Reg = MI->getOperand(0).getReg() - X86::FP0; +    DEBUG(dbgs() << "Emitting LD_F0 for implicit FP" << Reg << '\n'); +    BuildMI(*MBB, I, MI->getDebugLoc(), TII->get(X86::LD_F0)); +    pushReg(Reg); +    break; +  } +    case X86::FpPOP_RETVAL: {      // The FpPOP_RETVAL instruction is used after calls that return a value on      // the floating point stack. We cannot model this with ST defs since CALL  | 
