Teach the x86 floating point stackifier to handle COPY instructions.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 8 Jul 2010 19:46:30 +0000 (19:46 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 8 Jul 2010 19:46:30 +0000 (19:46 +0000)
This pass runs before COPY instructions are passed to copyPhysReg, so we simply
translate COPY to the proper pseudo instruction. Note that copyPhysReg does not
handle floating point stack copies.

Once COPY is used everywhere, this can be cleaned up a bit, and most of the
pseudo instructions can be removed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107899 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FloatingPoint.cpp

index b5c6aa6b9c77628591cc4f3c43e4659040658cf2..0e135f3a49622eed0c5d82baf92370813ed1e4fd 100644 (file)
@@ -164,6 +164,8 @@ namespace {
     void handleCompareFP(MachineBasicBlock::iterator &I);
     void handleCondMovFP(MachineBasicBlock::iterator &I);
     void handleSpecialFP(MachineBasicBlock::iterator &I);
+
+    bool translateCopy(MachineInstr*);
   };
   char FPS::ID = 0;
 }
@@ -237,7 +239,10 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
     unsigned FPInstClass = Flags & X86II::FPTypeMask;
     if (MI->isInlineAsm())
       FPInstClass = X86II::SpecialFP;
-    
+
+    if (MI->isCopy() && translateCopy(MI))
+      FPInstClass = X86II::SpecialFP;
+
     if (FPInstClass == X86II::NotFP)
       continue;  // Efficiently ignore non-fp insts!
 
@@ -1206,3 +1211,33 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
   I = MBB->erase(I);  // Remove the pseudo instruction
   --I;
 }
+
+// Translate a COPY instruction to a pseudo-op that handleSpecialFP understands.
+bool FPS::translateCopy(MachineInstr *MI) {
+  unsigned DstReg = MI->getOperand(0).getReg();
+  unsigned SrcReg = MI->getOperand(1).getReg();
+
+  if (DstReg == X86::ST0) {
+    MI->setDesc(TII->get(X86::FpSET_ST0_80));
+    MI->RemoveOperand(0);
+    return true;
+  }
+  if (DstReg == X86::ST1) {
+    MI->setDesc(TII->get(X86::FpSET_ST1_80));
+    MI->RemoveOperand(0);
+    return true;
+  }
+  if (SrcReg == X86::ST0) {
+    MI->setDesc(TII->get(X86::FpGET_ST0_80));
+    return true;
+  }
+  if (SrcReg == X86::ST1) {
+    MI->setDesc(TII->get(X86::FpGET_ST1_80));
+    return true;
+  }
+  if (X86::RFP80RegClass.contains(DstReg, SrcReg)) {
+    MI->setDesc(TII->get(X86::MOV_Fp8080));
+    return true;
+  }
+  return false;
+}