Fix spelling and grammar in a comment.
[oota-llvm.git] / lib / Target / Alpha / AlphaISelLowering.cpp
index 6d53a9e59c4c835724e8736e473edb498ead3859..dd001b4f168779826ea9a0dd39e5fdaf01b8c7bf 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Andrew Lenharth and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/Module.h"
 #include "llvm/Support/CommandLine.h"
-#include <iostream>
-
 using namespace llvm;
 
 /// AddLiveIn - This helper function adds the specified physical register to the
@@ -32,8 +31,8 @@ using namespace llvm;
 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);
+  unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
+  MF.getRegInfo().addLiveIn(PReg, VReg);
   return VReg;
 }
 
@@ -41,7 +40,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   // Set up the TargetLowering object.
   //I am having problems with shr n ubyte 1
   setShiftAmountType(MVT::i64);
-  setSetCCResultType(MVT::i64);
   setSetCCResultContents(ZeroOrOneSetCCResult);
   
   setUsesGlobalOffsetTable(true);
@@ -60,8 +58,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setLoadXAction(ISD::SEXTLOAD, MVT::i8,  Expand);
   setLoadXAction(ISD::SEXTLOAD, MVT::i16, Expand);
 
-  setStoreXAction(MVT::i1, Promote);
-  
   //  setOperationAction(ISD::BRIND,        MVT::Other,   Expand);
   setOperationAction(ISD::BR_JT,        MVT::Other, Expand);
   setOperationAction(ISD::BR_CC,        MVT::Other, Expand);
@@ -91,11 +87,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setOperationAction(ISD::SDIV     , MVT::i64, Custom);
   setOperationAction(ISD::UDIV     , MVT::i64, Custom);
 
-  setOperationAction(ISD::MEMMOVE  , MVT::Other, Expand);
-  setOperationAction(ISD::MEMSET   , MVT::Other, Expand);
-  setOperationAction(ISD::MEMCPY   , MVT::Other, Expand);
-  
-  // We don't support sin/cos/sqrt
+  // We don't support sin/cos/sqrt/pow
   setOperationAction(ISD::FSIN , MVT::f64, Expand);
   setOperationAction(ISD::FCOS , MVT::f64, Expand);
   setOperationAction(ISD::FSIN , MVT::f32, Expand);
@@ -103,13 +95,18 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
 
   setOperationAction(ISD::FSQRT, MVT::f64, Expand);
   setOperationAction(ISD::FSQRT, MVT::f32, Expand);
+
+  setOperationAction(ISD::FPOW , MVT::f32, Expand);
+  setOperationAction(ISD::FPOW , MVT::f64, Expand);
   
   setOperationAction(ISD::SETCC, MVT::f32, Promote);
 
+  setOperationAction(ISD::BIT_CONVERT, MVT::f32, Promote);
+
   // We don't have line number support yet.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
-  setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
+  setOperationAction(ISD::LABEL, MVT::Other, Expand);
 
   // Not implemented yet.
   setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 
@@ -122,6 +119,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setOperationAction(ISD::GlobalAddress,  MVT::i64, Custom);
   setOperationAction(ISD::ConstantPool,   MVT::i64, Custom);
   setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
 
   setOperationAction(ISD::VASTART, MVT::Other, Custom);
   setOperationAction(ISD::VAEND,   MVT::Other, Expand);
@@ -136,24 +134,24 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
 
   setStackPointerRegisterToSaveRestore(Alpha::R30);
 
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
-  addLegalFPImmediate(+0.0); //F31
-  addLegalFPImmediate(-0.0); //-F31
+  addLegalFPImmediate(APFloat(+0.0)); //F31
+  addLegalFPImmediate(APFloat(+0.0f)); //F31
+  addLegalFPImmediate(APFloat(-0.0)); //-F31
+  addLegalFPImmediate(APFloat(-0.0f)); //-F31
 
   setJumpBufSize(272);
   setJumpBufAlignment(16);
 
   computeRegisterProperties();
+}
 
-  useITOF = TM.getSubtarget<AlphaSubtarget>().hasF2I();
+MVT AlphaTargetLowering::getSetCCResultType(const SDOperand &) const {
+  return MVT::i64;
 }
 
 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (Opcode) {
   default: return 0;
-  case AlphaISD::ITOFT_: return "Alpha::ITOFT_";
-  case AlphaISD::FTOIT_: return "Alpha::FTOIT_";
   case AlphaISD::CVTQT_: return "Alpha::CVTQT_";
   case AlphaISD::CVTQS_: return "Alpha::CVTQS_";
   case AlphaISD::CVTTQ_: return "Alpha::CVTTQ_";
@@ -170,13 +168,13 @@ const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const {
 }
 
 static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType PtrVT = Op.getValueType();
+  MVT PtrVT = Op.getValueType();
   JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
   SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
   SDOperand Zero = DAG.getConstant(0, PtrVT);
   
   SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi,  MVT::i64, JTI,
-                            DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
+                             DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
   SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, JTI, Hi);
   return Lo;
 }
@@ -201,8 +199,8 @@ static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
 // //#define SP    $30
 
 static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
-                                      int &VarArgsBase,
-                                      int &VarArgsOffset) {
+                                       int &VarArgsBase,
+                                       int &VarArgsOffset) {
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   std::vector<SDOperand> ArgValues;
@@ -218,27 +216,26 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   
   for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
     SDOperand argt;
-    MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
+    MVT ObjectVT = Op.getValue(ArgNo).getValueType();
     SDOperand ArgVal;
 
     if (ArgNo  < 6) {
-      switch (ObjectVT) {
+      switch (ObjectVT.getSimpleVT()) {
       default:
-        std::cerr << "Unknown Type " << ObjectVT << "\n";
-        abort();
+        assert(false && "Invalid value type!");
       case MVT::f64:
         args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], 
-                                     &Alpha::F8RCRegClass);
+                                      &Alpha::F8RCRegClass);
         ArgVal = DAG.getCopyFromReg(Root, args_float[ArgNo], ObjectVT);
         break;
       case MVT::f32:
         args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], 
-                                     &Alpha::F4RCRegClass);
+                                      &Alpha::F4RCRegClass);
         ArgVal = DAG.getCopyFromReg(Root, args_float[ArgNo], ObjectVT);
         break;
       case MVT::i64:
         args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo], 
-                                   &Alpha::GPRCRegClass);
+                                    &Alpha::GPRCRegClass);
         ArgVal = DAG.getCopyFromReg(Root, args_int[ArgNo], MVT::i64);
         break;
       }
@@ -260,7 +257,7 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
     VarArgsOffset = (Op.Val->getNumValues()-1) * 8;
     std::vector<SDOperand> LS;
     for (int i = 0; i < 6; ++i) {
-      if (MRegisterInfo::isPhysicalRegister(args_int[i]))
+      if (TargetRegisterInfo::isPhysicalRegister(args_int[i]))
         args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass);
       SDOperand argt = DAG.getCopyFromReg(Root, args_int[i], MVT::i64);
       int FI = MFI->CreateFixedObject(8, -8 * (6 - i));
@@ -268,7 +265,7 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64);
       LS.push_back(DAG.getStore(Root, argt, SDFI, NULL, 0));
 
-      if (MRegisterInfo::isPhysicalRegister(args_float[i]))
+      if (TargetRegisterInfo::isPhysicalRegister(args_float[i]))
         args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass);
       argt = DAG.getCopyFromReg(Root, args_float[i], MVT::f64);
       FI = MFI->CreateFixedObject(8, - 8 * (12 - i));
@@ -283,16 +280,16 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   ArgValues.push_back(Root);
 
   // Return the new list of results.
-  std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
+  std::vector<MVT> RetVT(Op.Val->value_begin(),
                                     Op.Val->value_end());
   return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
 }
 
 static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Copy = DAG.getCopyToReg(Op.getOperand(0), Alpha::R26, 
-                                   DAG.getNode(AlphaISD::GlobalRetAddr, 
-                                    MVT::i64),
-                                   SDOperand());
+                                    DAG.getNode(AlphaISD::GlobalRetAddr, 
+                                                MVT::i64),
+                                    SDOperand());
   switch (Op.getNumOperands()) {
   default:
     assert(0 && "Do not know how to return this many arguments!");
@@ -301,17 +298,17 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
     break;
     //return SDOperand(); // ret void is legal
   case 3: {
-    MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
+    MVT ArgVT = Op.getOperand(1).getValueType();
     unsigned ArgReg;
-    if (MVT::isInteger(ArgVT))
+    if (ArgVT.isInteger())
       ArgReg = Alpha::R0;
     else {
-      assert(MVT::isFloatingPoint(ArgVT));
+      assert(ArgVT.isFloatingPoint());
       ArgReg = Alpha::F0;
     }
     Copy = DAG.getCopyToReg(Copy, ArgReg, Op.getOperand(1), Copy.getValue(1));
-    if(DAG.getMachineFunction().liveout_empty())
-      DAG.getMachineFunction().addLiveOut(ArgReg);
+    if (DAG.getMachineFunction().getRegInfo().liveout_empty())
+      DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg);
     break;
   }
   }
@@ -319,8 +316,8 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
 }
 
 std::pair<SDOperand, SDOperand>
-AlphaTargetLowering::LowerCallTo(SDOperand Chain,
-                                 const Type *RetTy, bool isVarArg,
+AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, 
+                                 bool RetSExt, bool RetZExt, bool isVarArg,
                                  unsigned CallingConv, bool isTailCall,
                                  SDOperand Callee, ArgListTy &Args,
                                  SelectionDAG &DAG) {
@@ -333,7 +330,7 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
   std::vector<SDOperand> args_to_use;
   for (unsigned i = 0, e = Args.size(); i != e; ++i)
   {
-    switch (getValueType(Args[i].second)) {
+    switch (getValueType(Args[i].Ty).getSimpleVT()) {
     default: assert(0 && "Unexpected ValueType for argument!");
     case MVT::i1:
     case MVT::i8:
@@ -341,23 +338,25 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
     case MVT::i32:
       // Promote the integer to 64 bits.  If the input type is signed use a
       // sign extend, otherwise use a zero extend.
-      if (Args[i].second->isSigned())
-        Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
+      if (Args[i].isSExt)
+        Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].Node);
+      else if (Args[i].isZExt)
+        Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].Node);
       else
-        Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
+        Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, MVT::i64, Args[i].Node);
       break;
     case MVT::i64:
     case MVT::f64:
     case MVT::f32:
       break;
     }
-    args_to_use.push_back(Args[i].first);
+    args_to_use.push_back(Args[i].Node);
   }
 
-  std::vector<MVT::ValueType> RetVals;
-  MVT::ValueType RetTyVT = getValueType(RetTy);
-  MVT::ValueType ActualRetTyVT = RetTyVT;
-  if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i32)
+  std::vector<MVT> RetVals;
+  MVT RetTyVT = getValueType(RetTy);
+  MVT ActualRetTyVT = RetTyVT;
+  if (RetTyVT.getSimpleVT() >= MVT::i1 && RetTyVT.getSimpleVT() <= MVT::i32)
     ActualRetTyVT = MVT::i64;
 
   if (RetTyVT != MVT::isVoid)
@@ -370,13 +369,23 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
   Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end());
   SDOperand TheCall = DAG.getNode(AlphaISD::CALL, RetVals, &Ops[0], Ops.size());
   Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, getPointerTy()));
+  Chain = DAG.getCALLSEQ_END(Chain,
+                             DAG.getConstant(NumBytes, getPointerTy()),
+                             DAG.getConstant(0, getPointerTy()),
+                             SDOperand());
   SDOperand RetVal = TheCall;
 
   if (RetTyVT != ActualRetTyVT) {
-    RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext,
-                         MVT::i64, RetVal, DAG.getValueType(RetTyVT));
+    ISD::NodeType AssertKind = ISD::DELETED_NODE;
+    if (RetSExt)
+      AssertKind = ISD::AssertSext;
+    else if (RetZExt)
+      AssertKind = ISD::AssertZext;
+
+    if (AssertKind != ISD::DELETED_NODE)
+      RetVal = DAG.getNode(AssertKind, MVT::i64, RetVal,
+                           DAG.getValueType(RetTyVT));
+
     RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
   }
 
@@ -389,33 +398,24 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Wasn't expecting to be able to lower this!");
   case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, 
-                                                          VarArgsBase,
-                                                          VarArgsOffset);
+                                                           VarArgsBase,
+                                                           VarArgsOffset);
 
   case ISD::RET: return LowerRET(Op,DAG);
   case ISD::JumpTable: return LowerJumpTable(Op, DAG);
 
   case ISD::SINT_TO_FP: {
-    assert(MVT::i64 == Op.getOperand(0).getValueType() && 
+    assert(Op.getOperand(0).getValueType() == MVT::i64 &&
            "Unhandled SINT_TO_FP type in custom expander!");
     SDOperand LD;
-    bool isDouble = MVT::f64 == Op.getValueType();
-    if (useITOF) {
-      LD = DAG.getNode(AlphaISD::ITOFT_, MVT::f64, Op.getOperand(0));
-    } else {
-      int FrameIdx =
-        DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
-      SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i64);
-      SDOperand ST = DAG.getStore(DAG.getEntryNode(),
-                                  Op.getOperand(0), FI, NULL, 0);
-      LD = DAG.getLoad(MVT::f64, ST, FI, NULL, 0);
-      }
+    bool isDouble = Op.getValueType() == MVT::f64;
+    LD = DAG.getNode(ISD::BIT_CONVERT, MVT::f64, Op.getOperand(0));
     SDOperand FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_,
                                isDouble?MVT::f64:MVT::f32, LD);
     return FP;
   }
   case ISD::FP_TO_SINT: {
-    bool isDouble = MVT::f64 == Op.getOperand(0).getValueType();
+    bool isDouble = Op.getOperand(0).getValueType() == MVT::f64;
     SDOperand src = Op.getOperand(0);
 
     if (!isDouble) //Promote
@@ -423,15 +423,7 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     
     src = DAG.getNode(AlphaISD::CVTTQ_, MVT::f64, src);
 
-    if (useITOF) {
-      return DAG.getNode(AlphaISD::FTOIT_, MVT::i64, src);
-    } else {
-      int FrameIdx =
-        DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
-      SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i64);
-      SDOperand ST = DAG.getStore(DAG.getEntryNode(), src, FI, NULL, 0);
-      return DAG.getLoad(MVT::i64, ST, FI, NULL, 0);
-      }
+    return DAG.getNode(ISD::BIT_CONVERT, MVT::i64, src);
   }
   case ISD::ConstantPool: {
     ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
@@ -439,40 +431,42 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment());
     
     SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi,  MVT::i64, CPI,
-                              DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
+                               DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
     SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, CPI, Hi);
     return Lo;
   }
+  case ISD::GlobalTLSAddress:
+    assert(0 && "TLS not implemented for Alpha.");
   case ISD::GlobalAddress: {
     GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
     GlobalValue *GV = GSDN->getGlobal();
     SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i64, GSDN->getOffset());
 
-    //    if (!GV->hasWeakLinkage() && !GV->isExternal() && !GV->hasLinkOnceLinkage()) {
+    //    if (!GV->hasWeakLinkage() && !GV->isDeclaration() && !GV->hasLinkOnceLinkage()) {
     if (GV->hasInternalLinkage()) {
       SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi,  MVT::i64, GA,
-                                DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
+                                DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
       SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, GA, Hi);
       return Lo;
     } else
       return DAG.getNode(AlphaISD::RelLit, MVT::i64, GA, 
-                        DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
+                         DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
   }
   case ISD::ExternalSymbol: {
     return DAG.getNode(AlphaISD::RelLit, MVT::i64, 
-                      DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)
-                                                  ->getSymbol(), MVT::i64),
-                      DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
+                       DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)
+                                                   ->getSymbol(), MVT::i64),
+                       DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64));
   }
 
   case ISD::UREM:
   case ISD::SREM:
     //Expand only on constant case
     if (Op.getOperand(1).getOpcode() == ISD::Constant) {
-      MVT::ValueType VT = Op.Val->getValueType(0);
+      MVT VT = Op.Val->getValueType(0);
       SDOperand Tmp1 = Op.Val->getOpcode() == ISD::UREM ?
-       BuildUDIV(Op.Val, DAG, NULL) :
-       BuildSDIV(Op.Val, DAG, NULL);
+        BuildUDIV(Op.Val, DAG, NULL) :
+        BuildSDIV(Op.Val, DAG, NULL);
       Tmp1 = DAG.getNode(ISD::MUL, VT, Tmp1, Op.getOperand(1));
       Tmp1 = DAG.getNode(ISD::SUB, VT, Op.getOperand(0), Tmp1);
       return Tmp1;
@@ -480,12 +474,12 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     //fall through
   case ISD::SDIV:
   case ISD::UDIV:
-    if (MVT::isInteger(Op.getValueType())) {
+    if (Op.getValueType().isInteger()) {
       if (Op.getOperand(1).getOpcode() == ISD::Constant)
-       return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.Val, DAG, NULL) 
-         : BuildUDIV(Op.Val, DAG, NULL);
+        return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.Val, DAG, NULL) 
+          : BuildUDIV(Op.Val, DAG, NULL);
       const char* opstr = 0;
-      switch(Op.getOpcode()) {
+      switch (Op.getOpcode()) {
       case ISD::UREM: opstr = "__remqu"; break;
       case ISD::SREM: opstr = "__remq";  break;
       case ISD::UDIV: opstr = "__divqu"; break;
@@ -501,16 +495,15 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::VAARG: {
     SDOperand Chain = Op.getOperand(0);
     SDOperand VAListP = Op.getOperand(1);
-    SrcValueSDNode *VAListS = cast<SrcValueSDNode>(Op.getOperand(2));
+    const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
     
-    SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS->getValue(),
-                                 VAListS->getOffset());
+    SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS, 0);
     SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
                                 DAG.getConstant(8, MVT::i64));
     SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
                                       Tmp, NULL, 0, MVT::i32);
     SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset);
-    if (MVT::isFloatingPoint(Op.getValueType()))
+    if (Op.getValueType().isFloatingPoint())
     {
       //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
       SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr,
@@ -537,13 +530,11 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Chain = Op.getOperand(0);
     SDOperand DestP = Op.getOperand(1);
     SDOperand SrcP = Op.getOperand(2);
-    SrcValueSDNode *DestS = cast<SrcValueSDNode>(Op.getOperand(3));
-    SrcValueSDNode *SrcS = cast<SrcValueSDNode>(Op.getOperand(4));
+    const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
+    const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
     
-    SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
-                                SrcS->getValue(), SrcS->getOffset());
-    SDOperand Result = DAG.getStore(Val.getValue(1), Val, DestP, DestS->getValue(),
-                                    DestS->getOffset());
+    SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SrcS, 0);
+    SDOperand Result = DAG.getStore(Val.getValue(1), Val, DestP, DestS, 0);
     SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, 
                                DAG.getConstant(8, MVT::i64));
     Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, NULL,0, MVT::i32);
@@ -554,19 +545,22 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::VASTART: {
     SDOperand Chain = Op.getOperand(0);
     SDOperand VAListP = Op.getOperand(1);
-    SrcValueSDNode *VAListS = cast<SrcValueSDNode>(Op.getOperand(2));
+    const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
     
     // vastart stores the address of the VarArgsBase and VarArgsOffset
     SDOperand FR  = DAG.getFrameIndex(VarArgsBase, MVT::i64);
-    SDOperand S1  = DAG.getStore(Chain, FR, VAListP, VAListS->getValue(),
-                                 VAListS->getOffset());
+    SDOperand S1  = DAG.getStore(Chain, FR, VAListP, VAListS, 0);
     SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
                                 DAG.getConstant(8, MVT::i64));
     return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
                              SA2, NULL, 0, MVT::i32);
   }
+  case ISD::RETURNADDR:        
+    return DAG.getNode(AlphaISD::GlobalRetAddr, MVT::i64);
+      //FIXME: implement
+  case ISD::FRAMEADDR:          break;
   }
-
+  
   return SDOperand();
 }
 
@@ -586,49 +580,139 @@ SDOperand AlphaTargetLowering::CustomPromoteOperation(SDOperand Op,
 /// getConstraintType - Given a constraint letter, return the type of
 /// constraint it is for this target.
 AlphaTargetLowering::ConstraintType 
-AlphaTargetLowering::getConstraintType(char ConstraintLetter) const {
-  switch (ConstraintLetter) {
-  default: break;
-  case 'f':
-  case 'r':
-    return C_RegisterClass;
-  }  
-  return TargetLowering::getConstraintType(ConstraintLetter);
+AlphaTargetLowering::getConstraintType(const std::string &Constraint) const {
+  if (Constraint.size() == 1) {
+    switch (Constraint[0]) {
+    default: break;
+    case 'f':
+    case 'r':
+      return C_RegisterClass;
+    }
+  }
+  return TargetLowering::getConstraintType(Constraint);
 }
 
 std::vector<unsigned> AlphaTargetLowering::
 getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                  MVT::ValueType VT) const {
+                                  MVT VT) const {
   if (Constraint.size() == 1) {
     switch (Constraint[0]) {
     default: break;  // Unknown constriant letter
     case 'f': 
       return make_vector<unsigned>(Alpha::F0 , Alpha::F1 , Alpha::F2 ,
-                                  Alpha::F3 , Alpha::F4 , Alpha::F5 , 
-                                  Alpha::F6 , Alpha::F7 , Alpha::F8 , 
-                                  Alpha::F9 , Alpha::F10, Alpha::F11, 
+                                   Alpha::F3 , Alpha::F4 , Alpha::F5 ,
+                                   Alpha::F6 , Alpha::F7 , Alpha::F8 , 
+                                   Alpha::F9 , Alpha::F10, Alpha::F11, 
                                    Alpha::F12, Alpha::F13, Alpha::F14, 
-                                  Alpha::F15, Alpha::F16, Alpha::F17, 
-                                  Alpha::F18, Alpha::F19, Alpha::F20, 
-                                  Alpha::F21, Alpha::F22, Alpha::F23, 
+                                   Alpha::F15, Alpha::F16, Alpha::F17, 
+                                   Alpha::F18, Alpha::F19, Alpha::F20, 
+                                   Alpha::F21, Alpha::F22, Alpha::F23, 
                                    Alpha::F24, Alpha::F25, Alpha::F26, 
-                                  Alpha::F27, Alpha::F28, Alpha::F29, 
-                                  Alpha::F30, Alpha::F31, 0);
+                                   Alpha::F27, Alpha::F28, Alpha::F29, 
+                                   Alpha::F30, Alpha::F31, 0);
     case 'r': 
       return make_vector<unsigned>(Alpha::R0 , Alpha::R1 , Alpha::R2 , 
-                                  Alpha::R3 , Alpha::R4 , Alpha::R5 , 
-                                  Alpha::R6 , Alpha::R7 , Alpha::R8 , 
-                                  Alpha::R9 , Alpha::R10, Alpha::R11, 
+                                   Alpha::R3 , Alpha::R4 , Alpha::R5 , 
+                                   Alpha::R6 , Alpha::R7 , Alpha::R8 , 
+                                   Alpha::R9 , Alpha::R10, Alpha::R11, 
                                    Alpha::R12, Alpha::R13, Alpha::R14, 
-                                  Alpha::R15, Alpha::R16, Alpha::R17, 
-                                  Alpha::R18, Alpha::R19, Alpha::R20, 
-                                  Alpha::R21, Alpha::R22, Alpha::R23, 
+                                   Alpha::R15, Alpha::R16, Alpha::R17, 
+                                   Alpha::R18, Alpha::R19, Alpha::R20, 
+                                   Alpha::R21, Alpha::R22, Alpha::R23, 
                                    Alpha::R24, Alpha::R25, Alpha::R26, 
-                                  Alpha::R27, Alpha::R28, Alpha::R29, 
-                                  Alpha::R30, Alpha::R31, 0);
+                                   Alpha::R27, Alpha::R28, Alpha::R29, 
+                                   Alpha::R30, Alpha::R31, 0);
     }
   }
   
   return std::vector<unsigned>();
 }
+//===----------------------------------------------------------------------===//
+//  Other Lowering Code
+//===----------------------------------------------------------------------===//
+
+MachineBasicBlock *
+AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+                                                 MachineBasicBlock *BB) {
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  assert((MI->getOpcode() == Alpha::CAS32 ||
+          MI->getOpcode() == Alpha::CAS64 ||
+          MI->getOpcode() == Alpha::LAS32 ||
+          MI->getOpcode() == Alpha::LAS64 ||
+          MI->getOpcode() == Alpha::SWAP32 ||
+          MI->getOpcode() == Alpha::SWAP64) &&
+         "Unexpected instr type to insert");
+
+  bool is32 = MI->getOpcode() == Alpha::CAS32 || 
+    MI->getOpcode() == Alpha::LAS32 ||
+    MI->getOpcode() == Alpha::SWAP32;
+  
+  //Load locked store conditional for atomic ops take on the same form
+  //start:
+  //ll
+  //do stuff (maybe branch to exit)
+  //sc
+  //test sc and maybe branck to start
+  //exit:
+  const BasicBlock *LLVM_BB = BB->getBasicBlock();
+  ilist<MachineBasicBlock>::iterator It = BB;
+  ++It;
+  
+  MachineBasicBlock *thisMBB = BB;
+  MachineBasicBlock *llscMBB = new MachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
+
+  sinkMBB->transferSuccessors(thisMBB);
+
+  MachineFunction *F = BB->getParent();
+  F->getBasicBlockList().insert(It, llscMBB);
+  F->getBasicBlockList().insert(It, sinkMBB);
+
+  BuildMI(thisMBB, TII->get(Alpha::BR)).addMBB(llscMBB);
+  
+  unsigned reg_res = MI->getOperand(0).getReg(),
+    reg_ptr = MI->getOperand(1).getReg(),
+    reg_v2 = MI->getOperand(2).getReg(),
+    reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
+
+  BuildMI(llscMBB, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L), 
+          reg_res).addImm(0).addReg(reg_ptr);
+  switch (MI->getOpcode()) {
+  case Alpha::CAS32:
+  case Alpha::CAS64: {
+    unsigned reg_cmp 
+      = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
+    BuildMI(llscMBB, TII->get(Alpha::CMPEQ), reg_cmp)
+      .addReg(reg_v2).addReg(reg_res);
+    BuildMI(llscMBB, TII->get(Alpha::BEQ))
+      .addImm(0).addReg(reg_cmp).addMBB(sinkMBB);
+    BuildMI(llscMBB, TII->get(Alpha::BISr), reg_store)
+      .addReg(Alpha::R31).addReg(MI->getOperand(3).getReg());
+    break;
+  }
+  case Alpha::LAS32:
+  case Alpha::LAS64: {
+    BuildMI(llscMBB, TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr), reg_store)
+      .addReg(reg_res).addReg(reg_v2);
+    break;
+  }
+  case Alpha::SWAP32:
+  case Alpha::SWAP64: {
+    BuildMI(llscMBB, TII->get(Alpha::BISr), reg_store)
+      .addReg(reg_v2).addReg(reg_v2);
+    break;
+  }
+  }
+  BuildMI(llscMBB, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C), reg_store)
+    .addReg(reg_store).addImm(0).addReg(reg_ptr);
+  BuildMI(llscMBB, TII->get(Alpha::BEQ))
+    .addImm(0).addReg(reg_store).addMBB(llscMBB);
+  BuildMI(llscMBB, TII->get(Alpha::BR)).addMBB(sinkMBB);
+
+  thisMBB->addSuccessor(llscMBB);
+  llscMBB->addSuccessor(llscMBB);
+  llscMBB->addSuccessor(sinkMBB);
+  delete MI;   // The pseudo instruction is gone now.
+
+  return sinkMBB;
+}