Get rid of a pseudo instruction and replace it with subreg based operation on real...
[oota-llvm.git] / lib / Target / X86 / X86ISelDAGToDAG.cpp
index c51cd80cb9f52e2c9f8c39111eed1aed0d272540..bf233bfcbb459431c851f933662fdeab6819e8ed 100644 (file)
@@ -32,6 +32,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
@@ -43,7 +44,6 @@ using namespace llvm;
 STATISTIC(NumFPKill   , "Number of FP_REG_KILL instructions added");
 STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
 
-
 //===----------------------------------------------------------------------===//
 //                      Pattern Matcher Implementation
 //===----------------------------------------------------------------------===//
@@ -63,7 +63,7 @@ namespace {
       int FrameIndex;
     } Base;
 
-    bool isRIPRel;     // RIP relative?
+    bool isRIPRel;     // RIP as base?
     unsigned Scale;
     SDOperand IndexReg; 
     unsigned Disp;
@@ -426,7 +426,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
           RModW = true;
           std::swap(N10, N11);
         }
-        RModW = RModW && N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+        RModW = RModW && N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
           (N10.getOperand(1) == N2) &&
           (N10.Val->getValueType(0) == N1.getValueType());
         if (RModW)
@@ -445,7 +445,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
       case X86ISD::SHRD: {
         SDOperand N10 = N1.getOperand(0);
         if (ISD::isNON_EXTLoad(N10.Val))
-          RModW = N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+          RModW = N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
             (N10.getOperand(1) == N2) &&
             (N10.Val->getValueType(0) == N1.getValueType());
         if (RModW)
@@ -486,10 +486,15 @@ void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) {
     if (SrcIsSSE && DstIsSSE)
       continue;
 
-    // If this is an FPStack extension (but not a truncation), it is a noop.
-    if (!SrcIsSSE && !DstIsSSE && N->getOpcode() == ISD::FP_EXTEND)
-      continue;
-    
+    if (!SrcIsSSE && !DstIsSSE) {
+      // If this is an FPStack extension, it is a noop.
+      if (N->getOpcode() == ISD::FP_EXTEND)
+        continue;
+      // If this is a value-preserving FPStack truncation, it is a noop.
+      if (N->getConstantOperandVal(1))
+        continue;
+    }
+   
     // Here we could have an FP stack truncation or an FPStack <-> SSE convert.
     // FPStack has extload and truncstore.  SSE can fold direct loads into other
     // operations.  Based on this, decide what we want to do.
@@ -545,7 +550,8 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
 
   DAG.RemoveDeadNodes();
 
-  // Emit machine code to BB. 
+  // Emit machine code to BB.  This can change 'BB' to the last block being 
+  // inserted into.
   ScheduleAndEmitDAG(DAG);
   
   // If we are emitting FP stack code, scan the basic block to determine if this
@@ -561,15 +567,27 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   // Scan all of the machine instructions in these MBBs, checking for FP
   // stores.  (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.)
   MachineFunction::iterator MBBI = FirstMBB;
-  do {
+  MachineFunction::iterator EndMBB = BB; ++EndMBB;
+  for (; MBBI != EndMBB; ++MBBI) {
+    MachineBasicBlock *MBB = MBBI;
+    
+    // If this block returns, ignore it.  We don't want to insert an FP_REG_KILL
+    // before the return.
+    if (!MBB->empty()) {
+      MachineBasicBlock::iterator EndI = MBB->end();
+      --EndI;
+      if (EndI->getDesc().isReturn())
+        continue;
+    }
+    
     bool ContainsFPCode = false;
-    for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
+    for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
          !ContainsFPCode && I != E; ++I) {
       if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
         const TargetRegisterClass *clas;
         for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
           if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
-              MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
+            TargetRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
               ((clas = RegInfo->getRegClass(I->getOperand(0).getReg())) == 
                  X86::RFP32RegisterClass ||
                clas == X86::RFP64RegisterClass ||
@@ -603,11 +621,11 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
     }
     // Finally, if we found any FP code, emit the FP_REG_KILL instruction.
     if (ContainsFPCode) {
-      BuildMI(*MBBI, MBBI->getFirstTerminator(),
+      BuildMI(*MBB, MBBI->getFirstTerminator(),
               TM.getInstrInfo()->get(X86::FP_REG_KILL));
       ++NumFPKill;
     }
-  } while (&*(MBBI++) != BB);
+  }
 }
 
 /// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
@@ -664,7 +682,9 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
   case X86ISD::Wrapper: {
     bool is64Bit = Subtarget->is64Bit();
     // Under X86-64 non-small code model, GV (and friends) are 64-bits.
-    if (is64Bit && TM.getCodeModel() != CodeModel::Small)
+    // Also, base and index reg must be 0 in order to use rip as base.
+    if (is64Bit && (TM.getCodeModel() != CodeModel::Small ||
+                    AM.Base.Reg.Val || AM.IndexReg.Val))
       break;
     if (AM.GV != 0 || AM.CP != 0 || AM.ES != 0 || AM.JT != -1)
       break;
@@ -672,39 +692,31 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     // been picked, we can't fit the result available in the register in the
     // addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
     if (!AlreadySelected || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
-      bool isStatic = TM.getRelocationModel() == Reloc::Static;
       SDOperand N0 = N.getOperand(0);
-      // Mac OS X X86-64 lower 4G address is not available.
-      bool isAbs32 = !is64Bit ||
-        (isStatic && Subtarget->hasLow4GUserSpaceAddress());
       if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
         GlobalValue *GV = G->getGlobal();
-        if (isAbs32 || isRoot) {
-          AM.GV = GV;
-          AM.Disp += G->getOffset();
-          AM.isRIPRel = !isAbs32;
-          return false;
-        }
+        AM.GV = GV;
+        AM.Disp += G->getOffset();
+        AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+          Subtarget->isPICStyleRIPRel();
+        return false;
       } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
-        if (isAbs32 || isRoot) {
-          AM.CP = CP->getConstVal();
-          AM.Align = CP->getAlignment();
-          AM.Disp += CP->getOffset();
-          AM.isRIPRel = !isAbs32;
-          return false;
-        }
+        AM.CP = CP->getConstVal();
+        AM.Align = CP->getAlignment();
+        AM.Disp += CP->getOffset();
+        AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+          Subtarget->isPICStyleRIPRel();
+        return false;
       } else if (ExternalSymbolSDNode *S =dyn_cast<ExternalSymbolSDNode>(N0)) {
-        if (isAbs32 || isRoot) {
-          AM.ES = S->getSymbol();
-          AM.isRIPRel = !isAbs32;
-          return false;
-        }
+        AM.ES = S->getSymbol();
+        AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+          Subtarget->isPICStyleRIPRel();
+        return false;
       } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
-        if (isAbs32 || isRoot) {
-          AM.JT = J->getIndex();
-          AM.isRIPRel = !isAbs32;
-          return false;
-        }
+        AM.JT = J->getIndex();
+        AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+          Subtarget->isPICStyleRIPRel();
+        return false;
       }
     }
     break;
@@ -719,7 +731,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     break;
 
   case ISD::SHL:
-    if (AlreadySelected || AM.IndexReg.Val != 0 || AM.Scale != 1)
+    if (AlreadySelected || AM.IndexReg.Val != 0 || AM.Scale != 1 || AM.isRIPRel)
       break;
       
     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
@@ -759,7 +771,8 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     if (!AlreadySelected &&
         AM.BaseType == X86ISelAddressMode::RegBase &&
         AM.Base.Reg.Val == 0 &&
-        AM.IndexReg.Val == 0) {
+        AM.IndexReg.Val == 0 &&
+        !AM.isRIPRel) {
       if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1)))
         if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) {
           AM.Scale = unsigned(CN->getValue())-1;
@@ -817,7 +830,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
           // On x86-64, the resultant disp must fit in 32-bits.
           isInt32(AM.Disp + CN->getSignExtended()) &&
           // Check to see if the LHS & C is zero.
-          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) {
+          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
         AM.Disp += CN->getValue();
         return false;
       }
@@ -834,6 +847,9 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     
     // Scale must not be used already.
     if (AM.IndexReg.Val != 0 || AM.Scale != 1) break;
+
+    // Not when RIP is used as the base.
+    if (AM.isRIPRel) break;
       
     ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(N.getOperand(1));
     ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
@@ -874,7 +890,7 @@ bool X86DAGToDAGISel::MatchAddressBase(SDOperand N, X86ISelAddressMode &AM,
   // Is the base register already occupied?
   if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) {
     // If so, check to see if the scale index register is set.
-    if (AM.IndexReg.Val == 0) {
+    if (AM.IndexReg.Val == 0 && !AM.isRIPRel) {
       AM.IndexReg = N;
       AM.Scale = 1;
       return false;
@@ -1152,7 +1168,36 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
     case X86ISD::GlobalBaseReg: 
       return getGlobalBaseReg();
 
-    case X86ISD::FP_GET_RESULT2: {
+    // FIXME: This is a workaround for a tblgen problem: rdar://5791600
+    case X86ISD::RET_FLAG:
+      if (ConstantSDNode *Amt = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+        if (Amt->getSignExtended() != 0) break;
+        
+        // Match (X86retflag 0).
+        SDOperand Chain = N.getOperand(0);
+        bool HasInFlag = N.getOperand(N.getNumOperands()-1).getValueType()
+                          == MVT::Flag;
+        SmallVector<SDOperand, 8> Ops0;
+        AddToISelQueue(Chain);
+        SDOperand InFlag(0, 0);
+        if (HasInFlag) {
+          InFlag = N.getOperand(N.getNumOperands()-1);
+          AddToISelQueue(InFlag);
+        }
+        for (unsigned i = 2, e = N.getNumOperands()-(HasInFlag?1:0); i != e;
+             ++i) {
+          AddToISelQueue(N.getOperand(i));
+          Ops0.push_back(N.getOperand(i));
+        }
+        Ops0.push_back(Chain);
+        if (HasInFlag)
+          Ops0.push_back(InFlag);
+        return CurDAG->getTargetNode(X86::RET, MVT::Other,
+                                     &Ops0[0], Ops0.size());
+      }
+      break;
+      
+    case X86ISD::FP_GET_ST0_ST1: {
       SDOperand Chain = N.getOperand(0);
       SDOperand InFlag = N.getOperand(1);
       AddToISelQueue(Chain);
@@ -1163,7 +1208,7 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
       Tys.push_back(MVT::Other);
       Tys.push_back(MVT::Flag);
       SDOperand Ops[] = { Chain, InFlag };
-      SDNode *ResNode = CurDAG->getTargetNode(X86::FpGETRESULT80x2, Tys,
+      SDNode *ResNode = CurDAG->getTargetNode(X86::FpGET_ST0_ST1, Tys,
                                               Ops, 2);
       Chain = SDOperand(ResNode, 2);
       InFlag = SDOperand(ResNode, 3);
@@ -1219,15 +1264,6 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
       SDOperand N0 = Node->getOperand(0);
       SDOperand N1 = Node->getOperand(1);
 
-      // There are several forms of IMUL that just return the low part and
-      // don't have fixed-register operands. If we don't need the high part,
-      // use these instead. They can be selected with the generated ISel code.
-      if (NVT != MVT::i8 &&
-          N.getValue(1).use_empty()) {
-        N = CurDAG->getNode(ISD::MUL, NVT, N0, N1);
-        break;
-      }
-
       bool isSigned = Opcode == ISD::SMUL_LOHI;
       if (!isSigned)
         switch (NVT) {
@@ -1499,20 +1535,22 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
         SDOperand SRIdx;
         switch(N0.getValueType()) {
         case MVT::i32:
-          SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
           break;
         case MVT::i16:
-          SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
           break;
         case MVT::i8:
           if (Subtarget->is64Bit())
-            SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+            SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
           break;
         default: assert(0 && "Unknown any_extend!");
         }
         if (SRIdx.Val) {
+          SDOperand ImplVal = 
+              CurDAG->getTargetConstant(X86InstrInfo::IMPL_VAL_UNDEF, MVT::i32);
           SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
-                                                  NVT, N0, SRIdx);
+                                                  NVT, ImplVal, N0, SRIdx);
 
 #ifndef NDEBUG
           DOUT << std::string(Indent-2, ' ') << "=> ";