//===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for Alpha.
//
//===----------------------------------------------------------------------===//

#include "Alpha.h"
#include "AlphaRegisterInfo.h"
#include "llvm/Constants.h"                   // FIXME: REMOVE
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include <set>
#include <algorithm>
using namespace llvm;

namespace llvm {
  cl::opt<bool> EnableAlphaIDIV("enable-alpha-intfpdiv",
                             cl::desc("Use the FP div instruction for integer div when possible"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaFTOI("enable-alpha-ftoi",
                             cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaCount("enable-alpha-count",
                             cl::desc("Print estimates on live ins and outs"),
                             cl::Hidden);
}

//===----------------------------------------------------------------------===//
//  AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
namespace {
  class AlphaTargetLowering : public TargetLowering {
    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
    unsigned GP; //GOT vreg
  public:
    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);

      addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
      addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
      addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);

      setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
      setOperationAction(ISD::EXTLOAD  , MVT::i1   , Promote);
      setOperationAction(ISD::EXTLOAD  , MVT::f32  , Promote);

      setOperationAction(ISD::ZEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::ZEXTLOAD , MVT::i32  , Expand);

      setOperationAction(ISD::SEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i8   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i16  , Expand);

      setOperationAction(ISD::SREM     , MVT::f32  , Expand);
      setOperationAction(ISD::SREM     , MVT::f64  , Expand);

      //If this didn't legalize into a div....
      //      setOperationAction(ISD::SREM     , MVT::i64, Expand);
      //      setOperationAction(ISD::UREM     , MVT::i64, Expand);

      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
      setOperationAction(ISD::FSIN , MVT::f64, Expand);
      setOperationAction(ISD::FCOS , MVT::f64, Expand);
      setOperationAction(ISD::FSQRT, MVT::f64, Expand);
      setOperationAction(ISD::FSIN , MVT::f32, Expand);
      setOperationAction(ISD::FCOS , MVT::f32, Expand);
      setOperationAction(ISD::FSQRT, MVT::f32, Expand);

      //Doesn't work yet
      setOperationAction(ISD::SETCC, MVT::f32,   Promote);

      computeRegisterProperties();

      addLegalFPImmediate(+0.0); //F31
      addLegalFPImmediate(-0.0); //-F31
    }

    /// LowerArguments - This hook must be implemented to indicate how we should
    /// lower the arguments for the specified function, into the specified DAG.
    virtual std::vector<SDOperand>
    LowerArguments(Function &F, SelectionDAG &DAG);

    /// LowerCallTo - This hook lowers an abstract call to a function into an
    /// actual call.
    virtual std::pair<SDOperand, SDOperand>
    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
                SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerVAStart(SDOperand Chain, SelectionDAG &DAG);

    virtual std::pair<SDOperand,SDOperand>
    LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
                   const Type *ArgTy, SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                            SelectionDAG &DAG);

    void restoreGP(MachineBasicBlock* BB)
    {
      BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
    }
  };
}

//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21

//For now, just use variable size stack frame format

//In a standard call, the first six items are passed in registers $16
//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
//of argument-to-register correspondence.) The remaining items are
//collected in a memory argument list that is a naturally aligned
//array of quadwords. In a standard call, this list, if present, must
//be passed at 0(SP).
//7 ... n         0(SP) ... (n-7)*8(SP)

// //#define FP    $15
// //#define RA    $26
// //#define PV    $27
// //#define GP    $29
// //#define SP    $30

std::vector<SDOperand>
AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
{
  std::vector<SDOperand> ArgValues;
  std::vector<SDOperand> LS;
  SDOperand Chain = DAG.getRoot();

  //  assert(0 && "TODO");
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo*MFI = MF.getFrameInfo();

  GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
  MachineBasicBlock& BB = MF.front();

  //Handle the return address
  //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);

  unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
                         Alpha::R19, Alpha::R20, Alpha::R21};
  unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
                           Alpha::F19, Alpha::F20, Alpha::F21};
  int count = 0;

  //Def incoming registers
  {
    Function::arg_iterator I = F.arg_begin();
    Function::arg_iterator E = F.arg_end();
    for (int i = 0; i < 6; ++i)
    {
      if (F.isVarArg()) {
        MF.addLiveIn(args_int[i]);
        MF.addLiveIn(args_float[i]);
//        BuildMI(&BB, Alpha::IDEF, 0, args_int[i]);
//        BuildMI(&BB, Alpha::IDEF, 0, args_float[i]);
      } else if (I != E)
      {
        if(MVT::isInteger(getValueType(I->getType())))
          MF.addLiveIn(args_int[i]);
//          BuildMI(&BB, Alpha::IDEF, 0, args_int[i]);
        else
          MF.addLiveIn(args_float[i]);
//          BuildMI(&BB, Alpha::IDEF, 0, args_float[i]);
        ++I;
      }
    }
  }

  MF.addLiveIn(Alpha::R29);
//  BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
  BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);

  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
  {
    SDOperand newroot, argt;
    if (count  < 6) {
      unsigned Vreg;
      MVT::ValueType VT = getValueType(I->getType());
      switch (getValueType(I->getType())) {
      default:
        std::cerr << "Unknown Type " << VT << "\n";
        abort();
      case MVT::f64:
      case MVT::f32:
        Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(VT));
        BuildMI(&BB, Alpha::CPYS, 2, Vreg).addReg(args_float[count]).addReg(args_float[count]);
        argt = newroot = DAG.getCopyFromReg(Vreg,
                                            getValueType(I->getType()),
                                            Chain);
        break;
      case MVT::i1:
      case MVT::i8:
      case MVT::i16:
      case MVT::i32:
      case MVT::i64:
        Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
        BuildMI(&BB, Alpha::BIS, 2, Vreg).addReg(args_int[count]).addReg(args_int[count]);
        argt = newroot = DAG.getCopyFromReg(Vreg, MVT::i64, Chain);
        if (getValueType(I->getType()) != MVT::i64)
          argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
        break;
      }
    } else { //more args
      // Create the frame index object for this incoming parameter...
      int FI = MFI->CreateFixedObject(8, 8 * (count - 6));

      // Create the SelectionDAG nodes corresponding to a load
      //from this parameter
      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
      argt = newroot = DAG.getLoad(getValueType(I->getType()),
                                   DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
    }
    ++count;
    LS.push_back(newroot.getValue(1));
    ArgValues.push_back(argt);
  }

  // If the functions takes variable number of arguments, copy all regs to stack
  if (F.isVarArg())
    for (int i = 0; i < 6; ++i)
    {
      unsigned Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
      BuildMI(&BB, Alpha::BIS, 2, Vreg).addReg(args_int[i]).addReg(args_int[i]);
      SDOperand argt = DAG.getCopyFromReg(Vreg, MVT::i64, Chain);
      int FI = MFI->CreateFixedObject(8, -8 * (6 - i));
      SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64);
      LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, argt, SDFI, DAG.getSrcValue(NULL)));

      Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::f64));
      BuildMI(&BB, Alpha::CPYS, 2, Vreg).addReg(args_float[i]).addReg(args_float[i]);
      argt = DAG.getCopyFromReg(Vreg, MVT::f64, Chain);
      FI = MFI->CreateFixedObject(8, - 8 * (12 - i));
      SDFI = DAG.getFrameIndex(FI, MVT::i64);
      LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, argt, SDFI, DAG.getSrcValue(NULL)));
    }

  // If the function takes variable number of arguments, make a frame index for
  // the start of the first arg value... for expansion of llvm.va_start.
  //   if (F.isVarArg())
  //     VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);

  //Set up a token factor with all the stack traffic
  DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, LS));

  // Finally, inform the code generator which regs we return values in.
  switch (getValueType(F.getReturnType())) {
  default: assert(0 && "Unknown type!");
  case MVT::isVoid: break;
  case MVT::i1:
  case MVT::i8:
  case MVT::i16:
  case MVT::i32:
  case MVT::i64:
    MF.addLiveOut(Alpha::R0);
    break;
  case MVT::f32:
  case MVT::f64:
    MF.addLiveOut(Alpha::F0);
    break;
  }

  //return the arguments
  return ArgValues;
}

std::pair<SDOperand, SDOperand>
AlphaTargetLowering::LowerCallTo(SDOperand Chain,
                                 const Type *RetTy, bool isVarArg,
                                 SDOperand Callee, ArgListTy &Args, 
                                 SelectionDAG &DAG) {
  int NumBytes = 0;
  if (Args.size() > 6)
    NumBytes = (Args.size() - 6) * 8;

  Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
                      DAG.getConstant(NumBytes, getPointerTy()));
  std::vector<SDOperand> args_to_use;
  for (unsigned i = 0, e = Args.size(); i != e; ++i)
  {
    switch (getValueType(Args[i].second)) {
    default: assert(0 && "Unexpected ValueType for argument!");
    case MVT::i1:
    case MVT::i8:
    case MVT::i16:
    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);
      else
        Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
      break;
    case MVT::i64:
    case MVT::f64:
    case MVT::f32:
      break;
    }
    args_to_use.push_back(Args[i].first);
  }

  std::vector<MVT::ValueType> RetVals;
  MVT::ValueType RetTyVT = getValueType(RetTy);
  if (RetTyVT != MVT::isVoid)
    RetVals.push_back(RetTyVT);
  RetVals.push_back(MVT::Other);

  SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
                                            Chain, Callee, args_to_use), 0);
  Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
  Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
                      DAG.getConstant(NumBytes, getPointerTy()));
  return std::make_pair(TheCall, Chain);
}

std::pair<SDOperand, SDOperand>
AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
  //vastart just returns the address of the VarArgsFrameIndex slot.
  return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
}

std::pair<SDOperand,SDOperand> AlphaTargetLowering::
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
               const Type *ArgTy, SelectionDAG &DAG) {
  abort();
}


std::pair<SDOperand, SDOperand> AlphaTargetLowering::
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
                        SelectionDAG &DAG) {
  abort();
}





namespace {

//===--------------------------------------------------------------------===//
/// ISel - Alpha specific code to select Alpha machine instructions for
/// SelectionDAG operations.
//===--------------------------------------------------------------------===//
class ISel : public SelectionDAGISel {

  /// AlphaLowering - This object fully describes how to lower LLVM code to an
  /// Alpha-specific SelectionDAG.
  AlphaTargetLowering AlphaLowering;

  SelectionDAG *ISelDAG;  // Hack to support us having a dag->dag transform
                          // for sdiv and udiv until it is put into the future
                          // dag combiner.

  /// ExprMap - As shared expressions are codegen'd, we keep track of which
  /// vreg the value is produced in, so we only emit one copy of each compiled
  /// tree.
  static const unsigned notIn = (unsigned)(-1);
  std::map<SDOperand, unsigned> ExprMap;

  //CCInvMap sometimes (SetNE) we have the inverse CC code for free
  std::map<SDOperand, unsigned> CCInvMap;

  int count_ins;
  int count_outs;
  bool has_sym;
  int max_depth;

public:
  ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
  {}

  /// InstructionSelectBasicBlock - This callback is invoked by
  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
  virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
    DEBUG(BB->dump());
    count_ins = 0;
    count_outs = 0;
    max_depth = 0;
    has_sym = false;

    // Codegen the basic block.
    ISelDAG = &DAG;
    max_depth = DAG.getRoot().getNodeDepth();
    Select(DAG.getRoot());

    if(has_sym)
      ++count_ins;
    if(EnableAlphaCount)
      std::cerr << "COUNT: " << BB->getParent()->getFunction ()->getName() << " " 
                << BB->getNumber() << " " 
                << max_depth << " "
                << count_ins << " "
                << count_outs << "\n";

    // Clear state used for selection.
    ExprMap.clear();
    CCInvMap.clear();
  }

  unsigned SelectExpr(SDOperand N);
  unsigned SelectExprFP(SDOperand N, unsigned Result);
  void Select(SDOperand N);

  void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
  void SelectBranchCC(SDOperand N);
  void MoveFP2Int(unsigned src, unsigned dst, bool isDouble);
  void MoveInt2FP(unsigned src, unsigned dst, bool isDouble);
  //returns whether the sense of the comparison was inverted
  bool SelectFPSetCC(SDOperand N, unsigned dst);

  // dag -> dag expanders for integer divide by constant
  SDOperand BuildSDIVSequence(SDOperand N);
  SDOperand BuildUDIVSequence(SDOperand N);

};
}

//Factorize a number using the list of constants
static bool factorize(int v[], int res[], int size, uint64_t c)
{
  bool cont = true;
  while (c != 1 && cont)
  {
    cont = false;
    for(int i = 0; i < size; ++i)
    {
      if (c % v[i] == 0)
      {
        c /= v[i];
        ++res[i];
        cont=true;
      }
    }
  }
  return c == 1;
}


//Shamelessly adapted from PPC32
// Structure used to return the necessary information to codegen an SDIV as
// a multiply.
struct ms {
  int64_t m; // magic number
  int64_t s; // shift amount
};

struct mu {
  uint64_t m; // magic number
  int64_t a;          // add indicator
  int64_t s;          // shift amount
};

/// magic - calculate the magic numbers required to codegen an integer sdiv as
/// a sequence of multiply and shifts.  Requires that the divisor not be 0, 1,
/// or -1.
static struct ms magic(int64_t d) {
  int64_t p;
  uint64_t ad, anc, delta, q1, r1, q2, r2, t;
  const uint64_t two63 = 9223372036854775808ULL; // 2^63
  struct ms mag;

  ad = abs(d);
  t = two63 + ((uint64_t)d >> 63);
  anc = t - 1 - t%ad;   // absolute value of nc
  p = 63;               // initialize p
  q1 = two63/anc;       // initialize q1 = 2p/abs(nc)
  r1 = two63 - q1*anc;  // initialize r1 = rem(2p,abs(nc))
  q2 = two63/ad;        // initialize q2 = 2p/abs(d)
  r2 = two63 - q2*ad;   // initialize r2 = rem(2p,abs(d))
  do {
    p = p + 1;
    q1 = 2*q1;        // update q1 = 2p/abs(nc)
    r1 = 2*r1;        // update r1 = rem(2p/abs(nc))
    if (r1 >= anc) {  // must be unsigned comparison
      q1 = q1 + 1;
      r1 = r1 - anc;
    }
    q2 = 2*q2;        // update q2 = 2p/abs(d)
    r2 = 2*r2;        // update r2 = rem(2p/abs(d))
    if (r2 >= ad) {   // must be unsigned comparison
      q2 = q2 + 1;
      r2 = r2 - ad;
    }
    delta = ad - r2;
  } while (q1 < delta || (q1 == delta && r1 == 0));

  mag.m = q2 + 1;
  if (d < 0) mag.m = -mag.m; // resulting magic number
  mag.s = p - 64;            // resulting shift
  return mag;
}

/// magicu - calculate the magic numbers required to codegen an integer udiv as
/// a sequence of multiply, add and shifts.  Requires that the divisor not be 0.
static struct mu magicu(uint64_t d)
{
  int64_t p;
  uint64_t nc, delta, q1, r1, q2, r2;
  struct mu magu;
  magu.a = 0;               // initialize "add" indicator
  nc = - 1 - (-d)%d;
  p = 63;                   // initialize p
  q1 = 0x8000000000000000ull/nc;       // initialize q1 = 2p/nc
  r1 = 0x8000000000000000ull - q1*nc;  // initialize r1 = rem(2p,nc)
  q2 = 0x7FFFFFFFFFFFFFFFull/d;        // initialize q2 = (2p-1)/d
  r2 = 0x7FFFFFFFFFFFFFFFull - q2*d;   // initialize r2 = rem((2p-1),d)
  do {
    p = p + 1;
    if (r1 >= nc - r1 ) {
      q1 = 2*q1 + 1;  // update q1
      r1 = 2*r1 - nc; // update r1
    }
    else {
      q1 = 2*q1; // update q1
      r1 = 2*r1; // update r1
    }
    if (r2 + 1 >= d - r2) {
      if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1;
      q2 = 2*q2 + 1;     // update q2
      r2 = 2*r2 + 1 - d; // update r2
    }
    else {
      if (q2 >= 0x8000000000000000ull) magu.a = 1;
      q2 = 2*q2;     // update q2
      r2 = 2*r2 + 1; // update r2
    }
    delta = d - 1 - r2;
  } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
  magu.m = q2 + 1; // resulting magic number
  magu.s = p - 64;  // resulting shift
  return magu;
}

/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
/// return a DAG expression to select that will generate the same value by
/// multiplying by a magic number.  See:
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
SDOperand ISel::BuildSDIVSequence(SDOperand N) {
  int64_t d = (int64_t)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
  ms magics = magic(d);
  // Multiply the numerator (operand 0) by the magic value
  SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i64, N.getOperand(0),
                                 ISelDAG->getConstant(magics.m, MVT::i64));
  // If d > 0 and m < 0, add the numerator
  if (d > 0 && magics.m < 0)
    Q = ISelDAG->getNode(ISD::ADD, MVT::i64, Q, N.getOperand(0));
  // If d < 0 and m > 0, subtract the numerator.
  if (d < 0 && magics.m > 0)
    Q = ISelDAG->getNode(ISD::SUB, MVT::i64, Q, N.getOperand(0));
  // Shift right algebraic if shift value is nonzero
  if (magics.s > 0)
    Q = ISelDAG->getNode(ISD::SRA, MVT::i64, Q,
                         ISelDAG->getConstant(magics.s, MVT::i64));
  // Extract the sign bit and add it to the quotient
  SDOperand T =
    ISelDAG->getNode(ISD::SRL, MVT::i64, Q, ISelDAG->getConstant(63, MVT::i64));
  return ISelDAG->getNode(ISD::ADD, MVT::i64, Q, T);
}

/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant,
/// return a DAG expression to select that will generate the same value by
/// multiplying by a magic number.  See:
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
SDOperand ISel::BuildUDIVSequence(SDOperand N) {
  unsigned d =
    (unsigned)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
  mu magics = magicu(d);
  // Multiply the numerator (operand 0) by the magic value
  SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i64, N.getOperand(0),
                                 ISelDAG->getConstant(magics.m, MVT::i64));
  if (magics.a == 0) {
    Q = ISelDAG->getNode(ISD::SRL, MVT::i64, Q,
                         ISelDAG->getConstant(magics.s, MVT::i64));
  } else {
    SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i64, N.getOperand(0), Q);
    NPQ = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ,
                           ISelDAG->getConstant(1, MVT::i64));
    NPQ = ISelDAG->getNode(ISD::ADD, MVT::i64, NPQ, Q);
    Q = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ,
                           ISelDAG->getConstant(magics.s-1, MVT::i64));
  }
  return Q;
}

//From PPC32
/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N.  It
/// returns zero when the input is not exactly a power of two.
static unsigned ExactLog2(uint64_t Val) {
  if (Val == 0 || (Val & (Val-1))) return 0;
  unsigned Count = 0;
  while (Val != 1) {
    Val >>= 1;
    ++Count;
  }
  return Count;
}


//These describe LDAx
static const int IMM_LOW  = -32768;
static const int IMM_HIGH = 32767;
static const int IMM_MULT = 65536;

static long getUpper16(long l)
{
  long y = l / IMM_MULT;
  if (l % IMM_MULT > IMM_HIGH)
    ++y;
  return y;
}

static long getLower16(long l)
{
  long h = getUpper16(l);
  return l - h * IMM_MULT;
}

static unsigned GetSymVersion(unsigned opcode)
{
  switch (opcode) {
  default: assert(0 && "unknown load or store"); return 0;
  case Alpha::LDQ: return Alpha::LDQ_SYM;
  case Alpha::LDS: return Alpha::LDS_SYM;
  case Alpha::LDT: return Alpha::LDT_SYM;
  case Alpha::LDL: return Alpha::LDL_SYM;
  case Alpha::LDBU: return Alpha::LDBU_SYM;
  case Alpha::LDWU: return Alpha::LDWU_SYM;
  case Alpha::LDW: return Alpha::LDW_SYM;
  case Alpha::LDB: return Alpha::LDB_SYM;
  case Alpha::STQ: return Alpha::STQ_SYM;
  case Alpha::STS: return Alpha::STS_SYM;
  case Alpha::STT: return Alpha::STT_SYM;
  case Alpha::STL: return Alpha::STL_SYM;
  case Alpha::STW: return Alpha::STW_SYM;
  case Alpha::STB: return Alpha::STB_SYM;
  }
}

void ISel::MoveFP2Int(unsigned src, unsigned dst, bool isDouble)
{
  unsigned Opc;
  if (EnableAlphaFTOI) {
    Opc = isDouble ? Alpha::FTOIT : Alpha::FTOIS;
    BuildMI(BB, Opc, 1, dst).addReg(src);
  } else {
    //The hard way:
    // Spill the integer to memory and reload it from there.
    unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
    MachineFunction *F = BB->getParent();
    int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);

    Opc = isDouble ? Alpha::STT : Alpha::STS;
    BuildMI(BB, Opc, 3).addReg(src).addFrameIndex(FrameIdx).addReg(Alpha::F31);
    Opc = isDouble ? Alpha::LDQ : Alpha::LDL;
    BuildMI(BB, Alpha::LDQ, 2, dst).addFrameIndex(FrameIdx).addReg(Alpha::F31);
  }
}

void ISel::MoveInt2FP(unsigned src, unsigned dst, bool isDouble)
{
  unsigned Opc;
  if (EnableAlphaFTOI) {
    Opc = isDouble?Alpha::ITOFT:Alpha::ITOFS;
    BuildMI(BB, Opc, 1, dst).addReg(src);
  } else {
    //The hard way:
    // Spill the integer to memory and reload it from there.
    unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
    MachineFunction *F = BB->getParent();
    int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);

    Opc = isDouble ? Alpha::STQ : Alpha::STL;
    BuildMI(BB, Opc, 3).addReg(src).addFrameIndex(FrameIdx).addReg(Alpha::F31);
    Opc = isDouble ? Alpha::LDT : Alpha::LDS;
    BuildMI(BB, Opc, 2, dst).addFrameIndex(FrameIdx).addReg(Alpha::F31);
  }
}

bool ISel::SelectFPSetCC(SDOperand N, unsigned dst)
{
  SDNode *Node = N.Val;
  unsigned Opc, Tmp1, Tmp2, Tmp3;
  SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node);

  //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
  bool rev = false;
  bool inv = false;

  switch (SetCC->getCondition()) {
  default: Node->dump(); assert(0 && "Unknown FP comparison!");
  case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
  case ISD::SETLT: Opc = Alpha::CMPTLT; break;
  case ISD::SETLE: Opc = Alpha::CMPTLE; break;
  case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
  case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
  case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
  }

  //FIXME: check for constant 0.0
  ConstantFPSDNode *CN;
  if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
      && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
    Tmp1 = Alpha::F31;
  else
    Tmp1 = SelectExpr(N.getOperand(0));

  if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
      && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
    Tmp2 = Alpha::F31;
  else
    Tmp2 = SelectExpr(N.getOperand(1));

  //Can only compare doubles, and dag won't promote for me
  if (SetCC->getOperand(0).getValueType() == MVT::f32)
    {
      //assert(0 && "Setcc On float?\n");
      std::cerr << "Setcc on float!\n";
      Tmp3 = MakeReg(MVT::f64);
      BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
      Tmp1 = Tmp3;
    }
  if (SetCC->getOperand(1).getValueType() == MVT::f32)
    {
      //assert (0 && "Setcc On float?\n");
      std::cerr << "Setcc on float!\n";
      Tmp3 = MakeReg(MVT::f64);
      BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
      Tmp2 = Tmp3;
    }

  if (rev) std::swap(Tmp1, Tmp2);
  //do the comparison
  BuildMI(BB, Opc, 2, dst).addReg(Tmp1).addReg(Tmp2);
  return inv;
}

//Check to see if the load is a constant offset from a base register
void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
{
  unsigned opcode = N.getOpcode();
  if (opcode == ISD::ADD) {
    if(N.getOperand(1).getOpcode() == ISD::Constant &&
       cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
    { //Normal imm add
      Reg = SelectExpr(N.getOperand(0));
      offset = cast<ConstantSDNode>(N.getOperand(1))->getValue();
      return;
    }
    else if(N.getOperand(0).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 32767)
    {
      Reg = SelectExpr(N.getOperand(1));
      offset = cast<ConstantSDNode>(N.getOperand(0))->getValue();
      return;
    }
  }
  Reg = SelectExpr(N);
  offset = 0;
  return;
}

void ISel::SelectBranchCC(SDOperand N)
{
  assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
  MachineBasicBlock *Dest =
    cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
  unsigned Opc = Alpha::WTF;

  Select(N.getOperand(0));  //chain
  SDOperand CC = N.getOperand(1);

  if (CC.getOpcode() == ISD::SETCC)
  {
    SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
    if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
      //Dropping the CC is only useful if we are comparing to 0
      bool LeftZero = SetCC->getOperand(0).getOpcode() == ISD::Constant &&
        cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0;
      bool RightZero = SetCC->getOperand(0).getOpcode() == ISD::Constant &&
        cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0;
      bool isNE = false;

      //Fix up CC
      ISD::CondCode cCode= SetCC->getCondition();
      if (LeftZero && !RightZero) //Swap Operands
        cCode = ISD::getSetCCSwappedOperands(cCode);

      if(cCode == ISD::SETNE)
        isNE = true;

      if (LeftZero || RightZero) {
        switch (SetCC->getCondition()) {
        default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
        case ISD::SETEQ:  Opc = Alpha::BEQ; break;
        case ISD::SETLT:  Opc = Alpha::BLT; break;
        case ISD::SETLE:  Opc = Alpha::BLE; break;
        case ISD::SETGT:  Opc = Alpha::BGT; break;
        case ISD::SETGE:  Opc = Alpha::BGE; break;
        case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
        case ISD::SETUGT: Opc = Alpha::BNE; break;
        case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
        case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
        case ISD::SETNE:  Opc = Alpha::BNE; break;
        }
        unsigned Tmp1;
        if(LeftZero && !RightZero) //swap Operands
          Tmp1 = SelectExpr(SetCC->getOperand(1)); //Cond
        else
          Tmp1 = SelectExpr(SetCC->getOperand(0)); //Cond
        BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
        return;
      } else {
        unsigned Tmp1 = SelectExpr(CC);
        if (isNE)
          BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
        else
          BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
        return;
      }
    } else { //FP
      //Any comparison between 2 values should be codegened as an folded branch, as moving
      //CC to the integer register is very expensive
      //for a cmp b: c = a - b;
      //a = b: c = 0
      //a < b: c < 0
      //a > b: c > 0

      bool invTest = false;
      unsigned Tmp3;

      ConstantFPSDNode *CN;
      if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
          && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
        Tmp3 = SelectExpr(SetCC->getOperand(0));
      else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
          && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
      {
        Tmp3 = SelectExpr(SetCC->getOperand(1));
        invTest = true;
      }
      else
      {
        unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
        unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
        bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
        Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
        BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
          .addReg(Tmp1).addReg(Tmp2);
      }

      switch (SetCC->getCondition()) {
      default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
      case ISD::SETEQ: Opc = invTest ? Alpha::FBNE : Alpha::FBEQ; break;
      case ISD::SETLT: Opc = invTest ? Alpha::FBGT : Alpha::FBLT; break;
      case ISD::SETLE: Opc = invTest ? Alpha::FBGE : Alpha::FBLE; break;
      case ISD::SETGT: Opc = invTest ? Alpha::FBLT : Alpha::FBGT; break;
      case ISD::SETGE: Opc = invTest ? Alpha::FBLE : Alpha::FBGE; break;
      case ISD::SETNE: Opc = invTest ? Alpha::FBEQ : Alpha::FBNE; break;
      }
      BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
      return;
    }
    abort(); //Should never be reached
  } else {
    //Giveup and do the stupid thing
    unsigned Tmp1 = SelectExpr(CC);
    BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
    return;
  }
  abort(); //Should never be reached
}

unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
{
  unsigned Tmp1, Tmp2, Tmp3;
  unsigned Opc = 0;
  SDNode *Node = N.Val;
  MVT::ValueType DestType = N.getValueType();
  unsigned opcode = N.getOpcode();

  switch (opcode) {
  default:
    Node->dump();
    assert(0 && "Node not handled!\n");

  case ISD::UNDEF: {
    BuildMI(BB, Alpha::IDEF, 0, Result);
    return Result;
  }

  case ISD::FNEG:
    if(ISD::FABS == N.getOperand(0).getOpcode())
      {
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Tmp1);
      } else {
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp1).addReg(Tmp1);
      }
    return Result;

  case ISD::FABS:
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Tmp1);
    return Result;

  case ISD::SELECT:
    {
      //Tmp1 = SelectExpr(N.getOperand(0)); //Cond
      unsigned TV = SelectExpr(N.getOperand(1)); //Use if TRUE
      unsigned FV = SelectExpr(N.getOperand(2)); //Use if FALSE

      SDOperand CC = N.getOperand(0);
      SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);

      if (CC.getOpcode() == ISD::SETCC &&
          !MVT::isInteger(SetCC->getOperand(0).getValueType()))
      { //FP Setcc -> Select yay!


        //for a cmp b: c = a - b;
        //a = b: c = 0
        //a < b: c < 0
        //a > b: c > 0

        bool invTest = false;
        unsigned Tmp3;

        ConstantFPSDNode *CN;
        if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
            && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
          Tmp3 = SelectExpr(SetCC->getOperand(0));
        else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
                 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
        {
          Tmp3 = SelectExpr(SetCC->getOperand(1));
          invTest = true;
        }
        else
        {
          unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
          unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
          bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
          Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
          BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
            .addReg(Tmp1).addReg(Tmp2);
        }

        switch (SetCC->getCondition()) {
        default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
        case ISD::SETEQ: Opc = invTest ? Alpha::FCMOVNE : Alpha::FCMOVEQ; break;
        case ISD::SETLT: Opc = invTest ? Alpha::FCMOVGT : Alpha::FCMOVLT; break;
        case ISD::SETLE: Opc = invTest ? Alpha::FCMOVGE : Alpha::FCMOVLE; break;
        case ISD::SETGT: Opc = invTest ? Alpha::FCMOVLT : Alpha::FCMOVGT; break;
        case ISD::SETGE: Opc = invTest ? Alpha::FCMOVLE : Alpha::FCMOVGE; break;
        case ISD::SETNE: Opc = invTest ? Alpha::FCMOVEQ : Alpha::FCMOVNE; break;
        }
        BuildMI(BB, Opc, 3, Result).addReg(FV).addReg(TV).addReg(Tmp3);
        return Result;
      }
      else
      {
        Tmp1 = SelectExpr(N.getOperand(0)); //Cond
        BuildMI(BB, Alpha::FCMOVEQ_INT, 3, Result).addReg(TV).addReg(FV).addReg(Tmp1);
//         // Spill the cond to memory and reload it from there.
//         unsigned Tmp4 = MakeReg(MVT::f64);
//         MoveIntFP(Tmp1, Tmp4, true);
//         //now ideally, we don't have to do anything to the flag...
//         // Get the condition into the zero flag.
//         BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4);
        return Result;
      }
    }

  case ISD::FP_ROUND:
    assert (DestType == MVT::f32 &&
            N.getOperand(0).getValueType() == MVT::f64 &&
            "only f64 to f32 conversion supported here");
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
    return Result;

  case ISD::FP_EXTEND:
    assert (DestType == MVT::f64 &&
            N.getOperand(0).getValueType() == MVT::f32 &&
            "only f32 to f64 conversion supported here");
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
    return Result;

  case ISD::CopyFromReg:
    {
      // Make sure we generate both values.
      if (Result != notIn)
        ExprMap[N.getValue(1)] = notIn;   // Generate the token
      else
        Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

      SDOperand Chain   = N.getOperand(0);

      Select(Chain);
      unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
      //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
      BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
      return Result;
    }

  case ISD::LOAD:
    {
      // Make sure we generate both values.
      if (Result != notIn)
        ExprMap[N.getValue(1)] = notIn;   // Generate the token
      else
        Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

      DestType = N.getValue(0).getValueType();

      SDOperand Chain   = N.getOperand(0);
      SDOperand Address = N.getOperand(1);
      Select(Chain);
      Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;

      if (Address.getOpcode() == ISD::GlobalAddress) {
        AlphaLowering.restoreGP(BB);
        Opc = GetSymVersion(Opc);
        has_sym = true;
        BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
      }
      else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
        AlphaLowering.restoreGP(BB);
        Opc = GetSymVersion(Opc);
        has_sym = true;
        BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
      }
      else if(Address.getOpcode() == ISD::FrameIndex) {
        BuildMI(BB, Opc, 2, Result)
          .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
          .addReg(Alpha::F31);
      } else {
        long offset;
        SelectAddr(Address, Tmp1, offset);
        BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
      }
      return Result;
    }
  case ISD::ConstantFP:
    if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
      if (CN->isExactlyValue(+0.0)) {
        BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
      } else if ( CN->isExactlyValue(-0.0)) {
        BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
      } else {
        abort();
      }
    }
    return Result;

  case ISD::SDIV:
  case ISD::MUL:
  case ISD::ADD:
  case ISD::SUB:
    switch( opcode ) {
    case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
    case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
    case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
    case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
    };

    ConstantFPSDNode *CN;
    if (opcode == ISD::SUB
        && (CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
        && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
    {
      Tmp2 = SelectExpr(N.getOperand(1));
      BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2);
    } else {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1));
      BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::EXTLOAD:
    {
      //include a conversion sequence for float loads to double
      if (Result != notIn)
        ExprMap[N.getValue(1)] = notIn;   // Generate the token
      else
        Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

      Tmp1 = MakeReg(MVT::f32);

      assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 &&
             "EXTLOAD not from f32");
      assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");

      SDOperand Chain   = N.getOperand(0);
      SDOperand Address = N.getOperand(1);
      Select(Chain);

      if (Address.getOpcode() == ISD::GlobalAddress) {
        AlphaLowering.restoreGP(BB);
        has_sym = true;
        BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
      }
      else if (ConstantPoolSDNode *CP =
               dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
      {
        AlphaLowering.restoreGP(BB);
        has_sym = true;
        BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
      }
      else if(Address.getOpcode() == ISD::FrameIndex) {
        Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
        BuildMI(BB, Alpha::LDS, 2, Tmp1)
          .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
          .addReg(Alpha::F31);
      } else {
        long offset;
        SelectAddr(Address, Tmp2, offset);
        BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2);
      }
      BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
      return Result;
    }

  case ISD::UINT_TO_FP:
  case ISD::SINT_TO_FP:
    {
      assert (N.getOperand(0).getValueType() == MVT::i64
              && "only quads can be loaded from");
      Tmp1 = SelectExpr(N.getOperand(0));  // Get the operand register
      Tmp2 = MakeReg(MVT::f64);
      MoveInt2FP(Tmp1, Tmp2, true);
      Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
      BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
      return Result;
    }
  }
  assert(0 && "should not get here");
  return 0;
}

unsigned ISel::SelectExpr(SDOperand N) {
  unsigned Result;
  unsigned Tmp1, Tmp2 = 0, Tmp3;
  unsigned Opc = 0;
  unsigned opcode = N.getOpcode();

  SDNode *Node = N.Val;
  MVT::ValueType DestType = N.getValueType();

  unsigned &Reg = ExprMap[N];
  if (Reg) return Reg;

  if (N.getOpcode() != ISD::CALL)
    Reg = Result = (N.getValueType() != MVT::Other) ?
      MakeReg(N.getValueType()) : notIn;
  else {
    // If this is a call instruction, make sure to prepare ALL of the result
    // values as well as the chain.
    if (Node->getNumValues() == 1)
      Reg = Result = notIn;  // Void call, just a chain.
    else {
      Result = MakeReg(Node->getValueType(0));
      ExprMap[N.getValue(0)] = Result;
      for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
        ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
      ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
    }
  }

  if (DestType == MVT::f64 || DestType == MVT::f32 ||
      (
       (opcode == ISD::LOAD || opcode == ISD::CopyFromReg ||
        opcode == ISD::EXTLOAD) &&
       (N.getValue(0).getValueType() == MVT::f32 ||
        N.getValue(0).getValueType() == MVT::f64)
       )
      )
    return SelectExprFP(N, Result);

  switch (opcode) {
  default:
    Node->dump();
    assert(0 && "Node not handled!\n");

  case ISD::MULHU:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, Alpha::UMULH, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
  case ISD::MULHS:
    {
      //MULHU - Ra<63>*Rb - Rb<63>*Ra
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1));
      Tmp3 = MakeReg(MVT::i64);
      BuildMI(BB, Alpha::UMULH, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
      unsigned V1 = MakeReg(MVT::i64);
      unsigned V2 = MakeReg(MVT::i64);
      BuildMI(BB, Alpha::CMOVGE, 3, V1).addReg(Tmp2).addReg(Alpha::R31).addReg(Tmp1);
      BuildMI(BB, Alpha::CMOVGE, 3, V2).addReg(Tmp1).addReg(Alpha::R31).addReg(Tmp2);
      unsigned IRes = MakeReg(MVT::i64);
      BuildMI(BB, Alpha::SUBQ, 2, IRes).addReg(Tmp3).addReg(V1);
      BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(IRes).addReg(V2);
      return Result;
    }
  case ISD::UNDEF: {
    BuildMI(BB, Alpha::IDEF, 0, Result);
    return Result;
  }

  case ISD::DYNAMIC_STACKALLOC:
    // Generate both result values.
    if (Result != notIn)
      ExprMap[N.getValue(1)] = notIn;   // Generate the token
    else
      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

    // FIXME: We are currently ignoring the requested alignment for handling
    // greater than the stack alignment.  This will need to be revisited at some
    // point.  Align = N.getOperand(2);

    if (!isa<ConstantSDNode>(N.getOperand(2)) ||
        cast<ConstantSDNode>(N.getOperand(2))->getValue() != 0) {
      std::cerr << "Cannot allocate stack object with greater alignment than"
                << " the stack alignment yet!";
      abort();
    }

    Select(N.getOperand(0));
    if (ConstantSDNode* CN = dyn_cast<ConstantSDNode>(N.getOperand(1)))
    {
      if (CN->getValue() < 32000)
      {
        BuildMI(BB, Alpha::LDA, 2, Alpha::R30)
          .addImm(-CN->getValue()).addReg(Alpha::R30);
      } else {
        Tmp1 = SelectExpr(N.getOperand(1));
        // Subtract size from stack pointer, thereby allocating some space.
        BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
      }
    } else {
      Tmp1 = SelectExpr(N.getOperand(1));
      // Subtract size from stack pointer, thereby allocating some space.
      BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
    }

    // Put a pointer to the space into the result register, by copying the stack
    // pointer.
    BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R30).addReg(Alpha::R30);
    return Result;

//   case ISD::ConstantPool:
//     Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
//     AlphaLowering.restoreGP(BB);
//     BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(Tmp1);
//     return Result;

  case ISD::FrameIndex:
    BuildMI(BB, Alpha::LDA, 2, Result)
      .addFrameIndex(cast<FrameIndexSDNode>(N)->getIndex())
      .addReg(Alpha::F31);
    return Result;

  case ISD::EXTLOAD:
  case ISD::ZEXTLOAD:
  case ISD::SEXTLOAD:
  case ISD::LOAD:
    {
      // Make sure we generate both values.
      if (Result != notIn)
        ExprMap[N.getValue(1)] = notIn;   // Generate the token
      else
        Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

      SDOperand Chain   = N.getOperand(0);
      SDOperand Address = N.getOperand(1);
      Select(Chain);

      assert(Node->getValueType(0) == MVT::i64 &&
             "Unknown type to sign extend to.");
      if (opcode == ISD::LOAD)
        Opc = Alpha::LDQ;
      else
        switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
        default: Node->dump(); assert(0 && "Bad sign extend!");
        case MVT::i32: Opc = Alpha::LDL;
          assert(opcode != ISD::ZEXTLOAD && "Not sext"); break;
        case MVT::i16: Opc = Alpha::LDWU;
          assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
        case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
        case MVT::i8: Opc = Alpha::LDBU;
          assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
        }

      if (Address.getOpcode() == ISD::GlobalAddress) {
        AlphaLowering.restoreGP(BB);
        Opc = GetSymVersion(Opc);
        has_sym = true;
        BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
      }
      else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
        AlphaLowering.restoreGP(BB);
        Opc = GetSymVersion(Opc);
        has_sym = true;
        BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
      }
      else if(Address.getOpcode() == ISD::FrameIndex) {
        BuildMI(BB, Opc, 2, Result)
          .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
          .addReg(Alpha::F31);
      } else {
        long offset;
        SelectAddr(Address, Tmp1, offset);
        BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
      }
      return Result;
    }

  case ISD::GlobalAddress:
    AlphaLowering.restoreGP(BB);
    has_sym = true;
    BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
      .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
    return Result;

  case ISD::CALL:
    {
      Select(N.getOperand(0));

      // The chain for this call is now lowered.
      ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));

      //grab the arguments
      std::vector<unsigned> argvregs;
      //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
      for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
        argvregs.push_back(SelectExpr(N.getOperand(i)));

      //in reg args
      for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
      {
        unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
                               Alpha::R19, Alpha::R20, Alpha::R21};
        unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
                                 Alpha::F19, Alpha::F20, Alpha::F21};
        switch(N.getOperand(i+2).getValueType()) {
        default:
          Node->dump();
          N.getOperand(i).Val->dump();
          std::cerr << "Type for " << i << " is: " <<
            N.getOperand(i+2).getValueType() << "\n";
          assert(0 && "Unknown value type for call");
        case MVT::i1:
        case MVT::i8:
        case MVT::i16:
        case MVT::i32:
        case MVT::i64:
          BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
          break;
        case MVT::f32:
        case MVT::f64:
          BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
          break;
        }
      }
      //in mem args
      for (int i = 6, e = argvregs.size(); i < e; ++i)
      {
        switch(N.getOperand(i+2).getValueType()) {
        default:
          Node->dump();
          N.getOperand(i).Val->dump();
          std::cerr << "Type for " << i << " is: " <<
            N.getOperand(i+2).getValueType() << "\n";
          assert(0 && "Unknown value type for call");
        case MVT::i1:
        case MVT::i8:
        case MVT::i16:
        case MVT::i32:
        case MVT::i64:
          BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
          break;
        case MVT::f32:
          BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
          break;
        case MVT::f64:
          BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
          break;
        }
      }
      //build the right kind of call
      if (GlobalAddressSDNode *GASD =
          dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
      {
        if (GASD->getGlobal()->isExternal()) {
          //use safe calling convention
          AlphaLowering.restoreGP(BB);
          has_sym = true;
          BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal());
        } else {
          //use PC relative branch call
          AlphaLowering.restoreGP(BB);
          BuildMI(BB, Alpha::BSR, 1, Alpha::R26).addGlobalAddress(GASD->getGlobal(),true);
        }
      }
      else if (ExternalSymbolSDNode *ESSDN =
               dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
      {
        AlphaLowering.restoreGP(BB);
        has_sym = true;
        BuildMI(BB, Alpha::CALL, 1).addExternalSymbol(ESSDN->getSymbol(), true);
      } else {
        //no need to restore GP as we are doing an indirect call
        Tmp1 = SelectExpr(N.getOperand(1));
        BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
        BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
      }

      //push the result into a virtual register

      switch (Node->getValueType(0)) {
      default: Node->dump(); assert(0 && "Unknown value type for call result!");
      case MVT::Other: return notIn;
      case MVT::i1:
      case MVT::i8:
      case MVT::i16:
      case MVT::i32:
      case MVT::i64:
        BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
        break;
      case MVT::f32:
      case MVT::f64:
        BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
        break;
      }
      return Result+N.ResNo;
    }

  case ISD::SIGN_EXTEND_INREG:
    {
      //do SDIV opt for all levels of ints if not dividing by a constant
      if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV
          && N.getOperand(0).getOperand(1).getOpcode() != ISD::Constant)
      {
        unsigned Tmp4 = MakeReg(MVT::f64);
        unsigned Tmp5 = MakeReg(MVT::f64);
        unsigned Tmp6 = MakeReg(MVT::f64);
        unsigned Tmp7 = MakeReg(MVT::f64);
        unsigned Tmp8 = MakeReg(MVT::f64);
        unsigned Tmp9 = MakeReg(MVT::f64);

        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
        MoveInt2FP(Tmp1, Tmp4, true);
        MoveInt2FP(Tmp2, Tmp5, true);
        BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4);
        BuildMI(BB, Alpha::CVTQT, 1, Tmp7).addReg(Tmp5);
        BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7);
        BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8);
        MoveFP2Int(Tmp9, Result, true);
        return Result;
      }

      //Alpha has instructions for a bunch of signed 32 bit stuff
      if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
      {
        switch (N.getOperand(0).getOpcode()) {
        case ISD::ADD:
        case ISD::SUB:
        case ISD::MUL:
          {
            bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
            bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
            //FIXME: first check for Scaled Adds and Subs!
            ConstantSDNode* CSD = NULL;
            if(!isMul && N.getOperand(0).getOperand(0).getOpcode() == ISD::SHL &&
               (CSD = dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(0).getOperand(1))) &&
               (CSD->getValue() == 2 || CSD->getValue() == 3))
            {
              bool use4 = CSD->getValue() == 2;
              Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
              Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
              BuildMI(BB, isAdd?(use4?Alpha::S4ADDL:Alpha::S8ADDL):(use4?Alpha::S4SUBL:Alpha::S8SUBL),
                      2,Result).addReg(Tmp1).addReg(Tmp2);
            }
            else if(isAdd && N.getOperand(0).getOperand(1).getOpcode() == ISD::SHL &&
                    (CSD = dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1).getOperand(1))) &&
                    (CSD->getValue() == 2 || CSD->getValue() == 3))
            {
              bool use4 = CSD->getValue() == 2;
              Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
              Tmp2 = SelectExpr(N.getOperand(0).getOperand(0));
              BuildMI(BB, use4?Alpha::S4ADDL:Alpha::S8ADDL, 2,Result).addReg(Tmp1).addReg(Tmp2);
            }
            else if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
               cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
            { //Normal imm add/sub
              Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
              Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
              Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
            }
            else
            { //Normal add/sub
              Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULL : Alpha::SUBL);
              Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
              Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
            }
            return Result;
          }
        default: break; //Fall Though;
        }
      } //Every thing else fall though too, including unhandled opcodes above
      Tmp1 = SelectExpr(N.getOperand(0));
      MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
      //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
      switch(MVN->getExtraValueType())
      {
      default:
        Node->dump();
        assert(0 && "Sign Extend InReg not there yet");
        break;
      case MVT::i32:
        {
          BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
          break;
        }
      case MVT::i16:
        BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
        break;
      case MVT::i8:
        BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
        break;
      case MVT::i1:
        Tmp2 = MakeReg(MVT::i64);
        BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1);
        BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp2);
        break;
      }
      return Result;
    }

  case ISD::SETCC:
    {
      if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
        if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
          bool isConst1 = false;
          bool isConst2 = false;
          int dir;

          //Tmp1 = SelectExpr(N.getOperand(0));
          if(N.getOperand(0).getOpcode() == ISD::Constant &&
             cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
            isConst1 = true;
          if(N.getOperand(1).getOpcode() == ISD::Constant &&
             cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
            isConst2 = true;

          switch (SetCC->getCondition()) {
          default: Node->dump(); assert(0 && "Unknown integer comparison!");
          case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
          case ISD::SETLT:
            Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
          case ISD::SETLE:
            Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
          case ISD::SETGT:
            Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
          case ISD::SETGE:
            Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
          case ISD::SETULT:
            Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
          case ISD::SETUGT:
            Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
          case ISD::SETULE:
            Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
          case ISD::SETUGE:
            Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
          case ISD::SETNE: {//Handle this one special
            //std::cerr << "Alpha does not have a setne.\n";
            //abort();
            Tmp1 = SelectExpr(N.getOperand(0));
            Tmp2 = SelectExpr(N.getOperand(1));
            Tmp3 = MakeReg(MVT::i64);
            BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
            //Remeber we have the Inv for this CC
            CCInvMap[N] = Tmp3;
            //and invert
            BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
            return Result;
          }
          }
          if (dir == 1) {
            Tmp1 = SelectExpr(N.getOperand(0));
            if (isConst2) {
              Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
            } else {
              Tmp2 = SelectExpr(N.getOperand(1));
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
            }
          } else if (dir == 2) {
            Tmp1 = SelectExpr(N.getOperand(1));
            if (isConst1) {
              Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
            } else {
              Tmp2 = SelectExpr(N.getOperand(0));
              BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
            }
          } else { //dir == 0
            if (isConst1) {
              Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
              Tmp2 = SelectExpr(N.getOperand(1));
              BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
            } else if (isConst2) {
              Tmp1 = SelectExpr(N.getOperand(0));
              Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
              BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
            } else {
              Tmp1 = SelectExpr(N.getOperand(0));
              Tmp2 = SelectExpr(N.getOperand(1));
              BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
            }
          }
        } else {
          //do the comparison
          Tmp1 = MakeReg(MVT::f64);
          bool inv = SelectFPSetCC(N, Tmp1);

          //now arrange for Result (int) to have a 1 or 0
          Tmp2 = MakeReg(MVT::i64);
          BuildMI(BB, Alpha::ADDQi, 2, Tmp2).addReg(Alpha::R31).addImm(1);
          Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP;
          BuildMI(BB, Opc, 3, Result).addReg(Tmp2).addImm(0).addReg(Tmp1);
        }
      }
      return Result;
    }

  case ISD::CopyFromReg:
    {
      ++count_ins;

      // Make sure we generate both values.
      if (Result != notIn)
        ExprMap[N.getValue(1)] = notIn;   // Generate the token
      else
        Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());

      SDOperand Chain   = N.getOperand(0);

      Select(Chain);
      unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
      //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
      BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
      return Result;
    }

    //Most of the plain arithmetic and logic share the same form, and the same
    //constant immediate test
  case ISD::XOR:
    //Match Not
    if (N.getOperand(1).getOpcode() == ISD::Constant &&
        cast<ConstantSDNode>(N.getOperand(1))->getSignExtended() == -1)
      {
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp1);
        return Result;
      }
    //Fall through
  case ISD::AND:
    //handle zap
    if (opcode == ISD::AND && N.getOperand(1).getOpcode() == ISD::Constant)
    {
      uint64_t k = cast<ConstantSDNode>(N.getOperand(1))->getValue();
      unsigned int build = 0;
      for(int i = 0; i < 8; ++i)
      {
        if ((k & 0x00FF) == 0x00FF)
          build |= 1 << i;
        else if ((k & 0x00FF) != 0)
        { build = 0; break; }
        k >>= 8;
      }
      if (build)
      {
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, Alpha::ZAPNOTi, 2, Result).addReg(Tmp1).addImm(build);
        return Result;
      }
    }
  case ISD::OR:
    //Check operand(0) == Not
    if (N.getOperand(0).getOpcode() == ISD::XOR &&
        N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
        cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getSignExtended() == -1)
      {
        switch(opcode) {
        case ISD::AND: Opc = Alpha::BIC; break;
        case ISD::OR:  Opc = Alpha::ORNOT; break;
        case ISD::XOR: Opc = Alpha::EQV; break;
        }
        Tmp1 = SelectExpr(N.getOperand(1));
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(0));
        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
        return Result;
      }
    //Check operand(1) == Not
    if (N.getOperand(1).getOpcode() == ISD::XOR &&
        N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant &&
        cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getSignExtended() == -1)
      {
        switch(opcode) {
        case ISD::AND: Opc = Alpha::BIC; break;
        case ISD::OR:  Opc = Alpha::ORNOT; break;
        case ISD::XOR: Opc = Alpha::EQV; break;
        }
        Tmp1 = SelectExpr(N.getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(1).getOperand(0));
        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
        return Result;
      }
    //Fall through
  case ISD::SHL:
  case ISD::SRL:
  case ISD::SRA:
  case ISD::MUL:
    assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
    if(N.getOperand(1).getOpcode() == ISD::Constant &&
       cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
    {
      switch(opcode) {
      case ISD::AND: Opc = Alpha::ANDi; break;
      case ISD::OR:  Opc = Alpha::BISi; break;
      case ISD::XOR: Opc = Alpha::XORi; break;
      case ISD::SHL: Opc = Alpha::SLi; break;
      case ISD::SRL: Opc = Alpha::SRLi; break;
      case ISD::SRA: Opc = Alpha::SRAi; break;
      case ISD::MUL: Opc = Alpha::MULQi; break;
      };
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
      BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
    } else {
      switch(opcode) {
      case ISD::AND: Opc = Alpha::AND; break;
      case ISD::OR:  Opc = Alpha::BIS; break;
      case ISD::XOR: Opc = Alpha::XOR; break;
      case ISD::SHL: Opc = Alpha::SL; break;
      case ISD::SRL: Opc = Alpha::SRL; break;
      case ISD::SRA: Opc = Alpha::SRA; break;
      case ISD::MUL: Opc = Alpha::MULQ; break;
      };
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1));
      BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::ADD:
  case ISD::SUB:
    {
      bool isAdd = opcode == ISD::ADD;

      //first check for Scaled Adds and Subs!
      //Valid for add and sub
      ConstantSDNode* CSD = NULL;
      if(N.getOperand(0).getOpcode() == ISD::SHL &&
         (CSD = dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) &&
         (CSD->getValue() == 2 || CSD->getValue() == 3))
      {
        bool use4 = CSD->getValue() == 2;
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(0));
        if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1))) && CSD->getValue() <= 255)
          BuildMI(BB, isAdd?(use4?Alpha::S4ADDQi:Alpha::S8ADDQi):(use4?Alpha::S4SUBQi:Alpha::S8SUBQi),
                  2, Result).addReg(Tmp2).addImm(CSD->getValue());
        else {
          Tmp1 = SelectExpr(N.getOperand(1));
          BuildMI(BB, isAdd?(use4?Alpha::S4ADDQi:Alpha::S8ADDQi):(use4?Alpha::S4SUBQi:Alpha::S8SUBQi),
                  2, Result).addReg(Tmp2).addReg(Tmp1);
        }
      }
      //Position prevents subs
      else if(N.getOperand(1).getOpcode() == ISD::SHL && isAdd &&
              (CSD = dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) &&
              (CSD->getValue() == 2 || CSD->getValue() == 3))
      {
        bool use4 = CSD->getValue() == 2;
        Tmp2 = SelectExpr(N.getOperand(1).getOperand(0));
        if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(0))) && CSD->getValue() <= 255)
          BuildMI(BB, use4?Alpha::S4ADDQi:Alpha::S8ADDQi, 2, Result).addReg(Tmp2)
            .addImm(CSD->getValue());
        else {
          Tmp1 = SelectExpr(N.getOperand(0));
          BuildMI(BB, use4?Alpha::S4ADDQ:Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
        }
      }
      //small addi
      else if((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1))) &&
              CSD->getValue() <= 255)
      { //Normal imm add/sub
        Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CSD->getValue());
      }
      //larger addi
      else if((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1))) &&
              CSD->getSignExtended() <= 32767 &&
              CSD->getSignExtended() >= -32767)
      { //LDA
        Tmp1 = SelectExpr(N.getOperand(0));
        Tmp2 = (long)CSD->getSignExtended();
        if (!isAdd)
          Tmp2 = -Tmp2;
        BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
      }
      //give up and do the operation
      else {
        //Normal add/sub
        Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
        Tmp1 = SelectExpr(N.getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(1));
        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
      }
      return Result;
    }

  case ISD::SDIV:
    {
      ConstantSDNode* CSD;
      //check if we can convert into a shift!
      if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1).Val)) &&
          (int64_t)CSD->getSignExtended() != 0 &&
          ExactLog2(abs((int64_t)CSD->getSignExtended())) != 0)
      {
        unsigned k = ExactLog2(abs(CSD->getSignExtended()));
        Tmp1 = SelectExpr(N.getOperand(0));
        if (k == 1)
          Tmp2 = Tmp1;
        else
        {
          Tmp2 = MakeReg(MVT::i64);
          BuildMI(BB, Alpha::SRAi, 2, Tmp2).addReg(Tmp1).addImm(k - 1);
        }
        Tmp3 = MakeReg(MVT::i64);
        BuildMI(BB, Alpha::SRLi, 2, Tmp3).addReg(Tmp2).addImm(64-k);
        unsigned Tmp4 = MakeReg(MVT::i64);
        BuildMI(BB, Alpha::ADDQ, 2, Tmp4).addReg(Tmp3).addReg(Tmp1);
        if ((int64_t)CSD->getSignExtended() > 0)
          BuildMI(BB, Alpha::SRAi, 2, Result).addReg(Tmp4).addImm(k);
        else
        {
          unsigned Tmp5 = MakeReg(MVT::i64);
          BuildMI(BB, Alpha::SRAi, 2, Tmp5).addReg(Tmp4).addImm(k);
          BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp5);
        }
        return Result;
      }
    }
    //Else fall through

  case ISD::UDIV:
    {
      ConstantSDNode* CSD;
      if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1).Val)) &&
          ((int64_t)CSD->getSignExtended() >= 2 ||
           (int64_t)CSD->getSignExtended() <= -2))
      {
        // If this is a divide by constant, we can emit code using some magic
        // constants to implement it as a multiply instead.
        ExprMap.erase(N);
        if (opcode == ISD::SDIV)
          return SelectExpr(BuildSDIVSequence(N));
        else
          return SelectExpr(BuildUDIVSequence(N));
      }
    }
    //else fall though
  case ISD::UREM:
  case ISD::SREM:
    //FIXME: alpha really doesn't support any of these operations,
    // the ops are expanded into special library calls with
    // special calling conventions
    //Restore GP because it is a call after all...
    switch(opcode) {
    case ISD::UREM: Opc = Alpha::REMQU; break;
    case ISD::SREM: Opc = Alpha::REMQ; break;
    case ISD::UDIV: Opc = Alpha::DIVQU; break;
    case ISD::SDIV: Opc = Alpha::DIVQ; break;
    }
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    //set up regs explicitly (helps Reg alloc)
    BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp1).addReg(Tmp1);
    BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp2).addReg(Tmp2);
    AlphaLowering.restoreGP(BB);
    BuildMI(BB, Opc, 2).addReg(Alpha::R24).addReg(Alpha::R25);
    BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R27).addReg(Alpha::R27);
    return Result;

  case ISD::FP_TO_UINT:
  case ISD::FP_TO_SINT:
    {
      assert (DestType == MVT::i64 && "only quads can be loaded to");
      MVT::ValueType SrcType = N.getOperand(0).getValueType();
      assert (SrcType == MVT::f32 || SrcType == MVT::f64);
      Tmp1 = SelectExpr(N.getOperand(0));  // Get the operand register
      if (SrcType == MVT::f32)
        {
          Tmp2 = MakeReg(MVT::f64);
          BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
          Tmp1 = Tmp2;
        }
      Tmp2 = MakeReg(MVT::f64);
      BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
      MoveFP2Int(Tmp2, Result, true);

      return Result;
    }

  case ISD::SELECT:
    {
      //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) and can save stack use
      //Tmp1 = SelectExpr(N.getOperand(0)); //Cond
      //Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
      //Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
      // Get the condition into the zero flag.
      //BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);

      SDOperand CC = N.getOperand(0);
      SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);

      if (CC.getOpcode() == ISD::SETCC &&
          !MVT::isInteger(SetCC->getOperand(0).getValueType()))
      { //FP Setcc -> Int Select
        Tmp1 = MakeReg(MVT::f64);
        Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
        Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
        bool inv = SelectFPSetCC(CC, Tmp1);
        BuildMI(BB, inv?Alpha::CMOVNE_FP:Alpha::CMOVEQ_FP, 2, Result)
          .addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
        return Result;
      }
      if (CC.getOpcode() == ISD::SETCC) {
        //Int SetCC -> Select
        //Dropping the CC is only useful if we are comparing to 0
        if((SetCC->getOperand(1).getOpcode() == ISD::Constant &&
           cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0) ||
           (SetCC->getOperand(0).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0))
        {
          //figure out a few things
          bool LeftZero = SetCC->getOperand(0).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0;
          bool RightZero = SetCC->getOperand(0).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0;
          bool LeftConst = N.getOperand(1).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255;
          bool RightConst = N.getOperand(2).getOpcode() == ISD::Constant &&
            cast<ConstantSDNode>(N.getOperand(2))->getValue() <= 255;
          bool useImm = LeftConst || RightConst;

          //Fix up CC
          ISD::CondCode cCode= SetCC->getCondition();
          if (RightConst && !LeftConst) //Invert sense to get Imm field right
            cCode = ISD::getSetCCInverse(cCode, true);
          if (LeftZero && !RightZero) //Swap Operands
            cCode = ISD::getSetCCSwappedOperands(cCode);

          //Choose the CMOV
          switch (cCode) {
          default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
          case ISD::SETEQ:  Opc = useImm?Alpha::CMOVEQi:Alpha::CMOVEQ;      break;
          case ISD::SETLT:  Opc = useImm?Alpha::CMOVLTi:Alpha::CMOVLT;      break;
          case ISD::SETLE:  Opc = useImm?Alpha::CMOVLEi:Alpha::CMOVLE;      break;
          case ISD::SETGT:  Opc = useImm?Alpha::CMOVGTi:Alpha::CMOVGT;      break;
          case ISD::SETGE:  Opc = useImm?Alpha::CMOVGEi:Alpha::CMOVGE;      break;
          case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true");  break;
          case ISD::SETUGT: Opc = useImm?Alpha::CMOVNEi:Alpha::CMOVNE;      break;
          case ISD::SETULE: Opc = useImm?Alpha::CMOVEQi:Alpha::CMOVEQ;      break; //Technically you could have this CC
          case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
          case ISD::SETNE:  Opc = useImm?Alpha::CMOVNEi:Alpha::CMOVNE;      break;
          }
          if(LeftZero && !RightZero) //swap Operands
            Tmp1 = SelectExpr(SetCC->getOperand(1)); //Cond
          else
            Tmp1 = SelectExpr(SetCC->getOperand(0)); //Cond

          if (LeftConst) {
            Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
            BuildMI(BB, Opc, 2, Result).addReg(Tmp3)
                .addImm(cast<ConstantSDNode>(N.getOperand(1))->getValue())
                .addReg(Tmp1);
          } else if (RightConst) {
            Tmp3 = SelectExpr(N.getOperand(1)); //Use if FALSE
            BuildMI(BB, Opc, 2, Result).addReg(Tmp3)
                .addImm(cast<ConstantSDNode>(N.getOperand(2))->getValue())
                .addReg(Tmp1);
          } else {
            Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
            Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
            BuildMI(BB, Opc, 2, Result).addReg(Tmp3).addReg(Tmp2).addReg(Tmp1);
          }
          return Result;
        }
        //Otherwise, fall though
      }
      Tmp1 = SelectExpr(N.getOperand(0)); //Cond
      Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
      Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
      BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);

      return Result;
    }

  case ISD::Constant:
    {
      int64_t val = (int64_t)cast<ConstantSDNode>(N)->getValue();
      if (val <= IMM_HIGH && val >= IMM_LOW) {
        BuildMI(BB, Alpha::LDA, 2, Result).addImm(val).addReg(Alpha::R31);
      }
      else if (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT &&
               val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT) {
        Tmp1 = MakeReg(MVT::i64);
        BuildMI(BB, Alpha::LDAH, 2, Tmp1).addImm(getUpper16(val)).addReg(Alpha::R31);
        BuildMI(BB, Alpha::LDA, 2, Result).addImm(getLower16(val)).addReg(Tmp1);
      }
      else {
        MachineConstantPool *CP = BB->getParent()->getConstantPool();
        ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
        unsigned CPI = CP->getConstantPoolIndex(C);
        AlphaLowering.restoreGP(BB);
        BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(CPI);
      }
      return Result;
    }
  }

  return 0;
}

void ISel::Select(SDOperand N) {
  unsigned Tmp1, Tmp2, Opc;
  unsigned opcode = N.getOpcode();

  if (!ExprMap.insert(std::make_pair(N, notIn)).second)
    return;  // Already selected.

  SDNode *Node = N.Val;

  switch (opcode) {

  default:
    Node->dump(); std::cerr << "\n";
    assert(0 && "Node not handled yet!");

  case ISD::BRCOND: {
    SelectBranchCC(N);
    return;
  }

  case ISD::BR: {
    MachineBasicBlock *Dest =
      cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();

    Select(N.getOperand(0));
    BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
    return;
  }

  case ISD::ImplicitDef:
    ++count_ins;
    Select(N.getOperand(0));
    BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
    return;

  case ISD::EntryToken: return;  // Noop

  case ISD::TokenFactor:
    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
      Select(Node->getOperand(i));

    //N.Val->dump(); std::cerr << "\n";
    //assert(0 && "Node not handled yet!");

    return;

  case ISD::CopyToReg:
    ++count_outs;
    Select(N.getOperand(0));
    Tmp1 = SelectExpr(N.getOperand(1));
    Tmp2 = cast<RegSDNode>(N)->getReg();

    if (Tmp1 != Tmp2) {
      if (N.getOperand(1).getValueType() == MVT::f64 ||
          N.getOperand(1).getValueType() == MVT::f32)
        BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
      else
        BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
    }
    return;

  case ISD::RET:
    ++count_outs;
    switch (N.getNumOperands()) {
    default:
      std::cerr << N.getNumOperands() << "\n";
      for (unsigned i = 0; i < N.getNumOperands(); ++i)
        std::cerr << N.getOperand(i).getValueType() << "\n";
      Node->dump();
      assert(0 && "Unknown return instruction!");
    case 2:
      Select(N.getOperand(0));
      Tmp1 = SelectExpr(N.getOperand(1));
      switch (N.getOperand(1).getValueType()) {
      default: Node->dump();
        assert(0 && "All other types should have been promoted!!");
      case MVT::f64:
      case MVT::f32:
        BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
        break;
      case MVT::i32:
      case MVT::i64:
        BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
        break;
      }
      break;
    case 1:
      Select(N.getOperand(0));
      break;
    }
    //Tmp2 = AlphaLowering.getRetAddr();
    //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
    BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
    return;

  case ISD::TRUNCSTORE:
  case ISD::STORE:
    {
      SDOperand Chain   = N.getOperand(0);
      SDOperand Value = N.getOperand(1);
      SDOperand Address = N.getOperand(2);
      Select(Chain);

      Tmp1 = SelectExpr(Value); //value

      if (opcode == ISD::STORE) {
        switch(Value.getValueType()) {
        default: assert(0 && "unknown Type in store");
        case MVT::i64: Opc = Alpha::STQ; break;
        case MVT::f64: Opc = Alpha::STT; break;
        case MVT::f32: Opc = Alpha::STS; break;
        }
      } else { //ISD::TRUNCSTORE
        switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
        default: assert(0 && "unknown Type in store");
        case MVT::i1: //FIXME: DAG does not promote this load
        case MVT::i8: Opc = Alpha::STB; break;
        case MVT::i16: Opc = Alpha::STW; break;
        case MVT::i32: Opc = Alpha::STL; break;
        }
      }

      if (Address.getOpcode() == ISD::GlobalAddress)
      {
        AlphaLowering.restoreGP(BB);
        Opc = GetSymVersion(Opc);
        has_sym = true;
        BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
      }
      else if(Address.getOpcode() == ISD::FrameIndex)
      {
        BuildMI(BB, Opc, 3).addReg(Tmp1)
          .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
          .addReg(Alpha::F31);
      }
      else
      {
        long offset;
        SelectAddr(Address, Tmp2, offset);
        BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
      }
      return;
    }

  case ISD::EXTLOAD:
  case ISD::SEXTLOAD:
  case ISD::ZEXTLOAD:
  case ISD::LOAD:
  case ISD::CopyFromReg:
  case ISD::CALL:
  case ISD::DYNAMIC_STACKALLOC:
    ExprMap.erase(N);
    SelectExpr(N);
    return;

  case ISD::ADJCALLSTACKDOWN:
  case ISD::ADJCALLSTACKUP:
    Select(N.getOperand(0));
    Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();

    Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
      Alpha::ADJUSTSTACKUP;
    BuildMI(BB, Opc, 1).addImm(Tmp1);
    return;

  case ISD::PCMARKER:
    Select(N.getOperand(0)); //Chain
    BuildMI(BB, Alpha::PCLABEL, 2).addImm( cast<ConstantSDNode>(N.getOperand(1))->getValue());
    return;
  }
  assert(0 && "Should not be reached!");
}


/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
/// into a machine code representation using pattern matching and a machine
/// description file.
///
FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
  return new ISel(TM);
}

