//===-- PPC32ISelPattern.cpp - A pattern matching inst selector for PPC32 -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Nate Begeman 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 32 bit PowerPC.
// Magic number generation for integer divide from the PowerPC Compiler Writer's
// Guide, section 3.2.3.5
//
//===----------------------------------------------------------------------===//

#include "PPC.h"
#include "PPCInstrBuilder.h"
#include "PPCTargetMachine.h"
#include "PPCISelLowering.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/Statistic.h"
#include <set>
#include <algorithm>
using namespace llvm;

namespace {
Statistic<> Recorded("ppc-codegen", "Number of recording ops emitted");
Statistic<> FusedFP ("ppc-codegen", "Number of fused fp operations");
Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");

//===--------------------------------------------------------------------===//
// ISel - PPC32 specific code to select PPC32 machine instructions for
// SelectionDAG operations.
//===--------------------------------------------------------------------===//

class ISel : public SelectionDAGISel {
  PPCTargetLowering PPCLowering;
  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.
  std::map<SDOperand, unsigned> ExprMap;

  unsigned GlobalBaseReg;
  bool GlobalBaseInitialized;
  bool RecordSuccess;
public:
  ISel(TargetMachine &TM) : SelectionDAGISel(PPCLowering), PPCLowering(TM),
                            ISelDAG(0) {}

  /// runOnFunction - Override this function in order to reset our per-function
  /// variables.
  virtual bool runOnFunction(Function &Fn) {
    // Make sure we re-emit a set of the global base reg if necessary
    GlobalBaseInitialized = false;
    return SelectionDAGISel::runOnFunction(Fn);
  }

  /// 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());
    // Codegen the basic block.
    ISelDAG = &DAG;
    Select(DAG.getRoot());

    // Clear state used for selection.
    ExprMap.clear();
    ISelDAG = 0;
  }

  // convenience functions for virtual register creation
  inline unsigned MakeIntReg() {
    return RegMap->createVirtualRegister(PPC::GPRCRegisterClass);
  }
  
  // dag -> dag expanders for integer divide by constant
  SDOperand BuildSDIVSequence(SDOperand N);
  SDOperand BuildUDIVSequence(SDOperand N);

  unsigned getGlobalBaseReg();
  void MoveCRtoGPR(unsigned CCReg, ISD::CondCode CC, unsigned Result);
  bool SelectBitfieldInsert(SDOperand OR, unsigned Result);
  unsigned FoldIfWideZeroExtend(SDOperand N);
  unsigned SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);
  bool SelectIntImmediateExpr(SDOperand N, unsigned Result,
                              unsigned OCHi, unsigned OCLo,
                              bool IsArithmetic = false, bool Negate = false);
  unsigned SelectExpr(SDOperand N, bool Recording=false);
  void Select(SDOperand N);

  unsigned SelectAddr(SDOperand N, unsigned& Reg, int& offset);
  void SelectBranchCC(SDOperand N);
  
  virtual const char *getPassName() const {
    return "PowerPC Pattern Instruction Selection";
  } 
};

// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with
// any number of 0s on either side.  The 1s are allowed to wrap from LSB to
// MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs.  0x0F0F0000 is
// not, since all 1s are not contiguous.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
  if (isShiftedMask_32(Val)) {
    // look for the first non-zero bit
    MB = CountLeadingZeros_32(Val);
    // look for the first zero bit after the run of ones
    ME = CountLeadingZeros_32((Val - 1) ^ Val);
    return true;
  } else if (isShiftedMask_32(Val = ~Val)) { // invert mask
    // effectively look for the first zero bit
    ME = CountLeadingZeros_32(Val) - 1;
    // effectively look for the first one bit after the run of zeros
    MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1;
    return true;
  }
  // no run present
  return false;
}

// isRotateAndMask - Returns true if Mask and Shift can be folded in to a rotate
// and mask opcode and mask operation.
static bool isRotateAndMask(unsigned Opcode, unsigned Shift, unsigned Mask,
                            bool IsShiftMask,
                            unsigned &SH, unsigned &MB, unsigned &ME) {
  if (Shift > 31) return false;
  unsigned Indeterminant = ~0;       // bit mask marking indeterminant results
  
  if (Opcode == ISD::SHL) { // shift left
    // apply shift to mask if it comes first
    if (IsShiftMask) Mask = Mask << Shift;
    // determine which bits are made indeterminant by shift
    Indeterminant = ~(0xFFFFFFFFu << Shift);
  } else if (Opcode == ISD::SRL) { // shift rights
    // apply shift to mask if it comes first
    if (IsShiftMask) Mask = Mask >> Shift;
    // determine which bits are made indeterminant by shift
    Indeterminant = ~(0xFFFFFFFFu >> Shift);
    // adjust for the left rotate
    Shift = 32 - Shift;
  }
  
  // if the mask doesn't intersect any Indeterminant bits
  if (Mask && !(Mask & Indeterminant)) {
    SH = Shift;
    // make sure the mask is still a mask (wrap arounds may not be)
    return isRunOfOnes(Mask, MB, ME);
  }
  
  // can't do it
  return false;
}

// isIntImmediate - This method tests to see if a constant operand.
// If so Imm will receive the 32 bit value.
static bool isIntImmediate(SDOperand N, unsigned& Imm) {
  // test for constant
  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
    // retrieve value
    Imm = (unsigned)CN->getValue();
    // passes muster
    return true;
  }
  // not a constant
  return false;
}

// isOpcWithIntImmediate - This method tests to see if the node is a specific
// opcode and that it has a immediate integer right operand.
// If so Imm will receive the 32 bit value.
static bool isOpcWithIntImmediate(SDOperand N, unsigned Opc, unsigned& Imm) {
  return N.getOpcode() == Opc && isIntImmediate(N.getOperand(1), Imm);
}

// isOprShiftImm - Returns true if the specified operand is a shift opcode with
// a immediate shift count less than 32.
static bool isOprShiftImm(SDOperand N, unsigned& Opc, unsigned& SH) {
  Opc = N.getOpcode();
  return (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) &&
         isIntImmediate(N.getOperand(1), SH) && SH < 32;
}

// isOprNot - Returns true if the specified operand is an xor with immediate -1.
static bool isOprNot(SDOperand N) {
  unsigned Imm;
  return isOpcWithIntImmediate(N, ISD::XOR, Imm) && (signed)Imm == -1;
}

// Immediate constant composers.
// Lo16 - grabs the lo 16 bits from a 32 bit constant.
// Hi16 - grabs the hi 16 bits from a 32 bit constant.
// HA16 - computes the hi bits required if the lo bits are add/subtracted in
// arithmethically.
static unsigned Lo16(unsigned x)  { return x & 0x0000FFFF; }
static unsigned Hi16(unsigned x)  { return Lo16(x >> 16); }
static unsigned HA16(unsigned x)  { return Hi16((signed)x - (signed short)x); }

/// NodeHasRecordingVariant - If SelectExpr can always produce code for
/// NodeOpcode that also sets CR0 as a side effect, return true.  Otherwise,
/// return false.
static bool NodeHasRecordingVariant(unsigned NodeOpcode) {
  switch(NodeOpcode) {
  default: return false;
  case ISD::AND:
  case ISD::OR:
    return true;
  }
}

/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding
/// to Condition.
static unsigned getBCCForSetCC(ISD::CondCode CC) {
  switch (CC) {
  default: assert(0 && "Unknown condition!"); abort();
  case ISD::SETEQ:  return PPC::BEQ;
  case ISD::SETNE:  return PPC::BNE;
  case ISD::SETULT:
  case ISD::SETLT:  return PPC::BLT;
  case ISD::SETULE:
  case ISD::SETLE:  return PPC::BLE;
  case ISD::SETUGT:
  case ISD::SETGT:  return PPC::BGT;
  case ISD::SETUGE:
  case ISD::SETGE:  return PPC::BGE;
  }
  return 0;
}

/// getCRIdxForSetCC - Return the index of the condition register field
/// associated with the SetCC condition, and whether or not the field is
/// treated as inverted.  That is, lt = 0; ge = 0 inverted.
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) {
  switch (CC) {
  default: assert(0 && "Unknown condition!"); abort();
  case ISD::SETULT:
  case ISD::SETLT:  Inv = false;  return 0;
  case ISD::SETUGE:
  case ISD::SETGE:  Inv = true;   return 0;
  case ISD::SETUGT:
  case ISD::SETGT:  Inv = false;  return 1;
  case ISD::SETULE:
  case ISD::SETLE:  Inv = true;   return 1;
  case ISD::SETEQ:  Inv = false;  return 2;
  case ISD::SETNE:  Inv = true;   return 2;
  }
  return 0;
}

/// IndexedOpForOp - Return the indexed variant for each of the PowerPC load
/// and store immediate instructions.
static unsigned IndexedOpForOp(unsigned Opcode) {
  switch(Opcode) {
  default: assert(0 && "Unknown opcode!"); abort();
  case PPC::LBZ: return PPC::LBZX;  case PPC::STB: return PPC::STBX;
  case PPC::LHZ: return PPC::LHZX;  case PPC::STH: return PPC::STHX;
  case PPC::LHA: return PPC::LHAX;  case PPC::STW: return PPC::STWX;
  case PPC::LWZ: return PPC::LWZX;  case PPC::STFS: return PPC::STFSX;
  case PPC::LFS: return PPC::LFSX;  case PPC::STFD: return PPC::STFDX;
  case PPC::LFD: return PPC::LFDX;
  }
  return 0;
}
}

/// getGlobalBaseReg - Output the instructions required to put the
/// base address to use for accessing globals into a register.
///
unsigned ISel::getGlobalBaseReg() {
  if (!GlobalBaseInitialized) {
    // Insert the set of GlobalBaseReg into the first MBB of the function
    MachineBasicBlock &FirstMBB = BB->getParent()->front();
    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    GlobalBaseReg = MakeIntReg();
    BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
    BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
    GlobalBaseInitialized = true;
  }
  return GlobalBaseReg;
}

/// MoveCRtoGPR - Move CCReg[Idx] to the least significant bit of Result.  If
/// Inv is true, then invert the result.
void ISel::MoveCRtoGPR(unsigned CCReg, ISD::CondCode CC, unsigned Result){
  bool Inv;
  unsigned IntCR = MakeIntReg();
  unsigned Idx = getCRIdxForSetCC(CC, Inv);
  BuildMI(BB, PPC::MCRF, 1, PPC::CR7).addReg(CCReg);
  bool GPOpt =
    TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor();
  if (GPOpt)
    BuildMI(BB, PPC::MFOCRF, 1, IntCR).addReg(PPC::CR7);
  else
    BuildMI(BB, PPC::MFCR, 0, IntCR);
  if (Inv) {
    unsigned Tmp1 = MakeIntReg();
    BuildMI(BB, PPC::RLWINM, 4, Tmp1).addReg(IntCR).addImm(32-(3-Idx))
      .addImm(31).addImm(31);
    BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(1);
  } else {
    BuildMI(BB, PPC::RLWINM, 4, Result).addReg(IntCR).addImm(32-(3-Idx))
      .addImm(31).addImm(31);
  }
}

/// SelectBitfieldInsert - turn an or of two masked values into
/// the rotate left word immediate then mask insert (rlwimi) instruction.
/// Returns true on success, false if the caller still needs to select OR.
///
/// Patterns matched:
/// 1. or shl, and   5. or and, and
/// 2. or and, shl   6. or shl, shr
/// 3. or shr, and   7. or shr, shl
/// 4. or and, shr
bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
  bool IsRotate = false;
  unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
  unsigned Value;

  SDOperand Op0 = OR.getOperand(0);
  SDOperand Op1 = OR.getOperand(1);

  unsigned Op0Opc = Op0.getOpcode();
  unsigned Op1Opc = Op1.getOpcode();

  // Verify that we have the correct opcodes
  if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc)
    return false;
  if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc)
    return false;

  // Generate Mask value for Target
  if (isIntImmediate(Op0.getOperand(1), Value)) {
    switch(Op0Opc) {
    case ISD::SHL: TgtMask <<= Value; break;
    case ISD::SRL: TgtMask >>= Value; break;
    case ISD::AND: TgtMask &= Value; break;
    }
  } else {
    return false;
  }

  // Generate Mask value for Insert
  if (isIntImmediate(Op1.getOperand(1), Value)) {
    switch(Op1Opc) {
    case ISD::SHL:
      Amount = Value;
      InsMask <<= Amount;
      if (Op0Opc == ISD::SRL) IsRotate = true;
      break;
    case ISD::SRL:
      Amount = Value;
      InsMask >>= Amount;
      Amount = 32-Amount;
      if (Op0Opc == ISD::SHL) IsRotate = true;
      break;
    case ISD::AND:
      InsMask &= Value;
      break;
    }
  } else {
    return false;
  }

  unsigned Tmp3 = 0;

  // If both of the inputs are ANDs and one of them has a logical shift by
  // constant as its input, make that the inserted value so that we can combine
  // the shift into the rotate part of the rlwimi instruction
  if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) {
    if (Op1.getOperand(0).getOpcode() == ISD::SHL ||
        Op1.getOperand(0).getOpcode() == ISD::SRL) {
      if (isIntImmediate(Op1.getOperand(0).getOperand(1), Value)) {
        Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
          Value : 32 - Value;
        Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
      }
    } else if (Op0.getOperand(0).getOpcode() == ISD::SHL ||
               Op0.getOperand(0).getOpcode() == ISD::SRL) {
      if (isIntImmediate(Op0.getOperand(0).getOperand(1), Value)) {
        std::swap(Op0, Op1);
        std::swap(TgtMask, InsMask);
        Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
          Value : 32 - Value;
        Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
      }
    }
  }

  // Verify that the Target mask and Insert mask together form a full word mask
  // and that the Insert mask is a run of set bits (which implies both are runs
  // of set bits).  Given that, Select the arguments and generate the rlwimi
  // instruction.
  unsigned MB, ME;
  if (((TgtMask & InsMask) == 0) && isRunOfOnes(InsMask, MB, ME)) {
    unsigned Tmp1, Tmp2;
    bool fullMask = (TgtMask ^ InsMask) == 0xFFFFFFFF;
    // Check for rotlwi / rotrwi here, a special case of bitfield insert
    // where both bitfield halves are sourced from the same value.
    if (IsRotate && fullMask &&
        OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) {
      Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
      BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount)
        .addImm(0).addImm(31);
      return true;
    }
    if (Op0Opc == ISD::AND && fullMask)
      Tmp1 = SelectExpr(Op0.getOperand(0));
    else
      Tmp1 = SelectExpr(Op0);
    Tmp2 = Tmp3 ? Tmp3 : SelectExpr(Op1.getOperand(0));
    BuildMI(BB, PPC::RLWIMI, 5, Result).addReg(Tmp1).addReg(Tmp2)
      .addImm(Amount).addImm(MB).addImm(ME);
    return true;
  }
  return false;
}

/// FoldIfWideZeroExtend - 32 bit PowerPC implicit masks shift amounts to the
/// low six bits.  If the shift amount is an ISD::AND node with a mask that is
/// wider than the implicit mask, then we can get rid of the AND and let the
/// shift do the mask.
unsigned ISel::FoldIfWideZeroExtend(SDOperand N) {
  unsigned C;
  if (isOpcWithIntImmediate(N, ISD::AND, C) && isMask_32(C) && C > 63)
    return SelectExpr(N.getOperand(0));
  else
    return SelectExpr(N);
}

unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
  unsigned Result, Tmp1, Tmp2;
  bool AlreadySelected = false;

  // Allocate a condition register for this expression
  Result = RegMap->createVirtualRegister(PPC::CRRCRegisterClass);

  // Use U to determine whether the SETCC immediate range is signed or not.
  bool U = ISD::isUnsignedIntSetCC(CC);
  if (isIntImmediate(RHS, Tmp2) && 
      ((U && isUInt16(Tmp2)) || (!U && isInt16(Tmp2)))) {
    Tmp2 = Lo16(Tmp2);
    // For comparisons against zero, we can implicity set CR0 if a recording
    // variant (e.g. 'or.' instead of 'or') of the instruction that defines
    // operand zero of the SetCC node is available.
    if (Tmp2 == 0 &&
        NodeHasRecordingVariant(LHS.getOpcode()) && LHS.Val->hasOneUse()) {
      RecordSuccess = false;
      Tmp1 = SelectExpr(LHS, true);
      if (RecordSuccess) {
        ++Recorded;
        BuildMI(BB, PPC::MCRF, 1, Result).addReg(PPC::CR0);
        return Result;
      }
      AlreadySelected = true;
    }
    // If we could not implicitly set CR0, then emit a compare immediate
    // instead.
    if (!AlreadySelected) Tmp1 = SelectExpr(LHS);
    if (U)
      BuildMI(BB, PPC::CMPLWI, 2, Result).addReg(Tmp1).addImm(Tmp2);
    else
      BuildMI(BB, PPC::CMPWI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
  } else {
    unsigned CompareOpc;
    if (MVT::isInteger(LHS.getValueType()))
      CompareOpc = U ? PPC::CMPLW : PPC::CMPW;
    else if (LHS.getValueType() == MVT::f32)
      CompareOpc = PPC::FCMPUS;
    else
      CompareOpc = PPC::FCMPUD;
    Tmp1 = SelectExpr(LHS);
    Tmp2 = SelectExpr(RHS);
    BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
  }
  return Result;
}

/// Check to see if the load is a constant offset from a base register.
unsigned ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
{
  unsigned imm = 0, opcode = N.getOpcode();
  if (N.getOpcode() == ISD::ADD) {
    bool isFrame = N.getOperand(0).getOpcode() == ISD::FrameIndex;
    if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) {
      offset = Lo16(imm);
      if (isFrame) {
        ++FrameOff;
        Reg = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
        return 1;
      } else {
        Reg = SelectExpr(N.getOperand(0));
        return 0;
      }
    } else {
      Reg = SelectExpr(N.getOperand(0));
      offset = SelectExpr(N.getOperand(1));
      return 2;
    }
  }
  // Now check if we're dealing with a global, and whether or not we should emit
  // an optimized load or store for statics.
  if(GlobalAddressSDNode *GN = dyn_cast<GlobalAddressSDNode>(N)) {
    GlobalValue *GV = GN->getGlobal();
    if (!GV->hasWeakLinkage() && !GV->isExternal()) {
      unsigned GlobalHi = MakeIntReg();
      if (PICEnabled)
        BuildMI(BB, PPC::ADDIS, 2, GlobalHi).addReg(getGlobalBaseReg())
          .addGlobalAddress(GV);
      else
        BuildMI(BB, PPC::LIS, 1, GlobalHi).addGlobalAddress(GV);
      Reg = GlobalHi;
      offset = 0;
      return 3;
    }
  }
  Reg = SelectExpr(N);
  offset = 0;
  return 0;
}

void ISel::SelectBranchCC(SDOperand N)
{
  MachineBasicBlock *Dest =
    cast<BasicBlockSDNode>(N.getOperand(4))->getBasicBlock();

  Select(N.getOperand(0));  //chain
  ISD::CondCode CC = cast<CondCodeSDNode>(N.getOperand(1))->get();
  unsigned CCReg = SelectCC(N.getOperand(2), N.getOperand(3), CC);
  unsigned Opc = getBCCForSetCC(CC);

  // If this is a two way branch, then grab the fallthrough basic block argument
  // and build a PowerPC branch pseudo-op, suitable for long branch conversion
  // if necessary by the branch selection pass.  Otherwise, emit a standard
  // conditional branch.
  if (N.getOpcode() == ISD::BRTWOWAY_CC) {
    MachineBasicBlock *Fallthrough =
      cast<BasicBlockSDNode>(N.getOperand(5))->getBasicBlock();
    BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
      .addMBB(Dest).addMBB(Fallthrough);
    BuildMI(BB, PPC::B, 1).addMBB(Fallthrough);
  } else {
    // Iterate to the next basic block
    ilist<MachineBasicBlock>::iterator It = BB;
    ++It;

    // If the fallthrough path is off the end of the function, which would be
    // undefined behavior, set it to be the same as the current block because
    // we have nothing better to set it to, and leaving it alone will cause the
    // PowerPC Branch Selection pass to crash.
    if (It == BB->getParent()->end()) It = Dest;
    BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
      .addMBB(Dest).addMBB(It);
  }
  return;
}

// SelectIntImmediateExpr - Choose code for opcodes with immediate value.
bool ISel::SelectIntImmediateExpr(SDOperand N, unsigned Result,
                                  unsigned OCHi, unsigned OCLo,
                                  bool IsArithmetic, bool Negate) {
  // check constant
  ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1));
  // exit if not a constant
  if (!CN) return false;
  // extract immediate
  unsigned C = (unsigned)CN->getValue();
  // negate if required (ISD::SUB)
  if (Negate) C = -C;
  // get the hi and lo portions of constant
  unsigned Hi = IsArithmetic ? HA16(C) : Hi16(C);
  unsigned Lo = Lo16(C);
  // assume no intermediate result from lo instruction (same as final result)
  unsigned Tmp = Result;
  // check if two instructions are needed
  if (Hi && Lo) {
    // exit if usage indicates it would be better to load immediate into a 
    // register
    if (CN->use_size() > 2) return false;
    // need intermediate result for two instructions
    Tmp = MakeIntReg();
  }
  // get first operand
  unsigned Opr0 = SelectExpr(N.getOperand(0));
  // is a lo instruction needed
  if (Lo) {
    // generate instruction for lo portion
    BuildMI(BB, OCLo, 2, Tmp).addReg(Opr0).addImm(Lo);
    // need to switch out first operand for hi instruction
    Opr0 = Tmp;
  }
  // is a hi instruction needed
  if (Hi) {
    // generate instruction for hi portion
    BuildMI(BB, OCHi, 2, Result).addReg(Opr0).addImm(Hi);
  }
  return true;
}

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

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

  if (Node->getOpcode() == ISD::CopyFromReg) {
    unsigned Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
    // Just use the specified register as our input.
    if (MRegisterInfo::isVirtualRegister(Reg) || Reg == PPC::R1)
      return Reg;
  }

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

  switch (N.getOpcode()) {
  default:
    Reg = Result = (N.getValueType() != MVT::Other) ?
                            MakeReg(N.getValueType()) : 1;
    break;
  case ISD::AssertSext:
  case ISD::AssertZext:
    // Don't allocate a vreg for these nodes.
    return Reg = SelectExpr(N.getOperand(0));
  case ISD::TAILCALL:
  case ISD::CALL:
    // 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 = 1;  // 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)] = 1;
    }
    break;
  case ISD::ADD_PARTS:
  case ISD::SUB_PARTS:
    Result = MakeReg(Node->getValueType(0));
    ExprMap[N.getValue(0)] = Result;
    for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i)
      ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
    break;
  }

  switch (opcode) {
  default:
    Node->dump(); std::cerr << '\n';
    assert(0 && "Node not handled!\n");
  case PPCISD::FSEL:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    Tmp3 = SelectExpr(N.getOperand(2));

    // Extend the comparison to 64-bits if needed.
    if (N.getOperand(0).getValueType() == MVT::f32) {
      unsigned Tmp1New = MakeReg(MVT::f64);
      BuildMI(BB, PPC::FMRSD, 1, Tmp1New).addReg(Tmp1);
      Tmp1 = Tmp1New;
    }
      
    Opc = N.Val->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD;
    BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
    return Result;
  case PPCISD::FCFID:
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp1);
    return Result;
  case PPCISD::FCTIDZ:
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, PPC::FCTIDZ, 1, Result).addReg(Tmp1);
    return Result;
  case PPCISD::FCTIWZ:
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1);
    return Result;
  case ISD::UNDEF:
    if (Node->getValueType(0) == MVT::i32)
      BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result);
    else if (Node->getValueType(0) == MVT::f32)
      BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Result);
    else
      BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Result);
    return Result;
  case ISD::DYNAMIC_STACKALLOC:
    // Generate both result values.  FIXME: Need a better commment here?
    if (Result != 1)
      ExprMap[N.getValue(1)] = 1;
    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));
    Tmp1 = SelectExpr(N.getOperand(1));
    // Subtract size from stack pointer, thereby allocating some space.
    BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1);
    // Put a pointer to the space into the result register by copying the SP
    BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R1).addReg(PPC::R1);
    return Result;

  case ISD::ConstantPool:
    Tmp1 = BB->getParent()->getConstantPool()->
               getConstantPoolIndex(cast<ConstantPoolSDNode>(N)->get());
    Tmp2 = MakeIntReg();
    if (PICEnabled)
      BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg())
        .addConstantPoolIndex(Tmp1);
    else
      BuildMI(BB, PPC::LIS, 1, Tmp2).addConstantPoolIndex(Tmp1);
    BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1);
    return Result;

  case ISD::FrameIndex:
    Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
    addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false);
    return Result;

  case ISD::GlobalAddress: {
    GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
    Tmp1 = MakeIntReg();
    if (PICEnabled)
      BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg())
        .addGlobalAddress(GV);
    else
      BuildMI(BB, PPC::LIS, 1, Tmp1).addGlobalAddress(GV);
    if (GV->hasWeakLinkage() || GV->isExternal()) {
      BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
    } else {
      BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV);
    }
    return Result;
  }

  case ISD::LOAD:
  case ISD::EXTLOAD:
  case ISD::ZEXTLOAD:
  case ISD::SEXTLOAD: {
    MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ?
      Node->getValueType(0) : cast<VTSDNode>(Node->getOperand(3))->getVT();
    bool sext = (ISD::SEXTLOAD == opcode);

    // Make sure we generate both values.
    if (Result != 1)
      ExprMap[N.getValue(1)] = 1;   // 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);

    switch (TypeBeingLoaded) {
    default: Node->dump(); assert(0 && "Cannot load this type!");
    case MVT::i1:  Opc = PPC::LBZ; break;
    case MVT::i8:  Opc = PPC::LBZ; break;
    case MVT::i16: Opc = sext ? PPC::LHA : PPC::LHZ; break;
    case MVT::i32: Opc = PPC::LWZ; break;
    case MVT::f32: Opc = PPC::LFS; break;
    case MVT::f64: Opc = PPC::LFD; break;
    }

    if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
      Tmp1 = MakeIntReg();
      unsigned CPI = BB->getParent()->getConstantPool()->
        getConstantPoolIndex(CP->get());
      if (PICEnabled)
        BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg())
          .addConstantPoolIndex(CPI);
      else
        BuildMI(BB, PPC::LIS, 1, Tmp1).addConstantPoolIndex(CPI);
      BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1);
    } else if (Address.getOpcode() == ISD::FrameIndex) {
      Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
      addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1);
    } else {
      int offset;
      switch(SelectAddr(Address, Tmp1, offset)) {
      default: assert(0 && "Unhandled return value from SelectAddr");
      case 0:   // imm offset, no frame, no index
        BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
        break;
      case 1:   // imm offset + frame index
        addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1, offset);
        break;
      case 2:   // base+index addressing
        Opc = IndexedOpForOp(Opc);
        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
        break;
      case 3: {
        GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Address);
        GlobalValue *GV = GN->getGlobal();
        BuildMI(BB, Opc, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
      }
      }
    }
    return Result;
  }

  case ISD::TAILCALL:
  case ISD::CALL: {
    unsigned GPR_idx = 0, FPR_idx = 0;
    static const unsigned GPR[] = {
      PPC::R3, PPC::R4, PPC::R5, PPC::R6,
      PPC::R7, PPC::R8, PPC::R9, PPC::R10,
    };
    static const unsigned FPR[] = {
      PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
      PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
    };

    // Lower the chain for this call.
    Select(N.getOperand(0));
    ExprMap[N.getValue(Node->getNumValues()-1)] = 1;

    MachineInstr *CallMI;
    // Emit the correct call instruction based on the type of symbol called.
    if (GlobalAddressSDNode *GASD =
        dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
      CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
                                                           true);
    } else if (ExternalSymbolSDNode *ESSDN =
               dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
      CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
                                                            true);
    } else {
      Tmp1 = SelectExpr(N.getOperand(1));
      BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1);
      BuildMI(BB, PPC::OR4, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
      CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
        .addReg(PPC::R12);
    }

    // Load the register args to virtual regs
    std::vector<unsigned> ArgVR;
    for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
      ArgVR.push_back(SelectExpr(N.getOperand(i)));

    // Copy the virtual registers into the appropriate argument register
    for(int i = 0, e = ArgVR.size(); i < e; ++i) {
      switch(N.getOperand(i+2).getValueType()) {
      default: Node->dump(); assert(0 && "Unknown value type for call");
      case MVT::i32:
        assert(GPR_idx < 8 && "Too many int args");
        if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
          BuildMI(BB, PPC::OR4,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
          CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
        }
        ++GPR_idx;
        break;
      case MVT::f64:
      case MVT::f32:
        assert(FPR_idx < 13 && "Too many fp args");
        BuildMI(BB, N.getOperand(i+2).getValueType() == MVT::f32 ? PPC::FMRS :
                PPC::FMRD, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
        CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
        ++FPR_idx;
        break;
      }
    }

    // Put the call instruction in the correct place in the MachineBasicBlock
    BB->push_back(CallMI);

    switch (Node->getValueType(0)) {
    default: assert(0 && "Unknown value type for call result!");
    case MVT::Other: return 1;
    case MVT::i32:
      if (Node->getValueType(1) == MVT::i32) {
        BuildMI(BB, PPC::OR4, 2, Result+1).addReg(PPC::R3).addReg(PPC::R3);
        BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R4).addReg(PPC::R4);
      } else {
        BuildMI(BB, PPC::OR4, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
      }
      break;
    case MVT::f32:
      BuildMI(BB, PPC::FMRS, 1, Result).addReg(PPC::F1);
      break;
    case MVT::f64:
      BuildMI(BB, PPC::FMRD, 1, Result).addReg(PPC::F1);
      break;
    }
    return Result+N.ResNo;
  }

  case ISD::SIGN_EXTEND_INREG:
    Tmp1 = SelectExpr(N.getOperand(0));
    switch(cast<VTSDNode>(Node->getOperand(1))->getVT()) {
    default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break;
    case MVT::i16:
      BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
      break;
    case MVT::i8:
      BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
      break;
    }
    return Result;

  case ISD::CopyFromReg:
    DestType = N.getValue(0).getValueType();
    if (Result == 1)
      Result = ExprMap[N.getValue(0)] = MakeReg(DestType);
    else 
      ExprMap[N.getValue(1)] = 1;
    Tmp1 = dyn_cast<RegisterSDNode>(Node->getOperand(1))->getReg();
    if (MVT::isInteger(DestType))
      BuildMI(BB, PPC::OR4, 2, Result).addReg(Tmp1).addReg(Tmp1);
    else if (DestType == MVT::f32)
      BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1);
    else
      BuildMI(BB, PPC::FMRD, 1, Result).addReg(Tmp1);
    return Result;

  case ISD::SHL:
    if (isIntImmediate(N.getOperand(1), Tmp2)) {
      unsigned SH, MB, ME;
      if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) &&
          isRotateAndMask(ISD::SHL, Tmp2, Tmp3, true, SH, MB, ME)) {
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH)
          .addImm(MB).addImm(ME);
        return Result;
      }
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 &= 0x1F;
      BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Tmp2).addImm(0)
        .addImm(31-Tmp2);
    } else {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
      BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::SRL:
    if (isIntImmediate(N.getOperand(1), Tmp2)) {
      unsigned SH, MB, ME;
      if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) &&
          isRotateAndMask(ISD::SRL, Tmp2, Tmp3, true, SH, MB, ME)) {
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH & 0x1F)
          .addImm(MB).addImm(ME);
        return Result;
      }
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 &= 0x1F;
      BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm((32-Tmp2) & 0x1F)
        .addImm(Tmp2).addImm(31);
    } else {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
      BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::SRA:
    if (isIntImmediate(N.getOperand(1), Tmp2)) {
      Tmp1 = SelectExpr(N.getOperand(0));
      BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2 & 0x1F);
    } else {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
      BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::CTLZ:
    Tmp1 = SelectExpr(N.getOperand(0));
    BuildMI(BB, PPC::CNTLZW, 1, Result).addReg(Tmp1);
    return Result;

  case ISD::ADD:
    if (SelectIntImmediateExpr(N, Result, PPC::ADDIS, PPC::ADDI, true))
      return Result;
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, PPC::ADD4, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
    
  case ISD::FADD:
    if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL &&
        N.getOperand(0).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(1));
      Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
      return Result;
    }
    if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL &&
        N.getOperand(1).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(0));
      Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
      return Result;
    }
    Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS;
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
 
  case ISD::AND:
    if (isIntImmediate(N.getOperand(1), Tmp2)) {
      if (isShiftedMask_32(Tmp2) || isShiftedMask_32(~Tmp2)) {
        unsigned SH, MB, ME;
        Opc = Recording ? PPC::RLWINMo : PPC::RLWINM;
        unsigned OprOpc;
        if (isOprShiftImm(N.getOperand(0), OprOpc, Tmp3) &&
            isRotateAndMask(OprOpc, Tmp3, Tmp2, false, SH, MB, ME)) {
          Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        } else {
          Tmp1 = SelectExpr(N.getOperand(0));
          isRunOfOnes(Tmp2, MB, ME);
          SH = 0;
        }
        BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(SH)
          .addImm(MB).addImm(ME);
        RecordSuccess = true;
        return Result;
      } else if (isUInt16(Tmp2)) {
        Tmp2 = Lo16(Tmp2);
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, PPC::ANDIo, 2, Result).addReg(Tmp1).addImm(Tmp2);
        RecordSuccess = true;
        return Result;
      } else if (isUInt16(Tmp2)) {
        Tmp2 = Hi16(Tmp2);
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2);
        RecordSuccess = true;
       return Result;
      }
    }
    if (isOprNot(N.getOperand(1))) {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1).getOperand(0));
      BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp1).addReg(Tmp2);
      RecordSuccess = false;
      return Result;
    }
    if (isOprNot(N.getOperand(0))) {
      Tmp1 = SelectExpr(N.getOperand(1));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(0));
      BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp1).addReg(Tmp2);
      RecordSuccess = false;
      return Result;
    }
    // emit a regular and
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    Opc = Recording ? PPC::ANDo : PPC::AND;
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    RecordSuccess = true;
    return Result;

  case ISD::OR:
    if (SelectBitfieldInsert(N, Result))
      return Result;
    if (SelectIntImmediateExpr(N, Result, PPC::ORIS, PPC::ORI))
      return Result;
    if (isOprNot(N.getOperand(1))) {
      Tmp1 = SelectExpr(N.getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1).getOperand(0));
      BuildMI(BB, PPC::ORC, 2, Result).addReg(Tmp1).addReg(Tmp2);
      RecordSuccess = false;
      return Result;
    }
    if (isOprNot(N.getOperand(0))) {
      Tmp1 = SelectExpr(N.getOperand(1));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(0));
      BuildMI(BB, PPC::ORC, 2, Result).addReg(Tmp1).addReg(Tmp2);
      RecordSuccess = false;
      return Result;
    }
    // emit regular or
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    Opc = Recording ? PPC::ORo : PPC::OR4;
    RecordSuccess = true;
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;

  case ISD::XOR: {
    // Check for EQV: xor, (xor a, -1), b
    if (isOprNot(N.getOperand(0))) {
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1));
      BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
      return Result;
    }
    // Check for NOT, NOR, EQV, and NAND: xor (copy, or, xor, and), -1
    if (isOprNot(N)) {
      switch(N.getOperand(0).getOpcode()) {
      case ISD::OR:
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
        BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
        break;
      case ISD::AND:
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
        BuildMI(BB, PPC::NAND, 2, Result).addReg(Tmp1).addReg(Tmp2);
        break;
      case ISD::XOR:
        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
        BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
        break;
      default:
        Tmp1 = SelectExpr(N.getOperand(0));
        BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp1);
        break;
      }
      return Result;
    }
    if (SelectIntImmediateExpr(N, Result, PPC::XORIS, PPC::XORI))
      return Result;
    // emit regular xor
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
  }

  case ISD::FSUB:
    if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::FMUL &&
        N.getOperand(0).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(1));
      Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
      return Result;
    }
    if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::FMUL &&
        N.getOperand(1).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(0));
      Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
      return Result;
    }
    Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS;
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
  case ISD::SUB:
    if (isIntImmediate(N.getOperand(0), Tmp1) && isInt16(Tmp1)) {
      Tmp1 = Lo16(Tmp1);
      Tmp2 = SelectExpr(N.getOperand(1));
      if (0 == Tmp1)
        BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp2);
      else
        BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1);
      return Result;
    }
    if (SelectIntImmediateExpr(N, Result, PPC::ADDIS, PPC::ADDI, true, true))
        return Result;
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
    return Result;

  case ISD::FMUL:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    BuildMI(BB, DestType == MVT::f32 ? PPC::FMULS : PPC::FMUL, 2, 
            Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
  
  case ISD::MUL:
    Tmp1 = SelectExpr(N.getOperand(0));
    if (isIntImmediate(N.getOperand(1), Tmp2) && isInt16(Tmp2)) {
      Tmp2 = Lo16(Tmp2);
      BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
    } else {
      Tmp2 = SelectExpr(N.getOperand(1));
      BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
    }
    return Result;

  case ISD::MULHS:
  case ISD::MULHU:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    Opc = (ISD::MULHU == opcode) ? PPC::MULHWU : PPC::MULHW;
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;

  case ISD::FDIV:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    switch (DestType) {
    default: assert(0 && "Unknown type to ISD::FDIV"); break;
    case MVT::f32: Opc = PPC::FDIVS; break;
    case MVT::f64: Opc = PPC::FDIV; break;
    }
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;
    
  case ISD::SDIV:
    if (isIntImmediate(N.getOperand(1), Tmp3)) {
      if ((signed)Tmp3 > 0 && isPowerOf2_32(Tmp3)) {
        Tmp3 = Log2_32(Tmp3);
        Tmp1 = MakeIntReg();
        Tmp2 = SelectExpr(N.getOperand(0));
        BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
        BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1);
        return Result;
      } else if ((signed)Tmp3 < 0 && isPowerOf2_32(-Tmp3)) {
        Tmp3 = Log2_32(-Tmp3);
        Tmp2 = SelectExpr(N.getOperand(0));
        Tmp1 = MakeIntReg();
        unsigned Tmp4 = MakeIntReg();
        BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
        BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1);
        BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4);
        return Result;
      }
    }
    // fall thru
  case ISD::UDIV:
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break;
    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
    return Result;

  case ISD::ADD_PARTS:
  case ISD::SUB_PARTS: {
    assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 &&
           "Not an i64 add/sub!");
    unsigned Tmp4 = 0;
    Tmp1 = SelectExpr(N.getOperand(0));
    Tmp2 = SelectExpr(N.getOperand(1));
    
    if (N.getOpcode() == ISD::ADD_PARTS) {
      bool ME = false, ZE = false;
      if (isIntImmediate(N.getOperand(3), Tmp3)) {
        ME = (signed)Tmp3 == -1;
        ZE = Tmp3 == 0;
      }
      
      if (!ZE && !ME)
        Tmp4 = SelectExpr(N.getOperand(3));

      if (isIntImmediate(N.getOperand(2), Tmp3) &&
          ((signed)Tmp3 >= -32768 || (signed)Tmp3 < 32768)) {
        // Codegen the low 32 bits of the add.  Interestingly, there is no
        // shifted form of add immediate carrying.
        BuildMI(BB, PPC::ADDIC, 2, Result).addReg(Tmp1).addSImm(Tmp3);
      } else {
        Tmp3 = SelectExpr(N.getOperand(2));
        BuildMI(BB, PPC::ADDC, 2, Result).addReg(Tmp1).addReg(Tmp3);
      }
      
      // Codegen the high 32 bits, adding zero, minus one, or the full value
      // along with the carry flag produced by addc/addic to tmp2.
      if (ZE) {
        BuildMI(BB, PPC::ADDZE, 1, Result+1).addReg(Tmp2);
      } else if (ME) {
        BuildMI(BB, PPC::ADDME, 1, Result+1).addReg(Tmp2);
      } else {
        BuildMI(BB, PPC::ADDE, 2, Result+1).addReg(Tmp2).addReg(Tmp4);
      }
    } else {
      Tmp3 = SelectExpr(N.getOperand(2));
      Tmp4 = SelectExpr(N.getOperand(3));
      BuildMI(BB, PPC::SUBFC, 2, Result).addReg(Tmp3).addReg(Tmp1);
      BuildMI(BB, PPC::SUBFE, 2, Result+1).addReg(Tmp4).addReg(Tmp2);
    }
    return Result+N.ResNo;
  }

  case ISD::SETCC: {
    ISD::CondCode CC = cast<CondCodeSDNode>(Node->getOperand(2))->get();
    if (isIntImmediate(Node->getOperand(1), Tmp3)) {
      // We can codegen setcc op, imm very efficiently compared to a brcond.
      // Check for those cases here.
      // setcc op, 0
      if (Tmp3 == 0) {
        Tmp1 = SelectExpr(Node->getOperand(0));
        switch (CC) {
        default: Node->dump(); assert(0 && "Unhandled SetCC condition");abort();
        case ISD::SETEQ:
          Tmp2 = MakeIntReg();
          BuildMI(BB, PPC::CNTLZW, 1, Tmp2).addReg(Tmp1);
          BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp2).addImm(27)
            .addImm(5).addImm(31);
          break;
        case ISD::SETNE:
          Tmp2 = MakeIntReg();
          BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(-1);
          BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp2).addReg(Tmp1);
          break;
        case ISD::SETLT:
          BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(1)
            .addImm(31).addImm(31);
          break;
        case ISD::SETGT:
          Tmp2 = MakeIntReg();
          Tmp3 = MakeIntReg();
          BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1);
          BuildMI(BB, PPC::ANDC, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
          BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
            .addImm(31).addImm(31);
          break;
        }
        return Result;
      } else if (Tmp3 == ~0U) {        // setcc op, -1
        Tmp1 = SelectExpr(Node->getOperand(0));
        switch (CC) {
        default: assert(0 && "Unhandled SetCC condition"); abort();
        case ISD::SETEQ:
          Tmp2 = MakeIntReg();
          Tmp3 = MakeIntReg();
          BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(1);
          BuildMI(BB, PPC::LI, 1, Tmp3).addSImm(0);
          BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp3);
          break;
        case ISD::SETNE:
          Tmp2 = MakeIntReg();
          Tmp3 = MakeIntReg();
          BuildMI(BB, PPC::NOR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
          BuildMI(BB, PPC::ADDIC, 2, Tmp3).addReg(Tmp2).addSImm(-1);
          BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp3).addReg(Tmp2);
          break;
        case ISD::SETLT:
          Tmp2 = MakeIntReg();
          Tmp3 = MakeIntReg();
          BuildMI(BB, PPC::ADDI, 2, Tmp2).addReg(Tmp1).addSImm(1);
          BuildMI(BB, PPC::AND, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
          BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
            .addImm(31).addImm(31);
          break;
        case ISD::SETGT:
          Tmp2 = MakeIntReg();
          BuildMI(BB, PPC::RLWINM, 4, Tmp2).addReg(Tmp1).addImm(1)
            .addImm(31).addImm(31);
          BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp2).addImm(1);
          break;
        }
        return Result;
      }
    }

    unsigned CCReg = SelectCC(N.getOperand(0), N.getOperand(1), CC);
    MoveCRtoGPR(CCReg, CC, Result);
    return Result;
  }
    
  case ISD::SELECT_CC: {
    ISD::CondCode CC = cast<CondCodeSDNode>(N.getOperand(4))->get();

    // handle the setcc cases here.  select_cc lhs, 0, 1, 0, cc
    ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N.getOperand(1));
    ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N.getOperand(2));
    ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N.getOperand(3));
    if (N1C && N2C && N3C && N1C->isNullValue() && N3C->isNullValue() &&
        N2C->getValue() == 1ULL && CC == ISD::SETNE) {
      Tmp1 = SelectExpr(Node->getOperand(0));
      Tmp2 = MakeIntReg();
      BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(-1);
      BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp2).addReg(Tmp1);
      return Result;
    }
    
    // If the False value only has one use, we can generate better code by
    // selecting it in the fallthrough basic block rather than here, which
    // increases register pressure.
    unsigned TrueValue = SelectExpr(N.getOperand(2));
    unsigned FalseValue;

    // If the false value is simple enough, evaluate it inline in the false
    // block.
    if (N.getOperand(3).Val->hasOneUse() &&
        (isa<ConstantSDNode>(N.getOperand(3)) ||
         isa<GlobalAddressSDNode>(N.getOperand(3))))
      FalseValue = 0;
    else
      FalseValue = SelectExpr(N.getOperand(3));
    unsigned CCReg = SelectCC(N.getOperand(0), N.getOperand(1), CC);
    Opc = getBCCForSetCC(CC);
    
    // Create an iterator with which to insert the MBB for copying the false
    // value and the MBB to hold the PHI instruction for this SetCC.
    MachineBasicBlock *thisMBB = BB;
    const BasicBlock *LLVM_BB = BB->getBasicBlock();
    ilist<MachineBasicBlock>::iterator It = BB;
    ++It;

    //  thisMBB:
    //  ...
    //   TrueVal = ...
    //   cmpTY ccX, r1, r2
    //   bCC copy1MBB
    //   fallthrough --> copy0MBB
    MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
    MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
    BuildMI(BB, Opc, 2).addReg(CCReg).addMBB(sinkMBB);
    MachineFunction *F = BB->getParent();
    F->getBasicBlockList().insert(It, copy0MBB);
    F->getBasicBlockList().insert(It, sinkMBB);
    // Update machine-CFG edges
    BB->addSuccessor(copy0MBB);
    BB->addSuccessor(sinkMBB);

    //  copy0MBB:
    //   %FalseValue = ...
    //   # fallthrough to sinkMBB
    BB = copy0MBB;

    // If the false value is simple enough, evaluate it here, to avoid it being
    // evaluated on the true edge.
    if (FalseValue == 0)
      FalseValue = SelectExpr(N.getOperand(3));

    // Update machine-CFG edges
    BB->addSuccessor(sinkMBB);

    //  sinkMBB:
    //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
    //  ...
    BB = sinkMBB;
    BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
      .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
    return Result;
  }

  case ISD::Constant: {
    assert(N.getValueType() == MVT::i32 &&
           "Only i32 constants are legal on this target!");
    unsigned v = (unsigned)cast<ConstantSDNode>(N)->getValue();
    if (isInt16(v)) {
      BuildMI(BB, PPC::LI, 1, Result).addSImm(Lo16(v));
    } else {
      unsigned Hi = Hi16(v);
      unsigned Lo = Lo16(v);
      if (Lo) {
        Tmp1 = MakeIntReg();
        BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(Hi);
        BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(Lo);
      } else {
        BuildMI(BB, PPC::LIS, 1, Result).addSImm(Hi);
      }
    }
    return Result;
  }

  case ISD::FNEG:
    if (!NoExcessFPPrecision &&
        ISD::FADD == N.getOperand(0).getOpcode() &&
        N.getOperand(0).Val->hasOneUse() &&
        ISD::FMUL == N.getOperand(0).getOperand(0).getOpcode() &&
        N.getOperand(0).getOperand(0).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
      Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
    } else if (!NoExcessFPPrecision &&
        ISD::FADD == N.getOperand(0).getOpcode() &&
        N.getOperand(0).Val->hasOneUse() &&
        ISD::FMUL == N.getOperand(0).getOperand(1).getOpcode() &&
        N.getOperand(0).getOperand(1).Val->hasOneUse()) {
      ++FusedFP; // Statistic
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
      Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(1));
      Tmp3 = SelectExpr(N.getOperand(0).getOperand(0));
      Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
    } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
      if (N.getOperand(0).getValueType() == MVT::f32)
        BuildMI(BB, PPC::FNABSS, 1, Result).addReg(Tmp1);
      else
        BuildMI(BB, PPC::FNABSD, 1, Result).addReg(Tmp1);

    } else {
      Tmp1 = SelectExpr(N.getOperand(0));
      if (N.getOperand(0).getValueType() == MVT::f32)
        BuildMI(BB, PPC::FNEGS, 1, Result).addReg(Tmp1);
      else
        BuildMI(BB, PPC::FNEGD, 1, Result).addReg(Tmp1);
    }
    return Result;

  case ISD::FABS:
    Tmp1 = SelectExpr(N.getOperand(0));
    if (N.getOperand(0).getValueType() == MVT::f32)
      BuildMI(BB, PPC::FABSS, 1, Result).addReg(Tmp1);
    else
      BuildMI(BB, PPC::FABSD, 1, Result).addReg(Tmp1);
    return Result;

  case ISD::FSQRT:
    Tmp1 = SelectExpr(N.getOperand(0));
    Opc = DestType == MVT::f64 ? PPC::FSQRT : PPC::FSQRTS;
    BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
    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, PPC::FRSP, 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, PPC::FMRSD, 1, Result).addReg(Tmp1);
    return Result;
  }
  return 0;
}

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

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

  SDNode *Node = N.Val;

  switch (Node->getOpcode()) {
  default:
    Node->dump(); std::cerr << "\n";
    assert(0 && "Node not handled yet!");
  case ISD::EntryToken: return;  // Noop
  case ISD::TokenFactor:
    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
      Select(Node->getOperand(i));
    return;
  case ISD::CALLSEQ_START:
  case ISD::CALLSEQ_END:
    Select(N.getOperand(0));
    Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
    Opc = N.getOpcode() == ISD::CALLSEQ_START ? PPC::ADJCALLSTACKDOWN :
      PPC::ADJCALLSTACKUP;
    BuildMI(BB, Opc, 1).addImm(Tmp1);
    return;
  case ISD::BR: {
    MachineBasicBlock *Dest =
      cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
    Select(N.getOperand(0));
    BuildMI(BB, PPC::B, 1).addMBB(Dest);
    return;
  }
  case ISD::BR_CC:
  case ISD::BRTWOWAY_CC:
    SelectBranchCC(N);
    return;
  case ISD::CopyToReg:
    Select(N.getOperand(0));
    Tmp1 = SelectExpr(N.getOperand(2));
    Tmp2 = cast<RegisterSDNode>(N.getOperand(1))->getReg();

    if (Tmp1 != Tmp2) {
      if (N.getOperand(2).getValueType() == MVT::f64)
        BuildMI(BB, PPC::FMRD, 1, Tmp2).addReg(Tmp1);
      else if (N.getOperand(2).getValueType() == MVT::f32)
        BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1);
      else
        BuildMI(BB, PPC::OR4, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
    }
    return;
  case ISD::ImplicitDef:
    Select(N.getOperand(0));
    Tmp1 = cast<RegisterSDNode>(N.getOperand(1))->getReg();
    if (N.getOperand(1).getValueType() == MVT::i32)
      BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Tmp1);
    else if (N.getOperand(1).getValueType() == MVT::f32)
      BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Tmp1);
    else
      BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Tmp1);
    return;
  case ISD::RET:
    switch (N.getNumOperands()) {
    default:
      assert(0 && "Unknown return instruction!");
    case 3:
      assert(N.getOperand(1).getValueType() == MVT::i32 &&
             N.getOperand(2).getValueType() == MVT::i32 &&
             "Unknown two-register value!");
      Select(N.getOperand(0));
      Tmp1 = SelectExpr(N.getOperand(1));
      Tmp2 = SelectExpr(N.getOperand(2));
      BuildMI(BB, PPC::OR4, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2);
      BuildMI(BB, PPC::OR4, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1);
      break;
    case 2:
      Select(N.getOperand(0));
      Tmp1 = SelectExpr(N.getOperand(1));
      switch (N.getOperand(1).getValueType()) {
        default:
          assert(0 && "Unknown return type!");
        case MVT::f64:
          BuildMI(BB, PPC::FMRD, 1, PPC::F1).addReg(Tmp1);
          break;
        case MVT::f32:
          BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1);
          break;
        case MVT::i32:
          BuildMI(BB, PPC::OR4, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
          break;
      }
    case 1:
      Select(N.getOperand(0));
      break;
    }
    BuildMI(BB, PPC::BLR, 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::i32: Opc = PPC::STW; break;
      case MVT::f64: Opc = PPC::STFD; break;
      case MVT::f32: Opc = PPC::STFS; break;
      }
    } else { //ISD::TRUNCSTORE
      switch(cast<VTSDNode>(Node->getOperand(4))->getVT()) {
      default: assert(0 && "unknown Type in store");
      case MVT::i8: Opc  = PPC::STB; break;
      case MVT::i16: Opc = PPC::STH; break;
      }
    }

    if(Address.getOpcode() == ISD::FrameIndex) {
      Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
      addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2);
    } else {
      int offset;
      switch(SelectAddr(Address, Tmp2, offset)) {
      default: assert(0 && "Unhandled return value from SelectAddr");
      case 0:   // imm offset, no frame, no index
        BuildMI(BB, Opc, 3).addReg(Tmp1).addSImm(offset).addReg(Tmp2);
        break;
      case 1:   // imm offset + frame index
        addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2, offset);
        break;
      case 2:   // base+index addressing
        Opc = IndexedOpForOp(Opc);
        BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
        break;
      case 3: {
        GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Address);
        GlobalValue *GV = GN->getGlobal();
        BuildMI(BB, Opc, 3).addReg(Tmp1).addGlobalAddress(GV).addReg(Tmp2);
      }
      }
    }
    return;
  }
  case ISD::EXTLOAD:
  case ISD::SEXTLOAD:
  case ISD::ZEXTLOAD:
  case ISD::LOAD:
  case ISD::CopyFromReg:
  case ISD::TAILCALL:
  case ISD::CALL:
  case ISD::DYNAMIC_STACKALLOC:
    ExprMap.erase(N);
    SelectExpr(N);
    return;
  }
  assert(0 && "Should not be reached!");
}


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

