Partially revert r111155. It looks like MSVC is calling an operator<() that
[oota-llvm.git] / lib / Target / X86 / X86FloatingPoint.cpp
index a8275e660b53cf260e15f791805316fd04862d6b..4bf7cdbdbeedc4cd13f8d9d26cd147a1717e9823 100644 (file)
@@ -50,7 +50,12 @@ STATISTIC(NumFP  , "Number of floating point instructions");
 namespace {
   struct FPS : public MachineFunctionPass {
     static char ID;
-    FPS() : MachineFunctionPass(&ID) {}
+    FPS() : MachineFunctionPass(ID) {
+      // This is really only to keep valgrind quiet.
+      // The logic in isLive() is too much for it.
+      memset(Stack, 0, sizeof(Stack));
+      memset(RegMap, 0, sizeof(RegMap));
+    }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
@@ -139,32 +144,35 @@ namespace {
       dbgs() << "\n";
     }
 
-    /// isStackEmpty - Return true if the FP stack is empty.
-    bool isStackEmpty() const {
-      return StackTop == 0;
-    }
-
-    // getSlot - Return the stack slot number a particular register number is
-    // in.
+    /// getSlot - Return the stack slot number a particular register number is
+    /// in.
     unsigned getSlot(unsigned RegNo) const {
       assert(RegNo < 8 && "Regno out of range!");
       return RegMap[RegNo];
     }
 
-    // isLive - Is RegNo currently live in the stack?
+    /// isLive - Is RegNo currently live in the stack?
     bool isLive(unsigned RegNo) const {
       unsigned Slot = getSlot(RegNo);
       return Slot < StackTop && Stack[Slot] == RegNo;
     }
 
-    // getStackEntry - Return the X86::FP<n> register in register ST(i).
+    /// getScratchReg - Return an FP register that is not currently in use.
+    unsigned getScratchReg() {
+      for (int i = 7; i >= 0; --i)
+        if (!isLive(i))
+          return i;
+      llvm_unreachable("Ran out of scratch FP registers");
+    }
+
+    /// getStackEntry - Return the X86::FP<n> register in register ST(i).
     unsigned getStackEntry(unsigned STi) const {
       assert(STi < StackTop && "Access past stack top!");
       return Stack[StackTop-1-STi];
     }
 
-    // getSTReg - Return the X86::ST(i) register which contains the specified
-    // FP<RegNo> register.
+    /// getSTReg - Return the X86::ST(i) register which contains the specified
+    /// FP<RegNo> register.
     unsigned getSTReg(unsigned RegNo) const {
       return StackTop - 1 - getSlot(RegNo) + llvm::X86::ST0;
     }
@@ -205,27 +213,27 @@ namespace {
       BuildMI(*MBB, I, dl, TII->get(X86::LD_Frr)).addReg(STReg);
     }
 
-    // popStackAfter - Pop the current value off of the top of the FP stack
-    // after the specified instruction.
+    /// popStackAfter - Pop the current value off of the top of the FP stack
+    /// after the specified instruction.
     void popStackAfter(MachineBasicBlock::iterator &I);
 
-    // freeStackSlotAfter - Free the specified register from the register stack,
-    // so that it is no longer in a register.  If the register is currently at
-    // the top of the stack, we just pop the current instruction, otherwise we
-    // store the current top-of-stack into the specified slot, then pop the top
-    // of stack.
+    /// freeStackSlotAfter - Free the specified register from the register
+    /// stack, so that it is no longer in a register.  If the register is
+    /// currently at the top of the stack, we just pop the current instruction,
+    /// otherwise we store the current top-of-stack into the specified slot,
+    /// then pop the top of stack.
     void freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned Reg);
 
-    // freeStackSlotBefore - Just the pop, no folding. Return the inserted
-    // instruction.
+    /// freeStackSlotBefore - Just the pop, no folding. Return the inserted
+    /// instruction.
     MachineBasicBlock::iterator
     freeStackSlotBefore(MachineBasicBlock::iterator I, unsigned FPRegNo);
 
-    // Adjust the live registers to be the set in Mask.
+    /// Adjust the live registers to be the set in Mask.
     void adjustLiveRegs(unsigned Mask, MachineBasicBlock::iterator I);
 
-    // Shuffle the top FixCount stack entries susch that FP reg FixStack[0] is
-    //st(0), FP reg FixStack[1] is st(1) etc.
+    /// Shuffle the top FixCount stack entries susch that FP reg FixStack[0] is
+    //st(0), FP reg FixStack[1] is st(1) etc.
     void shuffleStackTop(const unsigned char *FixStack, unsigned FixCount,
                          MachineBasicBlock::iterator I);
 
@@ -994,7 +1002,7 @@ void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {
        MI->getOpcode() == X86::ISTT_Fp32m80 ||
        MI->getOpcode() == X86::ISTT_Fp64m80 ||
        MI->getOpcode() == X86::ST_FpP80m)) {
-    duplicateToTop(Reg, 7 /*temp register*/, I);
+    duplicateToTop(Reg, getScratchReg(), I);
   } else {
     moveToTop(Reg, I);            // Move to the top of the stack...
   }
@@ -1347,8 +1355,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
 
     if (!MI->killsRegister(X86::FP0 + Op0)) {
       // Duplicate Op0 into a temporary on the stack top.
-      // This actually assumes that FP7 is dead.
-      duplicateToTop(Op0, 7, I);
+      duplicateToTop(Op0, getScratchReg(), I);
     } else {
       // Op0 is killed, so just swap it into position.
       moveToTop(Op0, I);
@@ -1368,8 +1375,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
     ++StackTop;
     unsigned RegOnTop = getStackEntry(0); // This reg must remain in st(0).
     if (!MI->killsRegister(X86::FP0 + Op0)) {
-      // Assume FP6 is not live, use it as a scratch register.
-      duplicateToTop(Op0, 6, I);
+      duplicateToTop(Op0, getScratchReg(), I);
       moveToTop(RegOnTop, I);
     } else if (getSTReg(Op0) != X86::ST1) {
       // We have the wrong value at st(1). Shuffle! Untested!
@@ -1513,7 +1519,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
       
       // Duplicate the TOS so that we return it twice.  Just pick some other FPx
       // register to hold it.
-      unsigned NewReg = (FirstFPRegOp+1)%7;
+      unsigned NewReg = getScratchReg();
       duplicateToTop(FirstFPRegOp, NewReg, MI);
       FirstFPRegOp = NewReg;
     }