OSDN Git Service

Rewrite FP stackifier support in the X86InstrInfo.td file, splitting patterns
authorChris Lattner <sabre@nondot.org>
Wed, 21 Dec 2005 07:47:04 +0000 (07:47 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 21 Dec 2005 07:47:04 +0000 (07:47 +0000)
that were overloaded to work before and after the stackifier runs.  With the
new clean world, it is possible to write patterns for these instructions: woo!

This also adds a few simple patterns here and there, though there are a lot
still missing.  These should be easy to add though. :)

See the comments under "Floating Point Stack Support" for more details on
the new world order.

This patch as absolutely no effect on the generated code, woo!

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

lib/Target/X86/X86FloatingPoint.cpp
lib/Target/X86/X86ISelPattern.cpp
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86RegisterInfo.cpp

index 58568c3..4ac574f 100644 (file)
@@ -311,6 +311,63 @@ static int Lookup(const TableEntry *Table, unsigned N, unsigned Opcode) {
   }
 #endif
 
+//===----------------------------------------------------------------------===//
+// Register File -> Register Stack Mapping Methods
+//===----------------------------------------------------------------------===//
+
+// OpcodeTable - Sorted map of register instructions to their stack version.
+// The first element is an register file pseudo instruction, the second is the
+// concrete X86 instruction which uses the register stack.
+//
+static const TableEntry OpcodeTable[] = {
+  { X86::FpABS    , X86::FABS     },
+  { X86::FpADD32m , X86::FADD32m  },
+  { X86::FpADD64m , X86::FADD64m  },
+  { X86::FpCHS    , X86::FCHS     },
+  { X86::FpCMOVA  , X86::FCMOVA   },
+  { X86::FpCMOVAE , X86::FCMOVAE  },
+  { X86::FpCMOVB  , X86::FCMOVB   },
+  { X86::FpCMOVBE , X86::FCMOVBE  },
+  { X86::FpCMOVE  , X86::FCMOVE   },
+  { X86::FpCMOVNE , X86::FCMOVNE  },
+  { X86::FpCMOVNP , X86::FCMOVNP  },
+  { X86::FpCMOVP  , X86::FCMOVP   },
+  { X86::FpCOS    , X86::FCOS     },
+  { X86::FpDIV32m , X86::FDIV32m  },
+  { X86::FpDIV64m , X86::FDIV64m  },
+  { X86::FpDIVR32m, X86::FDIVR32m },
+  { X86::FpDIVR64m, X86::FDIVR64m },
+  { X86::FpILD16m , X86::FILD16m  },
+  { X86::FpILD32m , X86::FILD32m  },
+  { X86::FpILD64m , X86::FILD64m  },
+  { X86::FpIST16m , X86::FIST16m  },
+  { X86::FpIST32m , X86::FIST32m  },
+  { X86::FpIST64m , X86::FISTP64m },
+  { X86::FpLD0    , X86::FLD0     },
+  { X86::FpLD1    , X86::FLD1     },
+  { X86::FpLD32m  , X86::FLD32m   },
+  { X86::FpLD64m  , X86::FLD64m   },
+  { X86::FpMUL32m , X86::FMUL32m  },
+  { X86::FpMUL64m , X86::FMUL64m  },
+  { X86::FpSIN    , X86::FSIN     },
+  { X86::FpSQRT   , X86::FSQRT    },
+  { X86::FpST32m  , X86::FST32m   },
+  { X86::FpST64m  , X86::FST64m   },
+  { X86::FpSUB32m , X86::FSUB32m  },
+  { X86::FpSUB64m , X86::FSUB64m  },
+  { X86::FpSUBR32m, X86::FSUBR32m },
+  { X86::FpSUBR64m, X86::FSUBR64m },
+  { X86::FpTST    , X86::FTST     },
+  { X86::FpUCOMIr , X86::FUCOMIr  },
+  { X86::FpUCOMr  , X86::FUCOMr   },
+};
+
+static unsigned getConcreteOpcode(unsigned Opcode) {
+  ASSERT_SORTED(OpcodeTable);
+  int Opc = Lookup(OpcodeTable, ARRAY_SIZE(OpcodeTable), Opcode);
+  assert(Opc != -1 && "FP Stack instruction not in OpcodeTable!");
+  return Opc;
+}
 
 //===----------------------------------------------------------------------===//
 // Helper Methods
@@ -407,9 +464,12 @@ static unsigned getFPReg(const MachineOperand &MO) {
 void FPS::handleZeroArgFP(MachineBasicBlock::iterator &I) {
   MachineInstr *MI = I;
   unsigned DestReg = getFPReg(MI->getOperand(0));
-  MI->RemoveOperand(0);   // Remove the explicit ST(0) operand
 
-  // Result gets pushed on the stack...
+  // Change from the pseudo instruction to the concrete instruction.
+  MI->RemoveOperand(0);   // Remove the explicit ST(0) operand
+  MI->setOpcode(getConcreteOpcode(MI->getOpcode()));
+  
+  // Result gets pushed on the stack.
   pushReg(DestReg);
 }
 
@@ -424,20 +484,22 @@ void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {
   unsigned Reg = getFPReg(MI->getOperand(MI->getNumOperands()-1));
   bool KillsSrc = LV->KillsRegister(MI, X86::FP0+Reg);
 
-  // FSTP80r and FISTP64r are strange because there are no non-popping versions.
+  // FISTP64r 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
   // always ok.
   //
-  if ((MI->getOpcode() == X86::FSTP80m ||
-       MI->getOpcode() == X86::FISTP64m) && !KillsSrc) {
+  if (MI->getOpcode() == X86::FpIST64m && !KillsSrc) {
     duplicateToTop(Reg, 7 /*temp register*/, I);
   } else {
     moveToTop(Reg, I);            // Move to the top of the stack...
   }
+  
+  // Convert from the pseudo instruction to the concrete instruction.
   MI->RemoveOperand(MI->getNumOperands()-1);    // Remove explicit ST(0) operand
+  MI->setOpcode(getConcreteOpcode(MI->getOpcode()));
 
-  if (MI->getOpcode() == X86::FSTP80m || MI->getOpcode() == X86::FISTP64m) {
+  if (MI->getOpcode() == X86::FISTP64m) {
     assert(StackTop > 0 && "Stack empty??");
     --StackTop;
   } else if (KillsSrc) { // Last use of operand?
@@ -475,8 +537,10 @@ void FPS::handleOneArgFPRW(MachineBasicBlock::iterator &I) {
     duplicateToTop(Reg, getFPReg(MI->getOperand(0)), I);
   }
 
+  // Change from the pseudo instruction to the concrete instruction.
   MI->RemoveOperand(1);   // Drop the source operand.
   MI->RemoveOperand(0);   // Drop the destination operand.
+  MI->setOpcode(getConcreteOpcode(MI->getOpcode()));
 }
 
 
@@ -638,8 +702,10 @@ void FPS::handleCompareFP(MachineBasicBlock::iterator &I) {
   // anywhere.
   moveToTop(Op0, I);
 
+  // Change from the pseudo instruction to the concrete instruction.
   MI->getOperand(0).setReg(getSTReg(Op1));
   MI->RemoveOperand(1);
+  MI->setOpcode(getConcreteOpcode(MI->getOpcode()));
 
   // If any of the operands are killed by this instruction, free them.
   if (KillsOp0) freeStackSlotAfter(I, Op0);
@@ -660,9 +726,12 @@ void FPS::handleCondMovFP(MachineBasicBlock::iterator &I) {
   moveToTop(Op0, I);
 
   // Change the second operand to the stack register that the operand is in.
+  // Change from the pseudo instruction to the concrete instruction.
   MI->RemoveOperand(0);
   MI->getOperand(0).setReg(getSTReg(Op1));
-
+  MI->setOpcode(getConcreteOpcode(MI->getOpcode()));
+  
+  
   // If we kill the second operand, make sure to pop it from the stack.
   if (Op0 != Op1 && LV->KillsRegister(MI, X86::FP0+Op1)) {
     // Get this value off of the register stack.
index 9f3bb81..9ce406b 100644 (file)
@@ -757,9 +757,9 @@ void ISel::EmitSelectCC(SDOperand Cond, SDOperand True, SDOperand False,
     X86::CMOVA32rr,  X86::CMOVAE32rr, X86::CMOVP32rr,  X86::CMOVNP32rr,
   };
   static const unsigned CMOVTABFP[] = {
-    X86::FCMOVE ,  X86::FCMOVNE, /*missing*/0, /*missing*/0,
-    /*missing*/0,  /*missing*/0, X86::FCMOVB , X86::FCMOVBE,
-    X86::FCMOVA ,  X86::FCMOVAE, X86::FCMOVP , X86::FCMOVNP
+    X86::FpCMOVE,  X86::FpCMOVNE, /*missing*/0, /*missing*/0,
+    /*missing*/0,  /*missing*/ 0, X86::FpCMOVB, X86::FpCMOVBE,
+    X86::FpCMOVA,  X86::FpCMOVAE, X86::FpCMOVP, X86::FpCMOVNP
   };
   static const int SSE_CMOVTAB[] = {
     /*CMPEQ*/   0, /*CMPNEQ*/   4, /*missing*/  0, /*missing*/  0,
@@ -944,7 +944,7 @@ void ISel::EmitSelectCC(SDOperand Cond, SDOperand True, SDOperand False,
     default: assert(0 && "Cannot select this type!");
     case MVT::i16: Opc = X86::CMOVE16rr; break;
     case MVT::i32: Opc = X86::CMOVE32rr; break;
-    case MVT::f64: Opc = X86::FCMOVE; break;
+    case MVT::f64: Opc = X86::FpCMOVE; break;
     }
   } else {
     // FIXME: CMP R, 0 -> TEST R, R
@@ -990,7 +990,7 @@ void ISel::EmitCMP(SDOperand LHS, SDOperand RHS, bool HasOneUse) {
     if (!X86ScalarSSE && (CN->isExactlyValue(+0.0) ||
                           CN->isExactlyValue(-0.0))) {
       unsigned Reg = SelectExpr(LHS);
-      BuildMI(BB, X86::FTST, 1).addReg(Reg);
+      BuildMI(BB, X86::FpTST, 1).addReg(Reg);
       BuildMI(BB, X86::FNSTSW8r, 0);
       BuildMI(BB, X86::SAHF, 1);
       return;
@@ -1022,7 +1022,7 @@ void ISel::EmitCMP(SDOperand LHS, SDOperand RHS, bool HasOneUse) {
   case MVT::i16: Opc = X86::CMP16rr; break;
   case MVT::i32: Opc = X86::CMP32rr; break;
   case MVT::f32: Opc = X86::UCOMISSrr; break;
-  case MVT::f64: Opc = X86ScalarSSE ? X86::UCOMISDrr : X86::FUCOMIr; break;
+  case MVT::f64: Opc = X86ScalarSSE ? X86::UCOMISDrr : X86::FpUCOMIr; break;
   }
   unsigned Tmp1, Tmp2;
   if (getRegPressure(LHS) > getRegPressure(RHS)) {
@@ -1325,14 +1325,14 @@ unsigned ISel::SelectExpr(SDOperand N) {
 
     if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0) ||
         cast<ConstantFPSDNode>(N)->isExactlyValue(-0.0))
-      BuildMI(BB, X86::FLD0, 0, Tmp1);
+      BuildMI(BB, X86::FpLD0, 0, Tmp1);
     else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0) ||
              cast<ConstantFPSDNode>(N)->isExactlyValue(-1.0))
-      BuildMI(BB, X86::FLD1, 0, Tmp1);
+      BuildMI(BB, X86::FpLD1, 0, Tmp1);
     else
       assert(0 && "Unexpected constant!");
     if (Tmp1 != Result)
-      BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1);
+      BuildMI(BB, X86::FpCHS, 1, Result).addReg(Tmp1);
     return Result;
   case ISD::Constant:
     switch (N.getValueType()) {
@@ -1347,7 +1347,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
   case ISD::UNDEF:
     if (Node->getValueType(0) == MVT::f64) {
       // FIXME: SHOULD TEACH STACKIFIER ABOUT UNDEF VALUES!
-      BuildMI(BB, X86::FLD0, 0, Result);
+      BuildMI(BB, X86::FpLD0, 0, Result);
     } else {
       BuildMI(BB, X86::IMPLICIT_DEF, 0, Result);
     }
@@ -1471,11 +1471,11 @@ unsigned ISel::SelectExpr(SDOperand N) {
     switch (SrcTy) {
     case MVT::i32:
       addFrameReference(BuildMI(BB, X86::MOV32mr, 5), FrameIdx).addReg(Tmp1);
-      addFrameReference(BuildMI(BB, X86::FILD32m, 5, Result), FrameIdx);
+      addFrameReference(BuildMI(BB, X86::FpILD32m, 5, Result), FrameIdx);
       break;
     case MVT::i16:
       addFrameReference(BuildMI(BB, X86::MOV16mr, 5), FrameIdx).addReg(Tmp1);
-      addFrameReference(BuildMI(BB, X86::FILD16m, 5, Result), FrameIdx);
+      addFrameReference(BuildMI(BB, X86::FpILD16m, 5, Result), FrameIdx);
       break;
     default: break; // No promotion required.
     }
@@ -1523,7 +1523,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
           assert(Op1.getOpcode() == ISD::LOAD && "SSE load not promoted");
           Opc = X86::ADDSDrm;
         } else {
-          Opc = Op1.getOpcode() == ISD::LOAD ? X86::FADD64m : X86::FADD32m;
+          Opc = Op1.getOpcode() == ISD::LOAD ? X86::FpADD64m : X86::FpADD32m;
         }
         break;
       }
@@ -1616,7 +1616,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
       Opc = (N.getValueType() == MVT::f32) ? X86::SQRTSSrr : X86::SQRTSDrr;
       BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
     } else {
-      BuildMI(BB, X86::FSQRT, 1, Result).addReg(Tmp1);
+      BuildMI(BB, X86::FpSQRT, 1, Result).addReg(Tmp1);
     }
     return Result;
 
@@ -1631,10 +1631,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
     Tmp1 = SelectExpr(Node->getOperand(0));
     switch (N.getOpcode()) {
     default: assert(0 && "Unreachable!");
-    case ISD::FABS: BuildMI(BB, X86::FABS, 1, Result).addReg(Tmp1); break;
-    case ISD::FNEG: BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1); break;
-    case ISD::FSIN: BuildMI(BB, X86::FSIN, 1, Result).addReg(Tmp1); break;
-    case ISD::FCOS: BuildMI(BB, X86::FCOS, 1, Result).addReg(Tmp1); break;
+    case ISD::FABS: BuildMI(BB, X86::FpABS, 1, Result).addReg(Tmp1); break;
+    case ISD::FNEG: BuildMI(BB, X86::FpCHS, 1, Result).addReg(Tmp1); break;
+    case ISD::FSIN: BuildMI(BB, X86::FpSIN, 1, Result).addReg(Tmp1); break;
+    case ISD::FCOS: BuildMI(BB, X86::FpCOS, 1, Result).addReg(Tmp1); break;
     }
     return Result;
 
@@ -1698,7 +1698,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
   case ISD::XOR: {
     static const unsigned SUBTab[] = {
       X86::SUB8ri, X86::SUB16ri, X86::SUB32ri, 0, 0,
-      X86::SUB8rm, X86::SUB16rm, X86::SUB32rm, X86::FSUB32m, X86::FSUB64m,
+      X86::SUB8rm, X86::SUB16rm, X86::SUB32rm, X86::FpSUB32m, X86::FpSUB64m,
       X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::FpSUB  , X86::FpSUB,
     };
     static const unsigned SSE_SUBTab[] = {
@@ -1708,7 +1708,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
     };
     static const unsigned MULTab[] = {
       0, X86::IMUL16rri, X86::IMUL32rri, 0, 0,
-      0, X86::IMUL16rm , X86::IMUL32rm, X86::FMUL32m, X86::FMUL64m,
+      0, X86::IMUL16rm , X86::IMUL32rm, X86::FpMUL32m, X86::FpMUL64m,
       0, X86::IMUL16rr , X86::IMUL32rr, X86::FpMUL  , X86::FpMUL,
     };
     static const unsigned SSE_MULTab[] = {
@@ -1821,9 +1821,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
         // For FP, emit 'reverse' subract, with a memory operand.
         if (N.getValueType() == MVT::f64 && !X86ScalarSSE) {
           if (Op0.getOpcode() == ISD::EXTLOAD)
-            Opc = X86::FSUBR32m;
+            Opc = X86::FpSUBR32m;
           else
-            Opc = X86::FSUBR64m;
+            Opc = X86::FpSUBR64m;
 
           X86AddressMode AM;
           EmitFoldedLoad(Op0, AM);
@@ -2015,9 +2015,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
         // Check for reversed and unreversed DIV.
         if (isFoldableLoad(N.getOperand(0), N.getOperand(1), true)) {
           if (N.getOperand(0).getOpcode() == ISD::EXTLOAD)
-            Opc = X86::FDIVR32m;
+            Opc = X86::FpDIVR32m;
           else
-            Opc = X86::FDIVR64m;
+            Opc = X86::FpDIVR64m;
           X86AddressMode AM;
           EmitFoldedLoad(N.getOperand(0), AM);
           Tmp1 = SelectExpr(N.getOperand(1));
@@ -2026,9 +2026,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
         } else if (isFoldableLoad(N.getOperand(1), N.getOperand(0), true) &&
                    N.getOperand(1).getOpcode() == ISD::LOAD) {
           if (N.getOperand(1).getOpcode() == ISD::EXTLOAD)
-            Opc = X86::FDIV32m;
+            Opc = X86::FpDIV32m;
           else
-            Opc = X86::FDIV64m;
+            Opc = X86::FpDIV64m;
           X86AddressMode AM;
           EmitFoldedLoad(N.getOperand(1), AM);
           Tmp1 = SelectExpr(N.getOperand(0));
@@ -2230,7 +2230,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
       if (X86ScalarSSE) {
         Opc = X86::MOVSDrm;
       } else {
-        Opc = X86::FLD64m;
+        Opc = X86::FpLD64m;
         ContainsFPCode = true;
       }
       break;
@@ -2276,7 +2276,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
         Select(Chain);
       }
 
-      addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
+      addFullAddress(BuildMI(BB, X86::FpILD64m, 4, Result), AM);
     }
     return Result;
 
@@ -2295,7 +2295,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
         unsigned CPIdx = BB->getParent()->getConstantPool()->
           getConstantPoolIndex(CP->get());
 
-        addConstantPoolReference(BuildMI(BB, X86::FLD32m, 4, Result), CPIdx);
+        addConstantPoolReference(BuildMI(BB, X86::FpLD32m, 4, Result), CPIdx);
         return Result;
       }
 
@@ -2314,7 +2314,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
     case MVT::f64:
       assert(cast<VTSDNode>(Node->getOperand(3))->getVT() == MVT::f32 &&
              "Bad EXTLOAD!");
-      addFullAddress(BuildMI(BB, X86::FLD32m, 5, Result), AM);
+      addFullAddress(BuildMI(BB, X86::FpLD32m, 5, Result), AM);
       break;
     case MVT::i32:
       switch (cast<VTSDNode>(Node->getOperand(3))->getVT()) {
@@ -2521,7 +2521,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
           unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
           MachineFunction *F = BB->getParent();
           int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
-          addFrameReference(BuildMI(BB, X86::FST64m, 5), FrameIdx).addReg(X86::FP0);
+          addFrameReference(BuildMI(BB, X86::FpST64m, 5), FrameIdx).addReg(X86::FP0);
           addFrameReference(BuildMI(BB, X86::MOVSDrm, 4, Result), FrameIdx);
           break;
         } else {
@@ -3197,7 +3197,7 @@ void ISel::Select(SDOperand N) {
           MachineFunction *F = BB->getParent();
           int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
           addFrameReference(BuildMI(BB, X86::MOVSSmr, 5), FrameIdx).addReg(Tmp1);
-          addFrameReference(BuildMI(BB, X86::FLD32m, 4, X86::FP0), FrameIdx);
+          addFrameReference(BuildMI(BB, X86::FpLD32m, 4, X86::FP0), FrameIdx);
           BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0);
           ContainsFPCode = true;
         } else {
@@ -3212,7 +3212,7 @@ void ISel::Select(SDOperand N) {
           MachineFunction *F = BB->getParent();
           int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
           addFrameReference(BuildMI(BB, X86::MOVSDmr, 5), FrameIdx).addReg(Tmp1);
-          addFrameReference(BuildMI(BB, X86::FLD64m, 4, X86::FP0), FrameIdx);
+          addFrameReference(BuildMI(BB, X86::FpLD64m, 4, X86::FP0), FrameIdx);
           BuildMI(BB, X86::FpSETRESULT, 1).addReg(X86::FP0);
           ContainsFPCode = true;
         } else {
@@ -3342,9 +3342,9 @@ void ISel::Select(SDOperand N) {
 
     // Get the X86 opcode to use.
     switch (N.getOpcode()) {
-    case X86ISD::FP_TO_INT16_IN_MEM: Tmp1 = X86::FIST16m; break;
-    case X86ISD::FP_TO_INT32_IN_MEM: Tmp1 = X86::FIST32m; break;
-    case X86ISD::FP_TO_INT64_IN_MEM: Tmp1 = X86::FISTP64m; break;
+    case X86ISD::FP_TO_INT16_IN_MEM: Tmp1 = X86::FpIST16m; break;
+    case X86ISD::FP_TO_INT32_IN_MEM: Tmp1 = X86::FpIST32m; break;
+    case X86ISD::FP_TO_INT64_IN_MEM: Tmp1 = X86::FpIST64m; break;
     }
 
     addFullAddress(BuildMI(BB, Tmp1, 5), AM).addReg(ValReg);
@@ -3393,7 +3393,7 @@ void ISel::Select(SDOperand N) {
     case MVT::i1: Opc = X86::MOV8mr; break;
     case MVT::f32:
       assert(!X86ScalarSSE && "Cannot truncstore scalar SSE regs");
-      Opc = X86::FST32m; break;
+      Opc = X86::FpST32m; break;
     }
 
     std::vector<std::pair<unsigned, unsigned> > RP;
@@ -3474,7 +3474,7 @@ void ISel::Select(SDOperand N) {
     case MVT::i16: Opc = X86::MOV16mr; break;
     case MVT::i32: Opc = X86::MOV32mr; break;
     case MVT::f32: Opc = X86::MOVSSmr; break;
-    case MVT::f64: Opc = X86ScalarSSE ? X86::MOVSDmr : X86::FST64m; break;
+    case MVT::f64: Opc = X86ScalarSSE ? X86::MOVSDmr : X86::FpST64m; break;
     }
 
     std::vector<std::pair<unsigned, unsigned> > RP;
index 79db001..c5e77dc 100644 (file)
@@ -2203,334 +2203,256 @@ def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
 // Stack-based Floating point support
 //===----------------------------------------------------------------------===//
 
-// FIXME: These need to indicate mod/ref sets for FP regs... & FP 'TOP'
+// Floating point support.  All FP Stack operations are represented with two 
+// instructions here.  The first instruction, generated by the instruction
+// selector, uses "RFP" registers: a traditional register file to reference
+// floating point values.  These instructions are all psuedo instructions and
+// use the "Fp" prefix.  The second instruction is defined with FPI, which is
+// the actual instruction emitted by the assembler.  The FP stackifier pass
+// converts one to the other after register allocation occurs.
+//
+// Note that the FpI instruction should have instruction selection info (e.g.
+// a pattern) and the FPI instruction should have emission info (e.g. opcode
+// encoding and asm printing info).
+
+// FPI - Floating Point Instruction template.
+class FPI<bits<8> o, Format F, dag ops, string asm> : I<o, F, ops, asm, []> {}
 
-// Floating point instruction template
-class FPI<bits<8> o, Format F, FPFormat fp, dag ops, string asm,
-          list<dag> pattern>
-  : X86Inst<o, F, NoImm, ops, asm> {
+// FpI - Floating Point Psuedo Instruction template.
+class FpI<dag ops, FPFormat fp, list<dag> pattern>
+  : X86Inst<0, Pseudo, NoImm, ops, ""> {
   let FPForm = fp; let FPFormBits = FPForm.Value;
   let Pattern = pattern;
 }
 
-// Pseudo instructions for floating point.  We use these pseudo instructions
-// because they can be expanded by the fp spackifier into one of many different
-// forms of instructions for doing these operations.  Until the stackifier runs,
-// we prefer to be abstract.
-def FpMOV : FPI<0, Pseudo, SpecialFP,
-                (ops RFP:$dst, RFP:$src), "", []>;   // f1 = fmov f2
-def FpADD : FPI<0, Pseudo, TwoArgFP ,
-                (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
-                []>; // f1 = fadd f2, f3
-def FpSUB : FPI<0, Pseudo, TwoArgFP ,
-                (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
-                []>;    // f1 = fsub f2, f3
-def FpMUL : FPI<0, Pseudo, TwoArgFP ,
-                (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
-                []>;    // f1 = fmul f2, f3
-def FpDIV : FPI<0, Pseudo, TwoArgFP ,
-                (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
-                []>;    // f1 = fdiv f2, f3
-
-def FpLD32m  : FPI<0xD9, MRM0m, ZeroArgFP,
-                   (ops RFP:$dst, f32mem:$src),
-                   "fld{s} $src",
-                   [(set RFP:$dst, (X86fld addr:$src, f32))]>;
-
-def FpLD64m  : FPI<0xDD, MRM0m, ZeroArgFP,
-                   (ops RFP:$dst, f64mem:$src),
-                   "fld{l} $src",
-                   [(set RFP:$dst, (X86fld addr:$src, f64))]>;
-
-def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "", []>,
-                  Imp<[ST0], []>;  // FPR = ST(0)
-
-def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "",
-                      [(X86fpset RFP:$src)]>,
-                  Imp<[], [ST0]>;  // ST(0) = FPR
-
-// FADD reg, mem: Before stackification, these are represented by:
-// R1 = FADD* R2, [mem]
-def FADD32m  : FPI<0xD8, MRM0m, OneArgFPRW,    // ST(0) = ST(0) + [mem32real]
-                   (ops f32mem:$src, variable_ops),
-                   "fadd{s} $src", []>;
-def FADD64m  : FPI<0xDC, MRM0m, OneArgFPRW,    // ST(0) = ST(0) + [mem64real]
-                   (ops f64mem:$src, variable_ops),
-                   "fadd{l} $src", []>;
-//def FIADD16m : FPI<0xDE, MRM0m, OneArgFPRW>;    // ST(0) = ST(0) + [mem16int]
-//def FIADD32m : FPI<0xDA, MRM0m, OneArgFPRW>;    // ST(0) = ST(0) + [mem32int]
-
-// FMUL reg, mem: Before stackification, these are represented by:
-// R1 = FMUL* R2, [mem]
-def FMUL32m  : FPI<0xD8, MRM1m, OneArgFPRW,    // ST(0) = ST(0) * [mem32real]
-                   (ops f32mem:$src, variable_ops),
-                   "fmul{s} $src", []>;
-def FMUL64m  : FPI<0xDC, MRM1m, OneArgFPRW,    // ST(0) = ST(0) * [mem64real]
-                   (ops f64mem:$src, variable_ops),
-                   "fmul{l} $src", []>;
-// ST(0) = ST(0) * [mem16int]
-//def FIMUL16m : FPI16m<"fimul", 0xDE, MRM1m, OneArgFPRW>;
-// ST(0) = ST(0) * [mem32int]
-//def FIMUL32m : FPI32m<"fimul", 0xDA, MRM1m, OneArgFPRW>;
-
-// FSUB reg, mem: Before stackification, these are represented by:
-// R1 = FSUB* R2, [mem]
-def FSUB32m  : FPI<0xD8, MRM4m, OneArgFPRW,    // ST(0) = ST(0) - [mem32real]
-                   (ops f32mem:$src, variable_ops),
-                   "fsub{s} $src", []>;
-def FSUB64m  : FPI<0xDC, MRM4m, OneArgFPRW,    // ST(0) = ST(0) - [mem64real]
-                   (ops f64mem:$src, variable_ops),
-                   "fsub{l} $src", []>;
-// ST(0) = ST(0) - [mem16int]
-//def FISUB16m : FPI16m<"fisub", 0xDE, MRM4m, OneArgFPRW>;
-// ST(0) = ST(0) - [mem32int]
-//def FISUB32m : FPI32m<"fisub", 0xDA, MRM4m, OneArgFPRW>;
-
-// FSUBR reg, mem: Before stackification, these are represented by:
-// R1 = FSUBR* R2, [mem]
-
-// Note that the order of operands does not reflect the operation being
-// performed.
-def FSUBR32m  : FPI<0xD8, MRM5m, OneArgFPRW,  // ST(0) = [mem32real] - ST(0)
-                    (ops f32mem:$src, variable_ops),
-                    "fsubr{s} $src", []>;
-def FSUBR64m  : FPI<0xDC, MRM5m, OneArgFPRW,  // ST(0) = [mem64real] - ST(0)
-                    (ops f64mem:$src, variable_ops),
-                    "fsubr{l} $src", []>;
-// ST(0) = [mem16int] - ST(0)
-//def FISUBR16m : FPI16m<"fisubr", 0xDE, MRM5m, OneArgFPRW>;
-// ST(0) = [mem32int] - ST(0)
-//def FISUBR32m : FPI32m<"fisubr", 0xDA, MRM5m, OneArgFPRW>;
-
-// FDIV reg, mem: Before stackification, these are represented by:
-// R1 = FDIV* R2, [mem]
-def FDIV32m  : FPI<0xD8, MRM6m, OneArgFPRW,    // ST(0) = ST(0) / [mem32real]
-                   (ops f32mem:$src, variable_ops),
-                   "fdiv{s} $src", []>;
-def FDIV64m  : FPI<0xDC, MRM6m, OneArgFPRW,    // ST(0) = ST(0) / [mem64real]
-                   (ops f64mem:$src, variable_ops),
-                   "fdiv{l} $src", []>;
-// ST(0) = ST(0) / [mem16int]
-//def FIDIV16m : FPI16m<"fidiv", 0xDE, MRM6m, OneArgFPRW>;
-// ST(0) = ST(0) / [mem32int]
-//def FIDIV32m : FPI32m<"fidiv", 0xDA, MRM6m, OneArgFPRW>;
-
-// FDIVR reg, mem: Before stackification, these are represented by:
-// R1 = FDIVR* R2, [mem]
-// Note that the order of operands does not reflect the operation being
-// performed.
-def FDIVR32m  : FPI<0xD8, MRM7m, OneArgFPRW,  // ST(0) = [mem32real] / ST(0)
-                    (ops f32mem:$src, variable_ops),
-                    "fdivr{s} $src", []>;
-def FDIVR64m  : FPI<0xDC, MRM7m, OneArgFPRW,  // ST(0) = [mem64real] / ST(0)
-                    (ops f64mem:$src, variable_ops),
-                    "fdivr{l} $src", []>;
-// ST(0) = [mem16int] / ST(0)
-//def FIDIVR16m : FPI16m<"fidivr", 0xDE, MRM7m, OneArgFPRW>;
-// ST(0) = [mem32int] / ST(0)
-//def FIDIVR32m : FPI32m<"fidivr", 0xDA, MRM7m, OneArgFPRW>;
-
-
-// Floating point cmovs...
-let isTwoAddress = 1, Uses = [ST0], Defs = [ST0] in {
-  def FCMOVB  : FPI<0xC0, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovb {$op, %ST(0)|%ST(0), $op}", []>, DA;
-  def FCMOVBE : FPI<0xD0, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovbe {$op, %ST(0)|%ST(0), $op}", []>, DA;
-  def FCMOVE  : FPI<0xC8, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmove {$op, %ST(0)|%ST(0), $op}", []>, DA;
-  def FCMOVP  : FPI<0xD8, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovu  {$op, %ST(0)|%ST(0), $op}", []>, DA;
-  def FCMOVAE : FPI<0xC0, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovae {$op, %ST(0)|%ST(0), $op}", []>, DB;
-  def FCMOVA  : FPI<0xD0, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmova {$op, %ST(0)|%ST(0), $op}", []>, DB;
-  def FCMOVNE : FPI<0xC8, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovne {$op, %ST(0)|%ST(0), $op}", []>, DB;
-  def FCMOVNP : FPI<0xD8, AddRegFrm, CondMovFP,
-                    (ops RST:$op, variable_ops),
-                    "fcmovnu {$op, %ST(0)|%ST(0), $op}", []>, DB;
-}
-
-// Floating point loads & stores...
-// FIXME: these are all marked variable_ops because they have an implicit 
-// destination.  Instructions like FILD* that are generated by the instruction
-//  selector (not the fp stackifier) need more accurate operand accounting.
-def FLDrr   : FPI<0xC0, AddRegFrm, NotFP,
-                  (ops RST:$src, variable_ops),
-                  "fld $src", []>, D9;
-def FLD32m  : FPI<0xD9, MRM0m, ZeroArgFP,
-                  (ops f32mem:$src, variable_ops),
-                  "fld{s} $src", []>;
-def FLD64m  : FPI<0xDD, MRM0m, ZeroArgFP,
-                  (ops f64mem:$src, variable_ops),
-                  "fld{l} $src", []>;
-def FLD80m  : FPI<0xDB, MRM5m, ZeroArgFP,
-                  (ops f80mem:$src, variable_ops),
-                  "fld{t} $src", []>;
-def FILD16m : FPI<0xDF, MRM0m, ZeroArgFP,
-                  (ops i16mem:$src, variable_ops),
-                  "fild{s} $src", []>;
-def FILD32m : FPI<0xDB, MRM0m, ZeroArgFP,
-                  (ops i32mem:$src, variable_ops),
-                  "fild{l} $src", []>;
-def FILD64m : FPI<0xDF, MRM5m, ZeroArgFP,
-                  (ops i64mem:$src, variable_ops),
-                  "fild{ll} $src", []>;
-
-def FSTrr    : FPI<0xD0, AddRegFrm, NotFP,
-                   (ops RST:$op, variable_ops),
-                   "fst $op", []>, DD;
-def FSTPrr   : FPI<0xD8, AddRegFrm, NotFP,
-                   (ops RST:$op, variable_ops),
-                   "fstp $op", []>, DD;
-def FST32m   : FPI<0xD9, MRM2m, OneArgFP,
-                   (ops f32mem:$op, variable_ops),
-                   "fst{s} $op", []>;
-def FST64m   : FPI<0xDD, MRM2m, OneArgFP,
-                   (ops f64mem:$op, variable_ops),
-                   "fst{l} $op", []>;
-def FSTP32m  : FPI<0xD9, MRM3m, OneArgFP,
-                   (ops f32mem:$op, variable_ops),
-                   "fstp{s} $op", []>;
-def FSTP64m  : FPI<0xDD, MRM3m, OneArgFP,
-                   (ops f64mem:$op, variable_ops),
-                   "fstp{l} $op", []>;
-def FSTP80m  : FPI<0xDB, MRM7m, OneArgFP,
-                   (ops f80mem:$op, variable_ops),
-                   "fstp{t} $op", []>;
-
-def FIST16m  : FPI<0xDF, MRM2m , OneArgFP,
-                   (ops i16mem:$op, variable_ops),
-                   "fist{s} $op", []>;
-def FIST32m  : FPI<0xDB, MRM2m , OneArgFP,
-                   (ops i32mem:$op, variable_ops),
-                   "fist{l} $op", []>;
-def FISTP16m : FPI<0xDF, MRM3m , NotFP   ,
-                   (ops i16mem:$op, variable_ops),
-                   "fistp{s} $op", []>;
-def FISTP32m : FPI<0xDB, MRM3m , NotFP   ,
-                   (ops i32mem:$op, variable_ops),
-                   "fistp{l} $op", []>;
-def FISTP64m : FPI<0xDF, MRM7m , OneArgFP,
-                   (ops i64mem:$op, variable_ops),
-                   "fistp{ll} $op", []>;
-
-def FXCH     : FPI<0xC8, AddRegFrm, NotFP,
-                   (ops RST:$op), "fxch $op", []>, D9;      // fxch ST(i), ST(0)
-
-// Floating point constant loads...
-def FLD0 : FPI<0xEE, RawFrm, ZeroArgFP, (ops variable_ops), "fldz", []>, D9;
-def FLD1 : FPI<0xE8, RawFrm, ZeroArgFP, (ops variable_ops), "fld1", []>, D9;
-
-
-// Unary operations...
-def FCHS  : FPI<0xE0, RawFrm, OneArgFPRW,   // f1 = fchs f2
-                (ops variable_ops),
-                "fchs", []>, D9;
-def FABS  : FPI<0xE1, RawFrm, OneArgFPRW,   // f1 = fabs f2
-                (ops variable_ops),
-                "fabs", []>, D9;
-def FSQRT : FPI<0xFA, RawFrm, OneArgFPRW,   // fsqrt ST(0)
-                (ops variable_ops),
-                "fsqrt", []>, D9;
-def FSIN  : FPI<0xFE, RawFrm, OneArgFPRW,   // fsin  ST(0)
-                (ops variable_ops),
-                "fsin", []>, D9;
-def FCOS  : FPI<0xFF, RawFrm, OneArgFPRW,   // fcos  ST(0)
-                (ops variable_ops),
-                "fcos", []>, D9;
-def FTST  : FPI<0xE4, RawFrm, OneArgFP  ,   // ftst ST(0)
-                (ops variable_ops),
-                "ftst", []>, D9;
-
-// Binary arithmetic operations...
-class FPST0rInst<bits<8> o, dag ops, string asm>
-  : I<o, AddRegFrm, ops, asm, []>, D8 {
-  list<Register> Uses = [ST0];
-  list<Register> Defs = [ST0];
-}
-class FPrST0Inst<bits<8> o, dag ops, string asm>
-  : I<o, AddRegFrm, ops, asm, []>, DC {
-  list<Register> Uses = [ST0];
-}
-class FPrST0PInst<bits<8> o, dag ops, string asm>
-  : I<o, AddRegFrm, ops, asm, []>, DE {
-  list<Register> Uses = [ST0];
+// Random Pseudo Instructions.
+def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, // FPR = ST(0)
+                      []>;  
+def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP,
+                      [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;  // ST(0) = FPR
+def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP,
+                      []>;   // f1 = fmov f2
+
+// Binary Ops with a memory source.
+def FpADD32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) + [mem32]
+def FpADD64m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) + [mem32]
+def FpMUL32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) * [mem32]
+def FpMUL64m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) * [mem32]
+def FpSUB32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                     []>; // ST(0) = ST(0) - [mem32]
+def FpSUB64m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) - [mem32]
+def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = [mem32] - ST(0)
+def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = [mem32] - ST(0)
+def FpDIV32m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                     []>; // ST(0) = ST(0) / [mem32]
+def FpDIV64m  : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = ST(0) / [mem32]
+def FpDIVR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = [mem32] / ST(0)
+def FpDIVR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
+                    []>; // ST(0) = [mem32] / ST(0)
+
+
+def FADD32m  : FPI<0xD8, MRM0m, (ops f32mem:$src), "fadd{s} $src">;
+def FADD64m  : FPI<0xDC, MRM0m, (ops f64mem:$src), "fadd{l} $src">;
+def FMUL32m  : FPI<0xD8, MRM1m, (ops f32mem:$src), "fmul{s} $src">;
+def FMUL64m  : FPI<0xDC, MRM1m, (ops f64mem:$src), "fmul{l} $src">;
+def FSUB32m  : FPI<0xD8, MRM4m, (ops f32mem:$src), "fsub{s} $src">;
+def FSUB64m  : FPI<0xDC, MRM4m, (ops f64mem:$src), "fsub{l} $src">;
+def FSUBR32m : FPI<0xD8, MRM5m, (ops f32mem:$src), "fsubr{s} $src">;
+def FSUBR64m : FPI<0xDC, MRM5m, (ops f64mem:$src), "fsubr{l} $src">;
+def FDIV32m  : FPI<0xD8, MRM6m, (ops f32mem:$src), "fdiv{s} $src">;
+def FDIV64m  : FPI<0xDC, MRM6m, (ops f64mem:$src), "fdiv{l} $src">;
+def FDIVR32m : FPI<0xD8, MRM7m, (ops f32mem:$src), "fdivr{s} $src">;
+def FDIVR64m : FPI<0xDC, MRM7m, (ops f64mem:$src), "fdivr{l} $src">;
+
+// FIXME: Implement these when we have a dag-dag isel!
+//def FIADD16m  : FPI<0xDE, MRM0m>;    // ST(0) = ST(0) + [mem16int]
+//def FIADD32m  : FPI<0xDA, MRM0m>;    // ST(0) = ST(0) + [mem32int]
+//def FIMUL16m  : FPI<0xDE, MRM1m>;    // ST(0) = ST(0) * [mem16]
+//def FIMUL32m  : FPI<0xDA, MRM1m>;    // ST(0) = ST(0) * [mem32]
+//def FISUB16m  : FPI<0xDE, MRM4m>;    // ST(0) = ST(0) - [mem16int]
+//def FISUB32m  : FPI<0xDA, MRM4m>;    // ST(0) = ST(0) - [mem32int]
+//def FISUBR16m : FPI<0xDE, MRM5m>;    // ST(0) = [mem16int] - ST(0)
+//def FISUBR32m : FPI<0xDA, MRM5m>;    // ST(0) = [mem32int] - ST(0)
+//def FIDIV16m  : FPI<0xDE, MRM6m>;    // ST(0) = ST(0) / [mem16int]
+//def FIDIV32m  : FPI<0xDA, MRM6m>;    // ST(0) = ST(0) / [mem32int]
+//def FIDIVR16m : FPI<0xDE, MRM7m>;    // ST(0) = [mem16int] / ST(0)
+//def FIDIVR32m : FPI<0xDA, MRM7m>;    // ST(0) = [mem32int] / ST(0)
+
+
+// Floating point cmovs.
+let isTwoAddress = 1 in {
+  def FpCMOVB  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVBE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVE  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVP  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVAE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVA  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVNE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVNP : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
 }
 
-def FADDST0r   : FPST0rInst <0xC0, (ops RST:$op),
-                             "fadd $op">;
-def FADDrST0   : FPrST0Inst <0xC0, (ops RST:$op),
-                             "fadd {%ST(0), $op|$op, %ST(0)}">;
-def FADDPrST0  : FPrST0PInst<0xC0, (ops RST:$op),
-                             "faddp $op">;
+def FCMOVB  : FPI<0xC0, AddRegFrm, (ops RST:$op),
+                  "fcmovb {$op, %ST(0)|%ST(0), $op}">, DA;
+def FCMOVBE : FPI<0xD0, AddRegFrm, (ops RST:$op),
+                  "fcmovbe {$op, %ST(0)|%ST(0), $op}">, DA;
+def FCMOVE  : FPI<0xC8, AddRegFrm, (ops RST:$op),
+                  "fcmove {$op, %ST(0)|%ST(0), $op}">, DA;
+def FCMOVP  : FPI<0xD8, AddRegFrm, (ops RST:$op),
+                  "fcmovu  {$op, %ST(0)|%ST(0), $op}">, DA;
+def FCMOVAE : FPI<0xC0, AddRegFrm, (ops RST:$op),
+                  "fcmovae {$op, %ST(0)|%ST(0), $op}">, DB;
+def FCMOVA  : FPI<0xD0, AddRegFrm, (ops RST:$op),
+                  "fcmova {$op, %ST(0)|%ST(0), $op}">, DB;
+def FCMOVNE : FPI<0xC8, AddRegFrm, (ops RST:$op),
+                  "fcmovne {$op, %ST(0)|%ST(0), $op}">, DB;
+def FCMOVNP : FPI<0xD8, AddRegFrm, (ops RST:$op),
+                  "fcmovnu {$op, %ST(0)|%ST(0), $op}">, DB;
+
+// Floating point loads & stores.
+def FpLD32m  : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
+                   [(set RFP:$dst, (X86fld addr:$src, f32))]>;
+def FpLD64m  : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
+                   [(set RFP:$dst, (X86fld addr:$src, f64))]>;
+def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
+                   []>;
+def FpILD32m : FpI<(ops RFP:$dst, i32mem:$src), ZeroArgFP,
+                   []>;
+def FpILD64m : FpI<(ops RFP:$dst, i64mem:$src), ZeroArgFP,
+                   []>;
+
+def FpST32m   : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
+def FpST64m   : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
+def FpSTP32m  : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
+def FpSTP64m  : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
+def FpIST16m  : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;
+def FpIST32m  : FpI<(ops i32mem:$op, RFP:$src), OneArgFP, []>;
+def FpIST64m  : FpI<(ops i64mem:$op, RFP:$src), OneArgFP, []>;
+
+def FLD32m   : FPI<0xD9, MRM0m, (ops f32mem:$src), "fld{s} $src">;
+def FLD64m   : FPI<0xDD, MRM0m, (ops f64mem:$src), "fld{l} $src">;
+def FILD16m  : FPI<0xDF, MRM0m, (ops i16mem:$src), "fild{s} $src">;
+def FILD32m  : FPI<0xDB, MRM0m, (ops i32mem:$src), "fild{l} $src">;
+def FILD64m  : FPI<0xDF, MRM5m, (ops i64mem:$src), "fild{ll} $src">;
+def FST32m   : FPI<0xD9, MRM2m, (ops f32mem:$dst), "fst{s} $dst">;
+def FST64m   : FPI<0xDD, MRM2m, (ops f64mem:$dst), "fst{l} $dst">;
+def FSTP32m  : FPI<0xD9, MRM3m, (ops f32mem:$dst), "fstp{s} $dst">;
+def FSTP64m  : FPI<0xDD, MRM3m, (ops f64mem:$dst), "fstp{l} $dst">;
+def FIST16m  : FPI<0xDF, MRM2m, (ops i16mem:$dst), "fist{s} $dst">;
+def FIST32m  : FPI<0xDB, MRM2m, (ops i32mem:$dst), "fist{l} $dst">;
+def FISTP16m : FPI<0xDF, MRM3m, (ops i16mem:$dst), "fistp{s} $dst">;
+def FISTP32m : FPI<0xDB, MRM3m, (ops i32mem:$dst), "fistp{l} $dst">;
+def FISTP64m : FPI<0xDF, MRM7m, (ops i64mem:$dst), "fistp{ll} $dst">;
+
+// FP Stack manipulation instructions.
+def FLDrr   : FPI<0xC0, AddRegFrm, (ops RST:$op), "fld $op">, D9;
+def FSTrr   : FPI<0xD0, AddRegFrm, (ops RST:$op), "fst $op">, DD;
+def FSTPrr  : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
+def FXCH    : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
+
+// Floating point constant loads.
+def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP, []>;
+def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP, []>;
+
+def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
+def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
+
+
+// Unary operations.
+def FpCHS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
+                 [(set RFP:$dst, (fneg RFP:$src))]>;
+def FpABS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
+                 [(set RFP:$dst, (fabs RFP:$src))]>;
+def FpSQRT : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
+                 [(set RFP:$dst, (fsqrt RFP:$src))]>;
+def FpSIN  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
+                 [(set RFP:$dst, (fsin RFP:$src))]>;
+def FpCOS  : FpI<(ops RFP:$dst, RFP:$src), OneArgFPRW,
+                 [(set RFP:$dst, (fcos RFP:$src))]>;
+def FpTST  : FpI<(ops RFP:$src), OneArgFP,
+                 []>;
+
+def FCHS  : FPI<0xE0, RawFrm, (ops), "fchs">, D9;
+def FABS  : FPI<0xE1, RawFrm, (ops), "fabs">, D9;
+def FSQRT : FPI<0xFA, RawFrm, (ops), "fsqrt">, D9;
+def FSIN  : FPI<0xFE, RawFrm, (ops), "fsin">, D9;
+def FCOS  : FPI<0xFF, RawFrm, (ops), "fcos">, D9;
+def FTST  : FPI<0xE4, RawFrm, (ops), "ftst">, D9;
+
+
+
+// Add, Sub, Mul, Div.
+def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
+                [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
+def FpSUB : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
+                [(set RFP:$dst, (fsub RFP:$src1, RFP:$src2))]>;
+def FpMUL : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
+                [(set RFP:$dst, (fmul RFP:$src1, RFP:$src2))]>;
+def FpDIV : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
+                [(set RFP:$dst, (fdiv RFP:$src1, RFP:$src2))]>;
+
+class FPST0rInst<bits<8> o, string asm>
+  : FPI<o, AddRegFrm, (ops RST:$op), asm>, D8;
+class FPrST0Inst<bits<8> o, string asm>
+  : FPI<o, AddRegFrm, (ops RST:$op), asm>, DC;
+class FPrST0PInst<bits<8> o, string asm>
+  : FPI<o, AddRegFrm, (ops RST:$op), asm>, DE;
 
 // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion
 // of some of the 'reverse' forms of the fsub and fdiv instructions.  As such,
 // we have to put some 'r's in and take them out of weird places.
-def FSUBRST0r  : FPST0rInst <0xE8, (ops RST:$op),
-                             "fsubr $op">;
-def FSUBrST0   : FPrST0Inst <0xE8, (ops RST:$op),
-                             "fsub{r} {%ST(0), $op|$op, %ST(0)}">;
-def FSUBPrST0  : FPrST0PInst<0xE8, (ops RST:$op),
-                             "fsub{r}p $op">;
-
-def FSUBST0r   : FPST0rInst <0xE0, (ops RST:$op),
-                             "fsub $op">;
-def FSUBRrST0  : FPrST0Inst <0xE0, (ops RST:$op),
-                             "fsub{|r} {%ST(0), $op|$op, %ST(0)}">;
-def FSUBRPrST0 : FPrST0PInst<0xE0, (ops RST:$op),
-                             "fsub{|r}p $op">;
-
-def FMULST0r   : FPST0rInst <0xC8, (ops RST:$op),
-                             "fmul $op">;
-def FMULrST0   : FPrST0Inst <0xC8, (ops RST:$op),
-                             "fmul {%ST(0), $op|$op, %ST(0)}">;
-def FMULPrST0  : FPrST0PInst<0xC8, (ops RST:$op),
-                             "fmulp $op">;
-
-def FDIVRST0r  : FPST0rInst <0xF8, (ops RST:$op),
-                             "fdivr $op">;
-def FDIVrST0   : FPrST0Inst <0xF8, (ops RST:$op),
-                             "fdiv{r} {%ST(0), $op|$op, %ST(0)}">;
-def FDIVPrST0  : FPrST0PInst<0xF8, (ops RST:$op),
-                             "fdiv{r}p $op">;
-
-def FDIVST0r   : FPST0rInst <0xF0, (ops RST:$op),  // ST(0) = ST(0) / ST(i)
-                             "fdiv $op">;
-def FDIVRrST0  : FPrST0Inst <0xF0, (ops RST:$op),  // ST(i) = ST(0) / ST(i)
-                             "fdiv{|r} {%ST(0), $op|$op, %ST(0)}">;
-def FDIVRPrST0 : FPrST0PInst<0xF0, (ops RST:$op),  // ST(i) = ST(0) / ST(i), pop
-                             "fdiv{|r}p $op">;
-
-// Floating point compares
-def FUCOMr    : FPI<0xE0, AddRegFrm, CompareFP,   // FPSW = cmp ST(0) with ST(i)
-                    (ops RST:$reg, variable_ops),
-                    "fucom $reg", []>, DD, Imp<[ST0],[]>;
-def FUCOMPr   : I<0xE8, AddRegFrm,           // FPSW = cmp ST(0) with ST(i), pop
-                  (ops RST:$reg, variable_ops),
-                  "fucomp $reg", []>, DD, Imp<[ST0],[]>;
-def FUCOMPPr  : I<0xE9, RawFrm,                // cmp ST(0) with ST(1), pop, pop
-                  (ops variable_ops),
-                  "fucompp", []>, DA, Imp<[ST0],[]>;
-
-def FUCOMIr  : FPI<0xE8, AddRegFrm, CompareFP,  // CC = cmp ST(0) with ST(i)
-                   (ops RST:$reg, variable_ops),
-                   "fucomi {$reg, %ST(0)|%ST(0), $reg}", []>, DB, Imp<[ST0],[]>;
-def FUCOMIPr : I<0xE8, AddRegFrm,              // CC = cmp ST(0) with ST(i), pop
-                 (ops RST:$reg, variable_ops),
-                 "fucomip {$reg, %ST(0)|%ST(0), $reg}", []>, DF, Imp<[ST0],[]>;
-
-
-// Floating point flag ops
+def FADDST0r   : FPST0rInst <0xC0, "fadd $op">;
+def FADDrST0   : FPrST0Inst <0xC0, "fadd {%ST(0), $op|$op, %ST(0)}">;
+def FADDPrST0  : FPrST0PInst<0xC0, "faddp $op">;
+def FSUBRST0r  : FPST0rInst <0xE8, "fsubr $op">;
+def FSUBrST0   : FPrST0Inst <0xE8, "fsub{r} {%ST(0), $op|$op, %ST(0)}">;
+def FSUBPrST0  : FPrST0PInst<0xE8, "fsub{r}p $op">;
+def FSUBST0r   : FPST0rInst <0xE0, "fsub $op">;
+def FSUBRrST0  : FPrST0Inst <0xE0, "fsub{|r} {%ST(0), $op|$op, %ST(0)}">;
+def FSUBRPrST0 : FPrST0PInst<0xE0, "fsub{|r}p $op">;
+def FMULST0r   : FPST0rInst <0xC8, "fmul $op">;
+def FMULrST0   : FPrST0Inst <0xC8, "fmul {%ST(0), $op|$op, %ST(0)}">;
+def FMULPrST0  : FPrST0PInst<0xC8, "fmulp $op">;
+def FDIVRST0r  : FPST0rInst <0xF8, "fdivr $op">;
+def FDIVrST0   : FPrST0Inst <0xF8, "fdiv{r} {%ST(0), $op|$op, %ST(0)}">;
+def FDIVPrST0  : FPrST0PInst<0xF8, "fdiv{r}p $op">;
+def FDIVST0r   : FPST0rInst <0xF0, "fdiv $op">;
+def FDIVRrST0  : FPrST0Inst <0xF0, "fdiv{|r} {%ST(0), $op|$op, %ST(0)}">;
+def FDIVRPrST0 : FPrST0PInst<0xF0, "fdiv{|r}p $op">;
+
+// Floating point compares.
+def FpUCOMr   : FpI<(ops RST:$lhs, RST:$rhs), CompareFP,
+                    []>;  // FPSW = cmp ST(0) with ST(i)
+def FpUCOMIr  : FpI<(ops RST:$lhs, RST:$rhs), CompareFP,
+                    []>;  // CC = cmp ST(0) with ST(i)
+
+def FUCOMr    : FPI<0xE0, AddRegFrm,    // FPSW = cmp ST(0) with ST(i)
+                    (ops RST:$reg),
+                    "fucom $reg">, DD, Imp<[ST0],[]>;
+def FUCOMPr   : FPI<0xE8, AddRegFrm,    // FPSW = cmp ST(0) with ST(i), pop
+                  (ops RST:$reg),
+                  "fucomp $reg">, DD, Imp<[ST0],[]>;
+def FUCOMPPr  : FPI<0xE9, RawFrm,       // cmp ST(0) with ST(1), pop, pop
+                  (ops),
+                  "fucompp">, DA, Imp<[ST0],[]>;
+
+def FUCOMIr  : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i)
+                   (ops RST:$reg),
+                   "fucomi {$reg, %ST(0)|%ST(0), $reg}">, DB, Imp<[ST0],[]>;
+def FUCOMIPr : FPI<0xE8, AddRegFrm,     // CC = cmp ST(0) with ST(i), pop
+                 (ops RST:$reg),
+                 "fucomip {$reg, %ST(0)|%ST(0), $reg}">, DF, Imp<[ST0],[]>;
+
+
+// Floating point flag ops.
 def FNSTSW8r  : I<0xE0, RawFrm,                  // AX = fp flags
                   (ops), "fnstsw", []>, DF, Imp<[],[AX]>;
 
index a0e0aca..765b657 100644 (file)
@@ -56,7 +56,7 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
   } else if (RC == &X86::R16RegClass) {
     Opc = X86::MOV16mr;
   } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) {
-    Opc = X86::FST64m;
+    Opc = X86::FpST64m;
   } else if (RC == &X86::V4F4RegClass) {
     Opc = X86::MOVSSmr;
   } else if (RC == &X86::V2F8RegClass) {
@@ -80,7 +80,7 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
   } else if (RC == &X86::R16RegClass) {
     Opc = X86::MOV16rm;
   } else if (RC == &X86::RFPRegClass || RC == &X86::RSTRegClass) {
-    Opc = X86::FLD64m;
+    Opc = X86::FpLD64m;
   } else if (RC == &X86::V4F4RegClass) {
     Opc = X86::MOVSSrm;
   } else if (RC == &X86::V2F8RegClass) {
@@ -123,8 +123,7 @@ unsigned X86RegisterInfo::isLoadFromStackSlot(MachineInstr *MI,
   case X86::MOV8rm:
   case X86::MOV16rm:
   case X86::MOV32rm:
-  case X86::FLD64m:
-  case X86::FLD80m:
+  case X86::FpLD64m:
   case X86::MOVSSrm:
   case X86::MOVSDrm:
     if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() &&