Add a chain to FORMAL_ARGUMENTS. This is a minimal port of the X86 backend,
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index 787436d35f2046f10c6853ec8bdd856e603e4ec2..8fc591b5d1bc1855a70040a62aa6ab62f4bf1549 100644 (file)
@@ -18,6 +18,7 @@
 #include "X86TargetMachine.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/ADT/VectorExtras.h"
@@ -206,10 +207,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     addRegisterClass(MVT::f32, X86::FR32RegisterClass);
     addRegisterClass(MVT::f64, X86::FR64RegisterClass);
 
-    // SSE has no load+extend ops
-    setOperationAction(ISD::EXTLOAD,  MVT::f32, Expand);
-    setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
-
     // Use ANDPD to simulate FABS.
     setOperationAction(ISD::FABS , MVT::f64, Custom);
     setOperationAction(ISD::FABS , MVT::f32, Custom);
@@ -366,12 +363,14 @@ X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   std::vector<SDOperand> Args = TargetLowering::LowerArguments(F, DAG);
 
   FormalArgs.clear();
-  // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be set
-  // before the rest of the function can be lowered.
+  FormalArgLocs.clear();
+
+  // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be
+  // set before the rest of the function can be lowered.
   if (F.getCallingConv() == CallingConv::Fast && EnableFastCC)
-    PreprocessFastCCArguments(Args[0], F, DAG);
+    PreprocessFastCCArguments(Args, F, DAG);
   else
-    PreprocessCCCArguments(Args[0], F, DAG);
+    PreprocessCCCArguments(Args, F, DAG);
   return Args;
 }
 
@@ -400,28 +399,117 @@ X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
 //                    C Calling Convention implementation
 //===----------------------------------------------------------------------===//
 
-void X86TargetLowering::PreprocessCCCArguments(SDOperand Op, Function &F,
-                                               SelectionDAG &DAG) {
-  unsigned NumArgs = Op.Val->getNumValues();
+/// AddLiveIn - This helper function adds the specified physical register to the
+/// MachineFunction as a live in value.  It also creates a corresponding virtual
+/// register for it.
+static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
+                          TargetRegisterClass *RC) {
+  assert(RC->contains(PReg) && "Not the correct regclass!");
+  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
+  MF.addLiveIn(PReg, VReg);
+  return VReg;
+}
+
+/// HowToPassCCCArgument - Returns how an formal argument of the specified type
+/// should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through XMM register, returns the number of XMM registers
+/// are needed.
+static void
+HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs,
+                     unsigned &ObjSize, unsigned &ObjXMMRegs) {
+  switch (ObjectVT) {
+  default: assert(0 && "Unhandled argument type!");
+  case MVT::i1:
+  case MVT::i8:  ObjSize = 1; break;
+  case MVT::i16: ObjSize = 2; break;
+  case MVT::i32: ObjSize = 4; break;
+  case MVT::i64: ObjSize = 8; break;
+  case MVT::f32: ObjSize = 4; break;
+  case MVT::f64: ObjSize = 8; break;
+  case MVT::v16i8:
+  case MVT::v8i16:
+  case MVT::v4i32:
+  case MVT::v2i64:
+  case MVT::v4f32:
+  case MVT::v2f64:
+    if (NumXMMRegs < 3)
+      ObjXMMRegs = 1;
+    else
+      ObjSize = 16;
+    break;
+  }
+}
+
+/// getFormalArgObjects - Returns itself if Op is a FORMAL_ARGUMENTS, otherwise
+/// returns the FORMAL_ARGUMENTS node(s) that made up parts of the node.
+static std::vector<SDOperand> getFormalArgObjects(SDOperand Op) {
+  unsigned Opc = Op.getOpcode();
+  std::vector<SDOperand> Objs;
+  if (Opc == ISD::TRUNCATE) {
+    Op = Op.getOperand(0);
+    assert(Op.getOpcode() == ISD::AssertSext ||
+           Op.getOpcode() == ISD::AssertZext);
+    Objs.push_back(Op.getOperand(0));
+  } else if (Opc == ISD::FP_ROUND || Opc == ISD::VBIT_CONVERT) {
+    Objs.push_back(Op.getOperand(0));
+  } else if (Opc == ISD::BUILD_PAIR) {
+    Objs.push_back(Op.getOperand(0));
+    Objs.push_back(Op.getOperand(1));
+  } else {
+    Objs.push_back(Op);
+  }
+  return Objs;
+}
+
+void X86TargetLowering::PreprocessCCCArguments(std::vector<SDOperand>Args,
+                                               Function &F, SelectionDAG &DAG) {
+  unsigned NumArgs = Args.size();
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
+  // Add DAG nodes to load the arguments...  On entry to a function on the X86,
+  // the stack frame looks like this:
+  //
+  // [ESP] -- return address
+  // [ESP + 4] -- first argument (leftmost lexically)
+  // [ESP + 8] -- second argument, if first argument is four bytes in size
+  //    ...
+  //
   unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  unsigned NumXMMRegs = 0;  // XMM regs used for parameter passing.
+  unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
   for (unsigned i = 0; i < NumArgs; ++i) {
-    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize;
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:  ObjSize = 1;                break;
-    case MVT::i16: ObjSize = 2;                break;
-    case MVT::i32: ObjSize = 4;                break;
-    case MVT::i64: ObjSize = ArgIncrement = 8; break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    SDOperand Op = Args[i];
+    std::vector<SDOperand> Objs = getFormalArgObjects(Op);
+    for (std::vector<SDOperand>::iterator I = Objs.begin(), E = Objs.end();
+         I != E; ++I) {
+      SDOperand Obj = *I;
+      MVT::ValueType ObjectVT = Obj.getValueType();
+      unsigned ArgIncrement = 4;
+      unsigned ObjSize = 0;
+      unsigned ObjXMMRegs = 0;
+      HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs);
+      if (ObjSize >= 8)
+        ArgIncrement = ObjSize;
+
+      if (ObjXMMRegs) {
+        // Passed in a XMM register.
+        unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
+                                 X86::VR128RegisterClass);
+        std::pair<FALocInfo, FALocInfo> Loc =
+          std::make_pair(FALocInfo(FALocInfo::LiveInRegLoc, Reg, ObjectVT),
+                         FALocInfo());
+        FormalArgLocs.push_back(Loc);
+        NumXMMRegs += ObjXMMRegs;
+      } else {
+        // Create the frame index object for this incoming parameter...
+        int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+        std::pair<FALocInfo, FALocInfo> Loc =
+          std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo());
+        FormalArgLocs.push_back(Loc);
+        ArgOffset += ArgIncrement;   // Move on to the next argument...
+      }
     }
-    ArgOffset += ArgIncrement;   // Move on to the next argument...
   }
 
   // If the function takes variable number of arguments, make a frame index for
@@ -434,43 +522,25 @@ void X86TargetLowering::PreprocessCCCArguments(SDOperand Op, Function &F,
 }
 
 void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) {
-  unsigned NumArgs = Op.Val->getNumValues();
+  unsigned NumArgs = Op.Val->getNumValues() - 1;
   MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
 
-  // Add DAG nodes to load the arguments...  On entry to a function on the X86,
-  // the stack frame looks like this:
-  //
-  // [ESP] -- return address
-  // [ESP + 4] -- first argument (leftmost lexically)
-  // [ESP + 8] -- second argument, if first argument is four bytes in size
-  //    ...
-  //
-  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
   for (unsigned i = 0; i < NumArgs; ++i) {
-    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize;
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:  ObjSize = 1;                break;
-    case MVT::i16: ObjSize = 2;                break;
-    case MVT::i32: ObjSize = 4;                break;
-    case MVT::i64: ObjSize = ArgIncrement = 8; break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    std::pair<FALocInfo, FALocInfo> Loc = FormalArgLocs[i];
+    SDOperand ArgValue;
+    if (Loc.first.Kind == FALocInfo::StackFrameLoc) {
+      // Create the SelectionDAG nodes corresponding to a load from this
+      // parameter.
+      unsigned FI = FormalArgLocs[i].first.Loc;
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+      ArgValue = DAG.getLoad(Op.Val->getValueType(i),
+                             DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
+    } else {
+      // Must be a CopyFromReg
+      ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+                                   Loc.first.Typ);
     }
-    // Create the frame index object for this incoming parameter...
-    int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-
-    // Create the SelectionDAG nodes corresponding to a load from this parameter
-    SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-    SDOperand ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                                     DAG.getSrcValue(NULL));
     FormalArgs.push_back(ArgValue);
-    ArgOffset += ArgIncrement;   // Move on to the next argument...
   }
 }
 
@@ -482,6 +552,11 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
   // Count how many bytes are to be pushed on the stack.
   unsigned NumBytes = 0;
 
+  // Keep track of the number of XMM regs passed so far.
+  unsigned NumXMMRegs = 0;
+  unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
+
+  std::vector<SDOperand> RegValuesToPass;
   if (Args.empty()) {
     // Save zero bytes.
     Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(0, getPointerTy()));
@@ -500,6 +575,12 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
       case MVT::f64:
         NumBytes += 8;
         break;
+      case MVT::Vector:
+        if (NumXMMRegs < 3)
+          ++NumXMMRegs;
+        else
+          NumBytes += 16;
+        break;
       }
 
     Chain = DAG.getCALLSEQ_START(Chain,
@@ -507,13 +588,10 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
 
     // Arguments go on the stack in reverse order, as specified by the ABI.
     unsigned ArgOffset = 0;
+    NumXMMRegs = 0;
     SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32);
     std::vector<SDOperand> Stores;
-
     for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-
       switch (getValueType(Args[i].second)) {
       default: assert(0 && "Unexpected ValueType for argument!");
       case MVT::i1:
@@ -528,21 +606,40 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
 
         // FALL THROUGH
       case MVT::i32:
-      case MVT::f32:
+      case MVT::f32: {
+        SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+        PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
         Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                      Args[i].first, PtrOff,
                                      DAG.getSrcValue(NULL)));
         ArgOffset += 4;
         break;
+      }
       case MVT::i64:
-      case MVT::f64:
+      case MVT::f64: {
+        SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+        PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
         Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                      Args[i].first, PtrOff,
                                      DAG.getSrcValue(NULL)));
         ArgOffset += 8;
         break;
       }
+      case MVT::Vector:
+        if (NumXMMRegs < 3) {
+          RegValuesToPass.push_back(Args[i].first);
+          NumXMMRegs++;
+        } else {
+          SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Args[i].first, PtrOff,
+                                       DAG.getSrcValue(NULL)));
+          ArgOffset += 16;
+        }
+      }
     }
+  if (!Stores.empty())
     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
   }
 
@@ -573,16 +670,35 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
     break;
   }
 
+  // Build a sequence of copy-to-reg nodes chained together with token chain
+  // and flag operands which copy the outgoing args into registers.
+  SDOperand InFlag;
+  for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
+    unsigned CCReg = XMMArgRegs[i];
+    SDOperand RegToPass = RegValuesToPass[i];
+    assert(RegToPass.getValueType() == MVT::Vector);
+    unsigned NumElems =
+      cast<ConstantSDNode>(*(RegToPass.Val->op_end()-2))->getValue();
+    MVT::ValueType EVT = cast<VTSDNode>(*(RegToPass.Val->op_end()-1))->getVT();
+    MVT::ValueType PVT = getVectorType(EVT, NumElems);
+    SDOperand CCRegNode = DAG.getRegister(CCReg, PVT);
+    RegToPass = DAG.getNode(ISD::VBIT_CONVERT, PVT, RegToPass);
+    Chain = DAG.getCopyToReg(Chain, CCRegNode, RegToPass, InFlag);
+    InFlag = Chain.getValue(1);
+  }
+
   std::vector<MVT::ValueType> NodeTys;
   NodeTys.push_back(MVT::Other);   // Returns a chain
   NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
   std::vector<SDOperand> Ops;
   Ops.push_back(Chain);
   Ops.push_back(Callee);
+  if (InFlag.Val)
+    Ops.push_back(InFlag);
 
   // FIXME: Do not generate X86ISD::TAILCALL for now.
   Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops);
-  SDOperand InFlag = Chain.getValue(1);
+  InFlag = Chain.getValue(1);
 
   NodeTys.clear();
   NodeTys.push_back(MVT::Other);   // Returns a chain
@@ -661,6 +777,16 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
         RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
       break;
     }
+    case MVT::Vector: {
+      const PackedType *PTy = cast<PackedType>(RetTy);
+      MVT::ValueType EVT;
+      MVT::ValueType LVT;
+      unsigned NumRegs = getPackedTypeBreakdown(PTy, EVT, LVT);
+      assert(NumRegs == 1 && "Unsupported type!");
+      RetVal = DAG.getCopyFromReg(Chain, X86::XMM0, EVT, InFlag);
+      Chain = RetVal.getValue(1);
+      break;
+    }
     }
   }
 
@@ -684,17 +810,6 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
 // (when we have a global fp allocator) and do other tricks.
 //
 
-/// AddLiveIn - This helper function adds the specified physical register to the
-/// MachineFunction as a live in value.  It also creates a corresponding virtual
-/// register for it.
-static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
-                          TargetRegisterClass *RC) {
-  assert(RC->contains(PReg) && "Not the correct regclass!");
-  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
-  MF.addLiveIn(PReg, VReg);
-  return VReg;
-}
-
 // FASTCC_NUM_INT_ARGS_INREGS - This is the max number of integer arguments
 // to pass in registers.  0 is none, 1 is is "use EAX", 2 is "use EAX and
 // EDX".  Anything more is illegal.
@@ -715,68 +830,177 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
 static unsigned FASTCC_NUM_INT_ARGS_INREGS = 0;
 
 
+/// HowToPassFastCCArgument - Returns how an formal argument of the specified
+/// type should be passed. If it is through stack, returns the size of the stack
+/// frame; if it is through integer or XMM register, returns the number of
+/// integer or XMM registers are needed.
+static void
+HowToPassFastCCArgument(MVT::ValueType ObjectVT,
+                        unsigned NumIntRegs, unsigned NumXMMRegs,
+                        unsigned &ObjSize, unsigned &ObjIntRegs,
+                        unsigned &ObjXMMRegs) {
+  ObjSize = 0;
+  NumIntRegs = 0;
+
+  switch (ObjectVT) {
+  default: assert(0 && "Unhandled argument type!");
+  case MVT::i1:
+  case MVT::i8:
+    if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
+      ObjIntRegs = 1;
+    else
+      ObjSize = 1;
+    break;
+  case MVT::i16:
+    if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
+      ObjIntRegs = 1;
+    else
+      ObjSize = 2;
+    break;
+  case MVT::i32:
+    if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
+      ObjIntRegs = 1;
+    else
+      ObjSize = 4;
+    break;
+  case MVT::i64:
+    if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
+      ObjIntRegs = 2;
+    } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
+      ObjIntRegs = 1;
+      ObjSize = 4;
+    } else
+      ObjSize = 8;
+  case MVT::f32:
+    ObjSize = 4;
+    break;
+  case MVT::f64:
+    ObjSize = 8;
+    break;
+  case MVT::v16i8:
+  case MVT::v8i16:
+  case MVT::v4i32:
+  case MVT::v2i64:
+  case MVT::v4f32:
+  case MVT::v2f64:
+    if (NumXMMRegs < 3)
+      ObjXMMRegs = 1;
+    else
+      ObjSize = 16;
+    break;
+  }
+}
+
 void
-X86TargetLowering::PreprocessFastCCArguments(SDOperand Op, Function &F,
-                                             SelectionDAG &DAG) {
-  unsigned NumArgs = Op.Val->getNumValues();
+X86TargetLowering::PreprocessFastCCArguments(std::vector<SDOperand>Args,
+                                             Function &F, SelectionDAG &DAG) {
+  unsigned NumArgs = Args.size();
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
+  // Add DAG nodes to load the arguments...  On entry to a function the stack
+  // frame looks like this:
+  //
+  // [ESP] -- return address
+  // [ESP + 4] -- first nonreg argument (leftmost lexically)
+  // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size
+  //    ...
   unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
 
   // Keep track of the number of integer regs passed so far.  This can be either
   // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
   // used).
   unsigned NumIntRegs = 0;
+  unsigned NumXMMRegs = 0;  // XMM regs used for parameter passing.
+  unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 };
   
   for (unsigned i = 0; i < NumArgs; ++i) {
-    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize = 0;
-    SDOperand ArgValue;
-
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        ++NumIntRegs;
-        break;
-      }
-
-      ObjSize = 1;
-      break;
-    case MVT::i16:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        ++NumIntRegs;
-        break;
-      }
-      ObjSize = 2;
-      break;
-    case MVT::i32:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        ++NumIntRegs;
-        break;
+    SDOperand Op = Args[i];
+    std::vector<SDOperand> Objs = getFormalArgObjects(Op);
+    for (std::vector<SDOperand>::iterator I = Objs.begin(), E = Objs.end();
+         I != E; ++I) {
+      SDOperand Obj = *I;
+      MVT::ValueType ObjectVT = Obj.getValueType();
+      unsigned ArgIncrement = 4;
+      unsigned ObjSize = 0;
+      unsigned ObjIntRegs = 0;
+      unsigned ObjXMMRegs = 0;
+
+      HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs,
+                              ObjSize, ObjIntRegs, ObjXMMRegs);
+      if (ObjSize >= 8)
+        ArgIncrement = ObjSize;
+
+      unsigned Reg;
+      std::pair<FALocInfo,FALocInfo> Loc = std::make_pair(FALocInfo(),
+                                                          FALocInfo());
+      if (ObjIntRegs) {
+        switch (ObjectVT) {
+        default: assert(0 && "Unhandled argument type!");
+        case MVT::i1:
+        case MVT::i8:
+          Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
+                          X86::R8RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = MVT::i8;
+          break;
+        case MVT::i16:
+          Reg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
+                          X86::R16RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = MVT::i16;
+          break;
+        case MVT::i32:
+          Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
+                          X86::R32RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = MVT::i32;
+          break;
+        case MVT::i64:
+          Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
+                          X86::R32RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = MVT::i32;
+          if (ObjIntRegs == 2) {
+            Reg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
+            Loc.second.Kind = FALocInfo::LiveInRegLoc;
+            Loc.second.Loc = Reg;
+            Loc.second.Typ = MVT::i32;
+          }
+          break;
+        case MVT::v16i8:
+        case MVT::v8i16:
+        case MVT::v4i32:
+        case MVT::v2i64:
+        case MVT::v4f32:
+        case MVT::v2f64:
+          Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass);
+          Loc.first.Kind = FALocInfo::LiveInRegLoc;
+          Loc.first.Loc = Reg;
+          Loc.first.Typ = ObjectVT;
+          break;
+        }
+        NumIntRegs += ObjIntRegs;
+        NumXMMRegs += ObjXMMRegs;
       }
-      ObjSize = 4;
-      break;
-    case MVT::i64:
-      if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        NumIntRegs += 2;
-        break;
-      } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        ArgOffset += 4;
-        NumIntRegs = FASTCC_NUM_INT_ARGS_INREGS;
-        break;
+      if (ObjSize) {
+        int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+        if (ObjectVT == MVT::i64 && ObjIntRegs) {
+          Loc.second.Kind = FALocInfo::StackFrameLoc;
+          Loc.second.Loc = FI;
+        } else {
+          Loc.first.Kind = FALocInfo::StackFrameLoc;
+          Loc.first.Loc = FI;
+        }
+        ArgOffset += ArgIncrement;   // Move on to the next argument.
       }
-      ObjSize = ArgIncrement = 8;
-      break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
-    }
 
-    if (ObjSize)
-      ArgOffset += ArgIncrement;   // Move on to the next argument.
+      FormalArgLocs.push_back(Loc);
+    }
   }
 
   // Make sure the instruction takes 8n+4 bytes to make sure the start of the
@@ -807,134 +1031,53 @@ X86TargetLowering::PreprocessFastCCArguments(SDOperand Op, Function &F,
   case MVT::f64:
     MF.addLiveOut(X86::ST0);
     break;
+  case MVT::Vector: {
+    const PackedType *PTy = cast<PackedType>(F.getReturnType());
+    MVT::ValueType EVT;
+    MVT::ValueType LVT;
+    unsigned NumRegs = getPackedTypeBreakdown(PTy, EVT, LVT);
+    assert(NumRegs == 1 && "Unsupported type!");
+    MF.addLiveOut(X86::XMM0);
+    break;
+  }
   }
 }
+
 void
 X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) {
-  unsigned NumArgs = Op.Val->getNumValues();
+  unsigned NumArgs = Op.Val->getNumValues()-1;
   MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
 
-  // Add DAG nodes to load the arguments...  On entry to a function the stack
-  // frame looks like this:
-  //
-  // [ESP] -- return address
-  // [ESP + 4] -- first nonreg argument (leftmost lexically)
-  // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size
-  //    ...
-  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
-
-  // Keep track of the number of integer regs passed so far.  This can be either
-  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
-  // used).
-  unsigned NumIntRegs = 0;
-  
   for (unsigned i = 0; i < NumArgs; ++i) {
-    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize = 0;
+    MVT::ValueType VT = Op.Val->getValueType(i);
+    std::pair<FALocInfo, FALocInfo> Loc = FormalArgLocs[i];
     SDOperand ArgValue;
-    bool hasUse = !Op.Val->hasNUsesOfValue(0, i);
-
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (hasUse) {
-          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
-                                    X86::R8RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8);
-          DAG.setRoot(ArgValue.getValue(1));
-          if (ObjectVT == MVT::i1)
-            // FIXME: Should insert a assertzext here.
-            ArgValue = DAG.getNode(ISD::TRUNCATE, MVT::i1, ArgValue);
-        }
-        ++NumIntRegs;
-        break;
-      }
-
-      ObjSize = 1;
-      break;
-    case MVT::i16:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (hasUse) {
-          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
-                                    X86::R16RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16);
-          DAG.setRoot(ArgValue.getValue(1));
-        }
-        ++NumIntRegs;
-        break;
-      }
-      ObjSize = 2;
-      break;
-    case MVT::i32:
-      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (hasUse) {
-          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
-                                    X86::R32RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
-          DAG.setRoot(ArgValue.getValue(1));
-        }
-        ++NumIntRegs;
-        break;
-      }
-      ObjSize = 4;
-      break;
-    case MVT::i64:
-      if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        if (hasUse) {
-          unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
-          unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
-
-          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
-          SDOperand Hi  = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32);
-          DAG.setRoot(Hi.getValue(1));
-
-          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
-        }
-        NumIntRegs += 2;
-        break;
-      } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        if (hasUse) {
-          unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
-          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
-          DAG.setRoot(Low.getValue(1));
-
-          // Load the high part from memory.
-          // Create the frame index object for this incoming parameter...
-          int FI = MFI->CreateFixedObject(4, ArgOffset);
-          SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-          SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
-                                     DAG.getSrcValue(NULL));
-          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
-        }
-        ArgOffset += 4;
-        NumIntRegs = FASTCC_NUM_INT_ARGS_INREGS;
-        break;
-      }
-      ObjSize = ArgIncrement = 8;
-      break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
-    }
-
-    if (ObjSize) {
-      // Create the frame index object for this incoming parameter...
-      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-
+    if (Loc.first.Kind == FALocInfo::StackFrameLoc) {
       // Create the SelectionDAG nodes corresponding to a load from this
       // parameter.
-      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
+      SDOperand FIN = DAG.getFrameIndex(Loc.first.Loc, MVT::i32);
+      ArgValue = DAG.getLoad(Op.Val->getValueType(i), DAG.getEntryNode(), FIN,
                              DAG.getSrcValue(NULL));
-    } else if (ArgValue.Val == 0) {
-      if (MVT::isInteger(ObjectVT))
-        ArgValue = DAG.getConstant(0, ObjectVT);
-      else
-        ArgValue = DAG.getConstantFP(0, ObjectVT);
+    } else {
+      // Must be a CopyFromReg
+      ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc,
+                                   Loc.first.Typ);
+    }
+
+    if (Loc.second.Kind != FALocInfo::None) {
+      SDOperand ArgValue2;
+      if (Loc.second.Kind == FALocInfo::StackFrameLoc) {
+        // Create the SelectionDAG nodes corresponding to a load from this
+        // parameter.
+        SDOperand FIN = DAG.getFrameIndex(Loc.second.Loc, MVT::i32);
+        ArgValue2 = DAG.getLoad(Op.Val->getValueType(i), DAG.getEntryNode(),
+                                FIN, DAG.getSrcValue(NULL));
+      } else {
+        // Must be a CopyFromReg
+        ArgValue2 = DAG.getCopyFromReg(DAG.getEntryNode(),
+                                       Loc.second.Loc, Loc.second.Typ);
+      }
+      ArgValue = DAG.getNode(ISD::BUILD_PAIR, VT, ArgValue, ArgValue2);
     }
     FormalArgs.push_back(ArgValue);
   }
@@ -1124,7 +1267,8 @@ X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
     Ops.push_back(InFlag);
 
   // FIXME: Do not generate X86ISD::TAILCALL for now.
-  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops);
+  Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
+                      NodeTys, Ops);
   InFlag = Chain.getValue(1);
 
   NodeTys.clear();
@@ -2597,10 +2741,55 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
   }
 
   if (NumElems == 4) {
-    // Break it into (shuffle shuffle_hi, shuffle_lo).
     MVT::ValueType MaskVT = PermMask.getValueType();
     MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
-    std::map<unsigned, std::pair<int, int> > Locs;
+    std::vector<std::pair<int, int> > Locs;
+    Locs.reserve(NumElems);
+    std::vector<SDOperand> Mask1(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
+    std::vector<SDOperand> Mask2(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
+    unsigned NumHi = 0;
+    unsigned NumLo = 0;
+    // If no more than two elements come from either vector. This can be
+    // implemented with two shuffles. First shuffle gather the elements.
+    // The second shuffle, which takes the first shuffle as both of its
+    // vector operands, put the elements into the right order.
+    for (unsigned i = 0; i != NumElems; ++i) {
+      SDOperand Elt = PermMask.getOperand(i);
+      if (Elt.getOpcode() == ISD::UNDEF) {
+        Locs[i] = std::make_pair(-1, -1);
+      } else {
+        unsigned Val = cast<ConstantSDNode>(Elt)->getValue();
+        if (Val < NumElems) {
+          Locs[i] = std::make_pair(0, NumLo);
+          Mask1[NumLo] = Elt;
+          NumLo++;
+        } else {
+          Locs[i] = std::make_pair(1, NumHi);
+          if (2+NumHi < NumElems)
+            Mask1[2+NumHi] = Elt;
+          NumHi++;
+        }
+      }
+    }
+    if (NumLo <= 2 && NumHi <= 2) {
+      V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
+                       DAG.getNode(ISD::BUILD_VECTOR, MaskVT, Mask1));
+      for (unsigned i = 0; i != NumElems; ++i) {
+        if (Locs[i].first == -1)
+          continue;
+        else {
+          unsigned Idx = (i < NumElems/2) ? 0 : NumElems;
+          Idx += Locs[i].first * (NumElems/2) + Locs[i].second;
+          Mask2[i] = DAG.getConstant(Idx, MaskEVT);
+        }
+      }
+
+      return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1,
+                         DAG.getNode(ISD::BUILD_VECTOR, MaskVT, Mask2));
+    }
+
+    // Break it into (shuffle shuffle_hi, shuffle_lo).
+    Locs.clear();
     std::vector<SDOperand> LoMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
     std::vector<SDOperand> HiMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
     std::vector<SDOperand> *MaskPtr = &LoMask;
@@ -2628,10 +2817,12 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
       }
     }
 
-    SDOperand LoShuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
-                                      DAG.getNode(ISD::BUILD_VECTOR, MaskVT, LoMask));
-    SDOperand HiShuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
-                                      DAG.getNode(ISD::BUILD_VECTOR, MaskVT, HiMask));
+    SDOperand LoShuffle =
+      DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
+                  DAG.getNode(ISD::BUILD_VECTOR, MaskVT, LoMask));
+    SDOperand HiShuffle = 
+      DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
+                  DAG.getNode(ISD::BUILD_VECTOR, MaskVT, HiMask));
     std::vector<SDOperand> MaskOps;
     for (unsigned i = 0; i != NumElems; ++i) {
       if (Locs[i].first == -1) {
@@ -2794,12 +2985,14 @@ SDOperand
 X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
-                                 DAG.getTargetGlobalAddress(GV, getPointerTy()));
+                                 DAG.getTargetGlobalAddress(GV,
+                                                            getPointerTy()));
   if (Subtarget->isTargetDarwin()) {
     // With PIC, the address is actually $g + Offset.
     if (getTargetMachine().getRelocationModel() == Reloc::PIC)
       Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
+                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                           Result);
 
     // For Darwin, external and weak symbols are indirect, so we want to load
     // the value at address GV, not the value of GV itself. This means that
@@ -2818,12 +3011,14 @@ SDOperand
 X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
   const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
   SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
-                                 DAG.getTargetExternalSymbol(Sym, getPointerTy()));
+                                 DAG.getTargetExternalSymbol(Sym,
+                                                             getPointerTy()));
   if (Subtarget->isTargetDarwin()) {
     // With PIC, the address is actually $g + Offset.
     if (getTargetMachine().getRelocationModel() == Reloc::PIC)
       Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
+                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                           Result);
   }
 
   return Result;
@@ -3207,7 +3402,8 @@ SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
     // With PIC, the address is actually $g + Offset.
     if (getTargetMachine().getRelocationModel() == Reloc::PIC)
       Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);    
+                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                           Result);    
   }
 
   return Result;
@@ -3310,7 +3506,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
 SDOperand
 X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
   if (FormalArgs.size() == 0) {
-    unsigned CC = cast<ConstantSDNode>(Op.getOperand(0))->getValue();
+    unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
     if (CC == CallingConv::Fast && EnableFastCC)
       LowerFastCCArguments(Op, DAG);
     else
@@ -3332,7 +3528,7 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
   if ((Align & 3) != 0 ||
       (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
     MVT::ValueType IntPtr = getPointerTy();
-    const Type *IntPtrTy = getTargetData().getIntPtrType();
+    const Type *IntPtrTy = getTargetData()->getIntPtrType();
     std::vector<std::pair<SDOperand, const Type*> > Args;
     Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
     // Extend the ubyte argument to be an int value for the call.
@@ -3465,7 +3661,7 @@ SDOperand X86TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
   if ((Align & 3) != 0 ||
       (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
     MVT::ValueType IntPtr = getPointerTy();
-    const Type *IntPtrTy = getTargetData().getIntPtrType();
+    const Type *IntPtrTy = getTargetData()->getIntPtrType();
     std::vector<std::pair<SDOperand, const Type*> > Args;
     Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
     Args.push_back(std::make_pair(Op.getOperand(2), IntPtrTy));
@@ -3812,14 +4008,34 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint,
     default: break;  // Unknown constriant letter
     case 'r':   // GENERAL_REGS
     case 'R':   // LEGACY_REGS
-      return make_vector<unsigned>(X86::EAX, X86::EBX, X86::ECX, X86::EDX,
-                                   X86::ESI, X86::EDI, X86::EBP, X86::ESP, 0);
+      if (VT == MVT::i32)
+        return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX,
+                                     X86::ESI, X86::EDI, X86::EBP, X86::ESP, 0);
+      else if (VT == MVT::i16)
+        return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX, 
+                                     X86::SI, X86::DI, X86::BP, X86::SP, 0);
+      else if (VT == MVT::i8)
+        return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
+      break;
     case 'l':   // INDEX_REGS
-      return make_vector<unsigned>(X86::EAX, X86::EBX, X86::ECX, X86::EDX,
-                                   X86::ESI, X86::EDI, X86::EBP, 0);
+      if (VT == MVT::i32)
+        return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX,
+                                     X86::ESI, X86::EDI, X86::EBP, 0);
+      else if (VT == MVT::i16)
+        return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX, 
+                                     X86::SI, X86::DI, X86::BP, 0);
+      else if (VT == MVT::i8)
+        return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
+      break;
     case 'q':   // Q_REGS (GENERAL_REGS in 64-bit mode)
     case 'Q':   // Q_REGS
-      return make_vector<unsigned>(X86::EAX, X86::EBX, X86::ECX, X86::EDX, 0);
+      if (VT == MVT::i32)
+        return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX, 0);
+      else if (VT == MVT::i16)
+        return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX, 0);
+      else if (VT == MVT::i8)
+        return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
+        break;
     case 'x':   // SSE_REGS if SSE1 allowed
       if (Subtarget->hasSSE1())
         return make_vector<unsigned>(X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,