//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interfaces that PIC16 uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "pic16-lower"
#include "PIC16ABINames.h"
#include "PIC16ISelLowering.h"
#include "PIC16TargetObjectFile.h"
#include "PIC16TargetMachine.h"
#include "PIC16MachineFunctionInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalValue.h"
#include "llvm/Function.h"
#include "llvm/CallingConv.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/ErrorHandling.h"


using namespace llvm;

static const char *getIntrinsicName(unsigned opcode) {
  std::string Basename;
  switch(opcode) {
  default: llvm_unreachable("do not know intrinsic name");
  // Arithmetic Right shift for integer types.
  case PIC16ISD::SRA_I8: Basename = "sra.i8"; break;
  case RTLIB::SRA_I16: Basename = "sra.i16"; break;
  case RTLIB::SRA_I32: Basename = "sra.i32"; break;

  // Left shift for integer types.
  case PIC16ISD::SLL_I8: Basename = "sll.i8"; break;
  case RTLIB::SHL_I16: Basename = "sll.i16"; break;
  case RTLIB::SHL_I32: Basename = "sll.i32"; break;

  // Logical Right Shift for integer types.
  case PIC16ISD::SRL_I8: Basename = "srl.i8"; break;
  case RTLIB::SRL_I16: Basename = "srl.i16"; break;
  case RTLIB::SRL_I32: Basename = "srl.i32"; break;

  // Multiply for integer types.
  case PIC16ISD::MUL_I8: Basename = "mul.i8"; break;
  case RTLIB::MUL_I16: Basename = "mul.i16"; break;
  case RTLIB::MUL_I32: Basename = "mul.i32"; break;

  // Signed division for integers.
  case RTLIB::SDIV_I16: Basename = "sdiv.i16"; break;
  case RTLIB::SDIV_I32: Basename = "sdiv.i32"; break;

  // Unsigned division for integers.
  case RTLIB::UDIV_I16: Basename = "udiv.i16"; break;
  case RTLIB::UDIV_I32: Basename = "udiv.i32"; break;

  // Signed Modulas for integers.
  case RTLIB::SREM_I16: Basename = "srem.i16"; break;
  case RTLIB::SREM_I32: Basename = "srem.i32"; break;

  // Unsigned Modulas for integers.
  case RTLIB::UREM_I16: Basename = "urem.i16"; break;
  case RTLIB::UREM_I32: Basename = "urem.i32"; break;

  //////////////////////
  // LIBCALLS FOR FLOATS
  //////////////////////

  // Float to signed integrals
  case RTLIB::FPTOSINT_F32_I8: Basename = "f32_to_si32"; break;
  case RTLIB::FPTOSINT_F32_I16: Basename = "f32_to_si32"; break;
  case RTLIB::FPTOSINT_F32_I32: Basename = "f32_to_si32"; break;

  // Signed integrals to float. char and int are first sign extended to i32 
  // before being converted to float, so an I8_F32 or I16_F32 isn't required.
  case RTLIB::SINTTOFP_I32_F32: Basename = "si32_to_f32"; break;

  // Float to Unsigned conversions.
  // Signed conversion can be used for unsigned conversion as well.
  // In signed and unsigned versions only the interpretation of the 
  // MSB is different. Bit representation remains the same. 
  case RTLIB::FPTOUINT_F32_I8: Basename = "f32_to_si32"; break;
  case RTLIB::FPTOUINT_F32_I16: Basename = "f32_to_si32"; break;
  case RTLIB::FPTOUINT_F32_I32: Basename = "f32_to_si32"; break;

  // Unsigned to Float conversions. char and int are first zero extended 
  // before being converted to float.
  case RTLIB::UINTTOFP_I32_F32: Basename = "ui32_to_f32"; break;
               
  // Floating point add, sub, mul, div.
  case RTLIB::ADD_F32: Basename = "add.f32"; break;
  case RTLIB::SUB_F32: Basename = "sub.f32"; break;
  case RTLIB::MUL_F32: Basename = "mul.f32"; break;
  case RTLIB::DIV_F32: Basename = "div.f32"; break;

  // Floating point comparison
  case RTLIB::O_F32: Basename = "unordered.f32"; break;
  case RTLIB::UO_F32: Basename = "unordered.f32"; break;
  case RTLIB::OLE_F32: Basename = "le.f32"; break;
  case RTLIB::OGE_F32: Basename = "ge.f32"; break;
  case RTLIB::OLT_F32: Basename = "lt.f32"; break;
  case RTLIB::OGT_F32: Basename = "gt.f32"; break;
  case RTLIB::OEQ_F32: Basename = "eq.f32"; break;
  case RTLIB::UNE_F32: Basename = "neq.f32"; break;
  }
  
  std::string prefix = PAN::getTagName(PAN::PREFIX_SYMBOL);
  std::string tagname = PAN::getTagName(PAN::LIBCALL);
  std::string Fullname = prefix + tagname + Basename; 

  // The name has to live through program life.
  return ESNames::createESName(Fullname);
}

// getStdLibCallName - Get the name for the standard library function.
static const char *getStdLibCallName(unsigned opcode) {
  std::string BaseName;
  switch(opcode) {
    case RTLIB::COS_F32: BaseName = "cos";
      break;
    case RTLIB::SIN_F32: BaseName = "sin";
      break;
    case RTLIB::MEMCPY: BaseName = "memcpy";
      break;
    case RTLIB::MEMSET: BaseName = "memset";
      break;
    case RTLIB::MEMMOVE: BaseName = "memmove";
      break;
    default: llvm_unreachable("do not know std lib call name");
  }
  std::string prefix = PAN::getTagName(PAN::PREFIX_SYMBOL);
  std::string LibCallName = prefix + BaseName;

  // The name has to live through program life.
  return ESNames::createESName(LibCallName);
}

// PIC16TargetLowering Constructor.
PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
  : TargetLowering(TM, new PIC16TargetObjectFile()) {
 
  Subtarget = &TM.getSubtarget<PIC16Subtarget>();

  addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);

  setShiftAmountType(MVT::i8);
  
  // Std lib call names
  setLibcallName(RTLIB::COS_F32, getStdLibCallName(RTLIB::COS_F32));
  setLibcallName(RTLIB::SIN_F32, getStdLibCallName(RTLIB::SIN_F32));
  setLibcallName(RTLIB::MEMCPY, getStdLibCallName(RTLIB::MEMCPY));
  setLibcallName(RTLIB::MEMSET, getStdLibCallName(RTLIB::MEMSET));
  setLibcallName(RTLIB::MEMMOVE, getStdLibCallName(RTLIB::MEMMOVE));

  // SRA library call names
  setPIC16LibcallName(PIC16ISD::SRA_I8, getIntrinsicName(PIC16ISD::SRA_I8));
  setLibcallName(RTLIB::SRA_I16, getIntrinsicName(RTLIB::SRA_I16));
  setLibcallName(RTLIB::SRA_I32, getIntrinsicName(RTLIB::SRA_I32));

  // SHL library call names
  setPIC16LibcallName(PIC16ISD::SLL_I8, getIntrinsicName(PIC16ISD::SLL_I8));
  setLibcallName(RTLIB::SHL_I16, getIntrinsicName(RTLIB::SHL_I16));
  setLibcallName(RTLIB::SHL_I32, getIntrinsicName(RTLIB::SHL_I32));

  // SRL library call names
  setPIC16LibcallName(PIC16ISD::SRL_I8, getIntrinsicName(PIC16ISD::SRL_I8));
  setLibcallName(RTLIB::SRL_I16, getIntrinsicName(RTLIB::SRL_I16));
  setLibcallName(RTLIB::SRL_I32, getIntrinsicName(RTLIB::SRL_I32));

  // MUL Library call names
  setPIC16LibcallName(PIC16ISD::MUL_I8, getIntrinsicName(PIC16ISD::MUL_I8));
  setLibcallName(RTLIB::MUL_I16, getIntrinsicName(RTLIB::MUL_I16));
  setLibcallName(RTLIB::MUL_I32, getIntrinsicName(RTLIB::MUL_I32));

  // Signed division lib call names
  setLibcallName(RTLIB::SDIV_I16, getIntrinsicName(RTLIB::SDIV_I16));
  setLibcallName(RTLIB::SDIV_I32, getIntrinsicName(RTLIB::SDIV_I32));

  // Unsigned division lib call names
  setLibcallName(RTLIB::UDIV_I16, getIntrinsicName(RTLIB::UDIV_I16));
  setLibcallName(RTLIB::UDIV_I32, getIntrinsicName(RTLIB::UDIV_I32));

  // Signed remainder lib call names
  setLibcallName(RTLIB::SREM_I16, getIntrinsicName(RTLIB::SREM_I16));
  setLibcallName(RTLIB::SREM_I32, getIntrinsicName(RTLIB::SREM_I32));

  // Unsigned remainder lib call names
  setLibcallName(RTLIB::UREM_I16, getIntrinsicName(RTLIB::UREM_I16));
  setLibcallName(RTLIB::UREM_I32, getIntrinsicName(RTLIB::UREM_I32));
 
  // Floating point to signed int conversions.
  setLibcallName(RTLIB::FPTOSINT_F32_I8, 
                 getIntrinsicName(RTLIB::FPTOSINT_F32_I8));
  setLibcallName(RTLIB::FPTOSINT_F32_I16, 
                 getIntrinsicName(RTLIB::FPTOSINT_F32_I16));
  setLibcallName(RTLIB::FPTOSINT_F32_I32, 
                 getIntrinsicName(RTLIB::FPTOSINT_F32_I32));

  // Signed int to floats.
  setLibcallName(RTLIB::SINTTOFP_I32_F32, 
                 getIntrinsicName(RTLIB::SINTTOFP_I32_F32));

  // Floating points to unsigned ints.
  setLibcallName(RTLIB::FPTOUINT_F32_I8, 
                 getIntrinsicName(RTLIB::FPTOUINT_F32_I8));
  setLibcallName(RTLIB::FPTOUINT_F32_I16, 
                 getIntrinsicName(RTLIB::FPTOUINT_F32_I16));
  setLibcallName(RTLIB::FPTOUINT_F32_I32, 
                 getIntrinsicName(RTLIB::FPTOUINT_F32_I32));

  // Unsigned int to floats.
  setLibcallName(RTLIB::UINTTOFP_I32_F32, 
                 getIntrinsicName(RTLIB::UINTTOFP_I32_F32));

  // Floating point add, sub, mul ,div.
  setLibcallName(RTLIB::ADD_F32, getIntrinsicName(RTLIB::ADD_F32));
  setLibcallName(RTLIB::SUB_F32, getIntrinsicName(RTLIB::SUB_F32));
  setLibcallName(RTLIB::MUL_F32, getIntrinsicName(RTLIB::MUL_F32));
  setLibcallName(RTLIB::DIV_F32, getIntrinsicName(RTLIB::DIV_F32));

  // Floationg point comparison
  setLibcallName(RTLIB::O_F32, getIntrinsicName(RTLIB::O_F32));
  setLibcallName(RTLIB::UO_F32, getIntrinsicName(RTLIB::UO_F32));
  setLibcallName(RTLIB::OLE_F32, getIntrinsicName(RTLIB::OLE_F32));
  setLibcallName(RTLIB::OGE_F32, getIntrinsicName(RTLIB::OGE_F32));
  setLibcallName(RTLIB::OLT_F32, getIntrinsicName(RTLIB::OLT_F32));
  setLibcallName(RTLIB::OGT_F32, getIntrinsicName(RTLIB::OGT_F32));
  setLibcallName(RTLIB::OEQ_F32, getIntrinsicName(RTLIB::OEQ_F32));
  setLibcallName(RTLIB::UNE_F32, getIntrinsicName(RTLIB::UNE_F32));

  // Return value comparisons of floating point calls. 
  setCmpLibcallCC(RTLIB::OEQ_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::UNE_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::OLT_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::OLE_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::OGE_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::OGT_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::UO_F32, ISD::SETNE);
  setCmpLibcallCC(RTLIB::O_F32, ISD::SETEQ);

  setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
  setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);

  setOperationAction(ISD::LOAD,   MVT::i8,  Legal);
  setOperationAction(ISD::LOAD,   MVT::i16, Custom);
  setOperationAction(ISD::LOAD,   MVT::i32, Custom);

  setOperationAction(ISD::STORE,  MVT::i8,  Legal);
  setOperationAction(ISD::STORE,  MVT::i16, Custom);
  setOperationAction(ISD::STORE,  MVT::i32, Custom);
  setOperationAction(ISD::STORE,  MVT::i64, Custom);

  setOperationAction(ISD::ADDE,    MVT::i8,  Custom);
  setOperationAction(ISD::ADDC,    MVT::i8,  Custom);
  setOperationAction(ISD::SUBE,    MVT::i8,  Custom);
  setOperationAction(ISD::SUBC,    MVT::i8,  Custom);
  setOperationAction(ISD::SUB,    MVT::i8,  Custom);
  setOperationAction(ISD::ADD,    MVT::i8,  Custom);
  setOperationAction(ISD::ADD,    MVT::i16, Custom);

  setOperationAction(ISD::OR,     MVT::i8,  Custom);
  setOperationAction(ISD::AND,    MVT::i8,  Custom);
  setOperationAction(ISD::XOR,    MVT::i8,  Custom);

  setOperationAction(ISD::FrameIndex, MVT::i16, Custom);

  setOperationAction(ISD::MUL,    MVT::i8,  Custom);

  setOperationAction(ISD::SMUL_LOHI,    MVT::i8,  Expand);
  setOperationAction(ISD::UMUL_LOHI,    MVT::i8,  Expand);
  setOperationAction(ISD::MULHU,        MVT::i8, Expand);
  setOperationAction(ISD::MULHS,        MVT::i8, Expand);

  setOperationAction(ISD::SRA,    MVT::i8,  Custom);
  setOperationAction(ISD::SHL,    MVT::i8,  Custom);
  setOperationAction(ISD::SRL,    MVT::i8,  Custom);

  setOperationAction(ISD::ROTL,    MVT::i8,  Expand);
  setOperationAction(ISD::ROTR,    MVT::i8,  Expand);

  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);

  // PIC16 does not support shift parts
  setOperationAction(ISD::SRA_PARTS,    MVT::i8, Expand);
  setOperationAction(ISD::SHL_PARTS,    MVT::i8, Expand);
  setOperationAction(ISD::SRL_PARTS,    MVT::i8, Expand);


  // PIC16 does not have a SETCC, expand it to SELECT_CC.
  setOperationAction(ISD::SETCC,  MVT::i8, Expand);
  setOperationAction(ISD::SELECT,  MVT::i8, Expand);
  setOperationAction(ISD::BRCOND, MVT::Other, Expand);
  setOperationAction(ISD::BRIND, MVT::Other, Expand);

  setOperationAction(ISD::SELECT_CC,  MVT::i8, Custom);
  setOperationAction(ISD::BR_CC,  MVT::i8, Custom);

  //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
  setTruncStoreAction(MVT::i16,   MVT::i8,  Custom);

  // Now deduce the information based on the above mentioned 
  // actions
  computeRegisterProperties();
}

std::pair<const TargetRegisterClass*, uint8_t>
PIC16TargetLowering::findRepresentativeClass(EVT VT) const {
  switch (VT.getSimpleVT().SimpleTy) {
  default:
    return TargetLowering::findRepresentativeClass(VT);
  case MVT::i16:
    return std::make_pair(PIC16::FSR16RegisterClass, 1);
  }
}

// getOutFlag - Extract the flag result if the Op has it.
static SDValue getOutFlag(SDValue &Op) {
  // Flag is the last value of the node.
  SDValue Flag = Op.getValue(Op.getNode()->getNumValues() - 1);

  assert (Flag.getValueType() == MVT::Flag 
          && "Node does not have an out Flag");

  return Flag;
}
// Get the TmpOffset for FrameIndex
unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI, unsigned size,
                                                MachineFunction &MF) const {
  PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>();
  std::map<unsigned, unsigned> &FiTmpOffsetMap = FuncInfo->getFiTmpOffsetMap();

  std::map<unsigned, unsigned>::iterator 
            MapIt = FiTmpOffsetMap.find(FI);
  if (MapIt != FiTmpOffsetMap.end())
      return MapIt->second;

  // This FI (FrameIndex) is not yet mapped, so map it
  FiTmpOffsetMap[FI] = FuncInfo->getTmpSize(); 
  FuncInfo->setTmpSize(FuncInfo->getTmpSize() + size);
  return FiTmpOffsetMap[FI];
}

void PIC16TargetLowering::ResetTmpOffsetMap(SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>();
  FuncInfo->getFiTmpOffsetMap().clear();
  FuncInfo->setTmpSize(0);
}

// To extract chain value from the SDValue Nodes
// This function will help to maintain the chain extracting
// code at one place. In case of any change in future it will
// help maintain the code.
static SDValue getChain(SDValue &Op) { 
  SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);

  // If the last value returned in Flag then the chain is
  // second last value returned.
  if (Chain.getValueType() == MVT::Flag)
    Chain = Op.getValue(Op.getNode()->getNumValues() - 2);
  
  // All nodes may not produce a chain. Therefore following assert
  // verifies that the node is returning a chain only.
  assert (Chain.getValueType() == MVT::Other 
          && "Node does not have a chain");

  return Chain;
}

/// PopulateResults - Helper function to LowerOperation.
/// If a node wants to return multiple results after lowering,
/// it stuffs them into an array of SDValue called Results.

static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) {
  if (N.getOpcode() == ISD::MERGE_VALUES) {
    int NumResults = N.getNumOperands();
    for( int i = 0; i < NumResults; i++)
      Results.push_back(N.getOperand(i));
  }
  else
    Results.push_back(N);
}

MVT::SimpleValueType
PIC16TargetLowering::getSetCCResultType(EVT ValType) const {
  return MVT::i8;
}

MVT::SimpleValueType
PIC16TargetLowering::getCmpLibcallReturnType() const {
  return MVT::i8; 
}

/// The type legalizer framework of generating legalizer can generate libcalls
/// only when the operand/result types are illegal.
/// PIC16 needs to generate libcalls even for the legal types (i8) for some ops.
/// For example an arithmetic right shift. These functions are used to lower
/// such operations that generate libcall for legal types.

void 
PIC16TargetLowering::setPIC16LibcallName(PIC16ISD::PIC16Libcall Call,
                                         const char *Name) {
  PIC16LibcallNames[Call] = Name; 
}

const char *
PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) const {
  return PIC16LibcallNames[Call];
}

SDValue
PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
                                      EVT RetVT, const SDValue *Ops,
                                      unsigned NumOps, bool isSigned,
                                      SelectionDAG &DAG, DebugLoc dl) const {

  TargetLowering::ArgListTy Args;
  Args.reserve(NumOps);

  TargetLowering::ArgListEntry Entry;
  for (unsigned i = 0; i != NumOps; ++i) {
    Entry.Node = Ops[i];
    Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext());
    Entry.isSExt = isSigned;
    Entry.isZExt = !isSigned;
    Args.push_back(Entry);
  }

  SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i16);

   const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
   std::pair<SDValue,SDValue> CallInfo = 
     LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
                 false, 0, CallingConv::C, false,
                 /*isReturnValueUsed=*/true,
                 Callee, Args, DAG, dl);

  return CallInfo.first;
}

const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
  switch (Opcode) {
  default:                         return NULL;
  case PIC16ISD::Lo:               return "PIC16ISD::Lo";
  case PIC16ISD::Hi:               return "PIC16ISD::Hi";
  case PIC16ISD::MTLO:             return "PIC16ISD::MTLO";
  case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
  case PIC16ISD::MTPCLATH:         return "PIC16ISD::MTPCLATH";
  case PIC16ISD::PIC16Connect:     return "PIC16ISD::PIC16Connect";
  case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
  case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
  case PIC16ISD::PIC16LdArg:       return "PIC16ISD::PIC16LdArg";
  case PIC16ISD::PIC16LdWF:        return "PIC16ISD::PIC16LdWF";
  case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
  case PIC16ISD::PIC16StWF:        return "PIC16ISD::PIC16StWF";
  case PIC16ISD::BCF:              return "PIC16ISD::BCF";
  case PIC16ISD::LSLF:             return "PIC16ISD::LSLF";
  case PIC16ISD::LRLF:             return "PIC16ISD::LRLF";
  case PIC16ISD::RLF:              return "PIC16ISD::RLF";
  case PIC16ISD::RRF:              return "PIC16ISD::RRF";
  case PIC16ISD::CALL:             return "PIC16ISD::CALL";
  case PIC16ISD::CALLW:            return "PIC16ISD::CALLW";
  case PIC16ISD::SUBCC:            return "PIC16ISD::SUBCC";
  case PIC16ISD::SELECT_ICC:       return "PIC16ISD::SELECT_ICC";
  case PIC16ISD::BRCOND:           return "PIC16ISD::BRCOND";
  case PIC16ISD::RET:              return "PIC16ISD::RET";
  case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
  }
}

void PIC16TargetLowering::ReplaceNodeResults(SDNode *N,
                                             SmallVectorImpl<SDValue>&Results,
                                             SelectionDAG &DAG) const {

  switch (N->getOpcode()) {
    case ISD::GlobalAddress:
      Results.push_back(ExpandGlobalAddress(N, DAG));
      return;
    case ISD::ExternalSymbol:
      Results.push_back(ExpandExternalSymbol(N, DAG));
      return;
    case ISD::STORE:
      Results.push_back(ExpandStore(N, DAG));
      return;
    case ISD::LOAD:
      PopulateResults(ExpandLoad(N, DAG), Results);
      return;
    case ISD::ADD:
      // Results.push_back(ExpandAdd(N, DAG));
      return;
    case ISD::FrameIndex:
      Results.push_back(ExpandFrameIndex(N, DAG));
      return;
    default:
      assert (0 && "not implemented");
      return;
  }
}

SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N,
                                              SelectionDAG &DAG) const {

  // Currently handling FrameIndex of size MVT::i16 only
  // One example of this scenario is when return value is written on
  // FrameIndex#0

  if (N->getValueType(0) != MVT::i16)
    return SDValue();

  // Expand the FrameIndex into ExternalSymbol and a Constant node
  // The constant will represent the frame index number
  // Get the current function frame
  MachineFunction &MF = DAG.getMachineFunction();
  const Function *Func = MF.getFunction();
  const std::string Name = Func->getName();
  
  FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0));
  // FIXME there isn't really debug info here
  DebugLoc dl = FR->getDebugLoc();

  // Expand FrameIndex like GlobalAddress and ExternalSymbol
  // Also use Offset field for lo and hi parts. The default 
  // offset is zero.

  SDValue ES;
  int FrameOffset;
  SDValue FI = SDValue(N,0);
  LegalizeFrameIndex(FI, DAG, ES, FrameOffset);
  SDValue Offset = DAG.getConstant(FrameOffset, MVT::i8);
  SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, Offset);
  SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, Offset);
  return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi);
}


SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) const { 
  StoreSDNode *St = cast<StoreSDNode>(N);
  SDValue Chain = St->getChain();
  SDValue Src = St->getValue();
  SDValue Ptr = St->getBasePtr();
  EVT ValueType = Src.getValueType();
  unsigned StoreOffset = 0;
  DebugLoc dl = N->getDebugLoc();

  SDValue PtrLo, PtrHi;
  LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset, dl);
 
  if (ValueType == MVT::i8) {
    return DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, Src,
                        PtrLo, PtrHi, 
                        DAG.getConstant (0 + StoreOffset, MVT::i8));
  }
  else if (ValueType == MVT::i16) {
    // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
    SDValue SrcLo, SrcHi;
    GetExpandedParts(Src, DAG, SrcLo, SrcHi);
    SDValue ChainLo = Chain, ChainHi = Chain;
    // FIXME: This makes unsafe assumptions. The Chain may be a TokenFactor
    // created for an unrelated purpose, in which case it may not have
    // exactly two operands. Also, even if it does have two operands, they
    // may not be the low and high parts of an aligned load that was split.
    if (Chain.getOpcode() == ISD::TokenFactor) {
      ChainLo = Chain.getOperand(0);
      ChainHi = Chain.getOperand(1);
    }
    SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other,
                                 ChainLo,
                                 SrcLo, PtrLo, PtrHi,
                                 DAG.getConstant (0 + StoreOffset, MVT::i8));

    SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi, 
                                 SrcHi, PtrLo, PtrHi,
                                 DAG.getConstant (1 + StoreOffset, MVT::i8));

    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, getChain(Store1),
                       getChain(Store2));
  }
  else if (ValueType == MVT::i32) {
    // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
    SDValue SrcLo, SrcHi;
    GetExpandedParts(Src, DAG, SrcLo, SrcHi);

    // Get the expanded parts of each of SrcLo and SrcHi.
    SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
    GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
    GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);

    SDValue ChainLo = Chain, ChainHi = Chain;
    // FIXME: This makes unsafe assumptions; see the FIXME above.
    if (Chain.getOpcode() == ISD::TokenFactor) {  
      ChainLo = Chain.getOperand(0);
      ChainHi = Chain.getOperand(1);
    }
    SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
            ChainHi2 = ChainHi;
    // FIXME: This makes unsafe assumptions; see the FIXME above.
    if (ChainLo.getOpcode() == ISD::TokenFactor) {
      ChainLo1 = ChainLo.getOperand(0);
      ChainLo2 = ChainLo.getOperand(1);
    }
    // FIXME: This makes unsafe assumptions; see the FIXME above.
    if (ChainHi.getOpcode() == ISD::TokenFactor) {
      ChainHi1 = ChainHi.getOperand(0);
      ChainHi2 = ChainHi.getOperand(1);
    }
    SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other,
                                 ChainLo1,
                                 SrcLo1, PtrLo, PtrHi,
                                 DAG.getConstant (0 + StoreOffset, MVT::i8));

    SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainLo2,
                                 SrcLo2, PtrLo, PtrHi,
                                 DAG.getConstant (1 + StoreOffset, MVT::i8));

    SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi1,
                                 SrcHi1, PtrLo, PtrHi,
                                 DAG.getConstant (2 + StoreOffset, MVT::i8));

    SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi2,
                                 SrcHi2, PtrLo, PtrHi,
                                 DAG.getConstant (3 + StoreOffset, MVT::i8));

    SDValue RetLo =  DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 
                                 getChain(Store1), getChain(Store2));
    SDValue RetHi =  DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 
                                 getChain(Store3), getChain(Store4));
    return  DAG.getNode(ISD::TokenFactor, dl, MVT::Other, RetLo, RetHi);

  } else if (ValueType == MVT::i64) {
    SDValue SrcLo, SrcHi;
    GetExpandedParts(Src, DAG, SrcLo, SrcHi);
    SDValue ChainLo = Chain, ChainHi = Chain;
    // FIXME: This makes unsafe assumptions; see the FIXME above.
    if (Chain.getOpcode() == ISD::TokenFactor) {
      ChainLo = Chain.getOperand(0);
      ChainHi = Chain.getOperand(1);
    }
    SDValue Store1 = DAG.getStore(ChainLo, dl, SrcLo, Ptr, NULL,
                                  0 + StoreOffset, false, false, 0);

    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
                      DAG.getConstant(4, Ptr.getValueType()));
    SDValue Store2 = DAG.getStore(ChainHi, dl, SrcHi, Ptr, NULL,
                                  1 + StoreOffset, false, false, 0);

    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1,
                       Store2);
  } else {
    assert (0 && "value type not supported");
    return SDValue();
  }
}

SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N,
                                                  SelectionDAG &DAG)
 const {
  ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(SDValue(N, 0));
  // FIXME there isn't really debug info here
  DebugLoc dl = ES->getDebugLoc();

  SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
  SDValue Offset = DAG.getConstant(0, MVT::i8);
  SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES, Offset);
  SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES, Offset);

  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi);
}

// ExpandGlobalAddress - 
SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N,
                                                 SelectionDAG &DAG) const {
  GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
  // FIXME there isn't really debug info here
  DebugLoc dl = G->getDebugLoc();
  
  SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), N->getDebugLoc(),
                                           MVT::i8,
                                           G->getOffset());

  SDValue Offset = DAG.getConstant(0, MVT::i8);
  SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA, Offset);
  SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA, Offset);

  return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi);
}

bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) const {
  assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");

  if (Op.getOpcode() == ISD::BUILD_PAIR) {
   if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) 
     return true;
  }
  return false;
}

// Return true if DirectAddress is in ROM_SPACE
bool PIC16TargetLowering::isRomAddress(const SDValue &Op) const {

  // RomAddress is a GlobalAddress in ROM_SPACE_
  // If the Op is not a GlobalAddress return NULL without checking
  // anything further.
  if (!isDirectAddress(Op))
    return false; 

  // Its a GlobalAddress.
  // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
  SDValue TGA = Op.getOperand(0).getOperand(0);
  GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);

  if (GSDN->getAddressSpace() == PIC16ISD::ROM_SPACE)
    return true;

  // Any other address space return it false
  return false;
}


// GetExpandedParts - This function is on the similiar lines as
// the GetExpandedInteger in type legalizer is. This returns expanded
// parts of Op in Lo and Hi. 

void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
                                           SDValue &Lo, SDValue &Hi) const {
  SDNode *N = Op.getNode();
  DebugLoc dl = N->getDebugLoc();
  EVT NewVT = getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));

  // Extract the lo component.
  Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NewVT, Op,
                   DAG.getConstant(0, MVT::i8));

  // extract the hi component
  Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NewVT, Op,
                   DAG.getConstant(1, MVT::i8));
}

// Legalize FrameIndex into ExternalSymbol and offset.
void 
PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
                                        SDValue &ES, int &Offset) const {

  MachineFunction &MF = DAG.getMachineFunction();
  const Function *Func = MF.getFunction();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>();
  const std::string Name = Func->getName();

  FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);

  // FrameIndices are not stack offsets. But they represent the request
  // for space on stack. That space requested may be more than one byte. 
  // Therefore, to calculate the stack offset that a FrameIndex aligns
  // with, we need to traverse all the FrameIndices available earlier in 
  // the list and add their requested size.
  unsigned FIndex = FR->getIndex();
  const char *tmpName;
  if (FIndex < FuncInfo->getReservedFrameCount()) {
    tmpName = ESNames::createESName(PAN::getFrameLabel(Name));
    ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
    Offset = 0;
    for (unsigned i=0; i<FIndex ; ++i) {
      Offset += MFI->getObjectSize(i);
    }
  } else {
   // FrameIndex has been made for some temporary storage 
    tmpName = ESNames::createESName(PAN::getTempdataLabel(Name));
    ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
    Offset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex), MF);
  }

  return;
}

// This function legalizes the PIC16 Addresses. If the Pointer is  
//  -- Direct address variable residing 
//     --> then a Banksel for that variable will be created.
//  -- Rom variable            
//     --> then it will be treated as an indirect address.
//  -- Indirect address 
//     --> then the address will be loaded into FSR
//  -- ADD with constant operand
//     --> then constant operand of ADD will be returned as Offset
//         and non-constant operand of ADD will be treated as pointer.
// Returns the high and lo part of the address, and the offset(in case of ADD).

void PIC16TargetLowering::LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, 
                                          SDValue &Lo, SDValue &Hi,
                                          unsigned &Offset, DebugLoc dl) const {

  // Offset, by default, should be 0
  Offset = 0;

  // If the pointer is ADD with constant,
  // return the constant value as the offset  
  if (Ptr.getOpcode() == ISD::ADD) {
    SDValue OperLeft = Ptr.getOperand(0);
    SDValue OperRight = Ptr.getOperand(1);
    if ((OperLeft.getOpcode() == ISD::Constant) &&
        (dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue() < 32 )) {
      Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
      Ptr = OperRight;
    } else if ((OperRight.getOpcode() == ISD::Constant)  &&
               (dyn_cast<ConstantSDNode>(OperRight)->getZExtValue() < 32 )){
      Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
      Ptr = OperLeft;
    }
  }

  // If the pointer is Type i8 and an external symbol
  // then treat it as direct address.
  // One example for such case is storing and loading
  // from function frame during a call
  if (Ptr.getValueType() == MVT::i8) {
    switch (Ptr.getOpcode()) {
    case ISD::TargetExternalSymbol:
      Lo = Ptr;
      Hi = DAG.getConstant(1, MVT::i8);
      return;
    }
  }

  // Expansion of FrameIndex has Lo/Hi parts
  if (isDirectAddress(Ptr)) { 
      SDValue TFI = Ptr.getOperand(0).getOperand(0); 
      int FrameOffset;
      if (TFI.getOpcode() == ISD::TargetFrameIndex) {
        LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset);
        Hi = DAG.getConstant(1, MVT::i8);
        Offset += FrameOffset; 
        return;
      } else if (TFI.getOpcode() == ISD::TargetExternalSymbol) {
        // FrameIndex has already been expanded.
        // Now just make use of its expansion
        Lo = TFI;
        Hi = DAG.getConstant(1, MVT::i8);
        SDValue FOffset = Ptr.getOperand(0).getOperand(1);
        assert (FOffset.getOpcode() == ISD::Constant && 
                          "Invalid operand of PIC16ISD::Lo");
        Offset += dyn_cast<ConstantSDNode>(FOffset)->getZExtValue();
        return;
      }
  }

  if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
    // Direct addressing case for RAM variables. The Hi part is constant
    // and the Lo part is the TGA itself.
    Lo = Ptr.getOperand(0).getOperand(0);

    // For direct addresses Hi is a constant. Value 1 for the constant
    // signifies that banksel needs to generated for it. Value 0 for
    // the constant signifies that banksel does not need to be generated 
    // for it. Mark it as 1 now and optimize later. 
    Hi = DAG.getConstant(1, MVT::i8);
    return; 
  }

  // Indirect addresses. Get the hi and lo parts of ptr. 
  GetExpandedParts(Ptr, DAG, Lo, Hi);

  // Put the hi and lo parts into FSR.
  Lo = DAG.getNode(PIC16ISD::MTLO, dl, MVT::i8, Lo);
  Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Hi);

  return;
}

SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) const {
  LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
  SDValue Chain = LD->getChain();
  SDValue Ptr = LD->getBasePtr();
  DebugLoc dl = LD->getDebugLoc();

  SDValue Load, Offset;
  SDVTList Tys; 
  EVT VT, NewVT;
  SDValue PtrLo, PtrHi;
  unsigned LoadOffset;

  // Legalize direct/indirect addresses. This will give the lo and hi parts
  // of the address and the offset.
  LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset, dl);

  // Load from the pointer (direct address or FSR) 
  VT = N->getValueType(0);
  unsigned NumLoads = VT.getSizeInBits() / 8; 
  std::vector<SDValue> PICLoads;
  unsigned iter;
  EVT MemVT = LD->getMemoryVT();
  if(ISD::isNON_EXTLoad(N)) {
    for (iter=0; iter<NumLoads ; ++iter) {
      // Add the pointer offset if any
      Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
      Tys = DAG.getVTList(MVT::i8, MVT::Other); 
      Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Chain, PtrLo, PtrHi,
                         Offset); 
      PICLoads.push_back(Load);
    }
  } else {
    // If it is extended load then use PIC16Load for Memory Bytes
    // and for all extended bytes perform action based on type of
    // extention - i.e. SignExtendedLoad or ZeroExtendedLoad

    
    // For extended loads this is the memory value type
    // i.e. without any extension
    EVT MemVT = LD->getMemoryVT();
    unsigned MemBytes = MemVT.getSizeInBits() / 8;
    // if MVT::i1 is extended to MVT::i8 then MemBytes will be zero
    // So set it to one
    if (MemBytes == 0) MemBytes = 1;
    
    unsigned ExtdBytes = VT.getSizeInBits() / 8;
    Offset = DAG.getConstant(LoadOffset, MVT::i8);

    Tys = DAG.getVTList(MVT::i8, MVT::Other); 
    // For MemBytes generate PIC16Load with proper offset
    for (iter=0; iter < MemBytes; ++iter) {
      // Add the pointer offset if any
      Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
      Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Chain, PtrLo, PtrHi,
                         Offset); 
      PICLoads.push_back(Load);
    }

    // For SignExtendedLoad
    if (ISD::isSEXTLoad(N)) {
      // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the 
      // highest MemByte
      SDValue SRA = DAG.getNode(ISD::SRA, dl, MVT::i8, Load, 
                                DAG.getConstant(7, MVT::i8));
      for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
        PICLoads.push_back(SRA);
      }
    } else if (ISD::isZEXTLoad(N) || ISD::isEXTLoad(N)) {
    //} else if (ISD::isZEXTLoad(N)) {
      // ZeroExtendedLoad -- For all ExtdBytes use constant 0
      SDValue ConstZero = DAG.getConstant(0, MVT::i8);
      for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
        PICLoads.push_back(ConstZero);
      }
    }
  }
  SDValue BP;

  if (VT == MVT::i8) {
    // Operand of Load is illegal -- Load itself is legal
    return PICLoads[0];
  }
  else if (VT == MVT::i16) {
    BP = DAG.getNode(ISD::BUILD_PAIR, dl, VT, PICLoads[0], PICLoads[1]);
    if ((MemVT == MVT::i8) || (MemVT == MVT::i1))
      Chain = getChain(PICLoads[0]);
    else
      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 
                          getChain(PICLoads[0]), getChain(PICLoads[1]));
  } else if (VT == MVT::i32) {
    SDValue BPs[2];
    BPs[0] = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, 
                         PICLoads[0], PICLoads[1]);
    BPs[1] = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16,
                         PICLoads[2], PICLoads[3]);
    BP = DAG.getNode(ISD::BUILD_PAIR, dl, VT, BPs[0], BPs[1]);
    if ((MemVT == MVT::i8) || (MemVT == MVT::i1))
      Chain = getChain(PICLoads[0]);
    else if (MemVT == MVT::i16)
      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 
                          getChain(PICLoads[0]), getChain(PICLoads[1]));
    else {
      SDValue Chains[2];
      Chains[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                              getChain(PICLoads[0]), getChain(PICLoads[1]));
      Chains[1] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                              getChain(PICLoads[2]), getChain(PICLoads[3]));
      Chain =  DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                           Chains[0], Chains[1]);
    }
  }
  Tys = DAG.getVTList(VT, MVT::Other); 
  return DAG.getNode(ISD::MERGE_VALUES, dl, Tys, BP, Chain);
}

SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) const {
  // We should have handled larger operands in type legalizer itself.
  assert (Op.getValueType() == MVT::i8 && "illegal shift to lower");
 
  SDNode *N = Op.getNode();
  SDValue Value = N->getOperand(0);
  SDValue Amt = N->getOperand(1);
  PIC16ISD::PIC16Libcall CallCode;
  switch (N->getOpcode()) {
  case ISD::SRA:
    CallCode = PIC16ISD::SRA_I8;
    break;
  case ISD::SHL:
    CallCode = PIC16ISD::SLL_I8;
    break;
  case ISD::SRL:
    CallCode = PIC16ISD::SRL_I8;
    break;
  default:
    assert ( 0 && "This shift is not implemented yet.");
    return SDValue();
  }
  SmallVector<SDValue, 2> Ops(2);
  Ops[0] = Value;
  Ops[1] = Amt;
  SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, 
                                  true, DAG, N->getDebugLoc());
  return Call;
}

SDValue PIC16TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const {
  // We should have handled larger operands in type legalizer itself.
  assert (Op.getValueType() == MVT::i8 && "illegal multiply to lower");

  SDNode *N = Op.getNode();
  SmallVector<SDValue, 2> Ops(2);
  Ops[0] = N->getOperand(0);
  Ops[1] = N->getOperand(1);
  SDValue Call = MakePIC16Libcall(PIC16ISD::MUL_I8, N->getValueType(0), 
                                  &Ops[0], 2, true, DAG, N->getDebugLoc());
  return Call;
}

void
PIC16TargetLowering::LowerOperationWrapper(SDNode *N,
                                           SmallVectorImpl<SDValue>&Results,
                                           SelectionDAG &DAG) const {
  SDValue Op = SDValue(N, 0);
  SDValue Res;
  unsigned i;
  switch (Op.getOpcode()) {
    case ISD::LOAD:
      Res = ExpandLoad(Op.getNode(), DAG); break;
    default: {
      // All other operations are handled in LowerOperation.
      Res = LowerOperation(Op, DAG);
      if (Res.getNode())
        Results.push_back(Res);
        
      return; 
    }
  }

  N = Res.getNode();
  unsigned NumValues = N->getNumValues(); 
  for (i = 0; i < NumValues ; i++) {
    Results.push_back(SDValue(N, i)); 
  }
}

SDValue PIC16TargetLowering::LowerOperation(SDValue Op,
                                            SelectionDAG &DAG) const {
  switch (Op.getOpcode()) {
    case ISD::ADD:
    case ISD::ADDC:
    case ISD::ADDE:
      return LowerADD(Op, DAG);
    case ISD::SUB:
    case ISD::SUBC:
    case ISD::SUBE:
      return LowerSUB(Op, DAG);
    case ISD::LOAD:
      return ExpandLoad(Op.getNode(), DAG);
    case ISD::STORE:
      return ExpandStore(Op.getNode(), DAG);
    case ISD::MUL:
      return LowerMUL(Op, DAG);
    case ISD::SHL:
    case ISD::SRA:
    case ISD::SRL:
      return LowerShift(Op, DAG);
    case ISD::OR:
    case ISD::AND:
    case ISD::XOR:
      return LowerBinOp(Op, DAG);
    case ISD::BR_CC:
      return LowerBR_CC(Op, DAG);
    case ISD::SELECT_CC:
      return LowerSELECT_CC(Op, DAG);
  }
  return SDValue();
}

SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
                                                 SelectionDAG &DAG,
                                                 DebugLoc dl) const {
  assert (Op.getValueType() == MVT::i8 
          && "illegal value type to store on stack.");

  MachineFunction &MF = DAG.getMachineFunction();
  const Function *Func = MF.getFunction();
  const std::string FuncName = Func->getName();


  // Put the value on stack.
  // Get a stack slot index and convert to es.
  int FI = MF.getFrameInfo()->CreateStackObject(1, 1, false);
  const char *tmpName = ESNames::createESName(PAN::getTempdataLabel(FuncName));
  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);

  // Store the value to ES.
  SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other,
                               DAG.getEntryNode(),
                               Op, ES, 
                               DAG.getConstant (1, MVT::i8), // Banksel.
                               DAG.getConstant (GetTmpOffsetForFI(FI, 1, MF), 
                                                MVT::i8));

  // Load the value from ES.
  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
  SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Store,
                             ES, DAG.getConstant (1, MVT::i8),
                             DAG.getConstant (GetTmpOffsetForFI(FI, 1, MF), 
                             MVT::i8));
    
  return Load.getValue(0);
}

SDValue PIC16TargetLowering::
LowerIndirectCallArguments(SDValue Chain, SDValue InFlag,
                           SDValue DataAddr_Lo, SDValue DataAddr_Hi,
                           const SmallVectorImpl<ISD::OutputArg> &Outs,
                           const SmallVectorImpl<SDValue> &OutVals,
                           const SmallVectorImpl<ISD::InputArg> &Ins,
                           DebugLoc dl, SelectionDAG &DAG) const {
  unsigned NumOps = Outs.size();

  // If call has no arguments then do nothing and return.
  if (NumOps == 0)
    return Chain;

  std::vector<SDValue> Ops;
  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
  SDValue Arg, StoreRet;

  // For PIC16 ABI the arguments come after the return value. 
  unsigned RetVals = Ins.size();
  for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) {
    // Get the arguments
    Arg = OutVals[i];
    
    Ops.clear();
    Ops.push_back(Chain);
    Ops.push_back(Arg);
    Ops.push_back(DataAddr_Lo);
    Ops.push_back(DataAddr_Hi);
    Ops.push_back(DAG.getConstant(ArgOffset, MVT::i8));
    Ops.push_back(InFlag);

    StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, dl, Tys, &Ops[0], Ops.size());

    Chain = getChain(StoreRet);
    InFlag = getOutFlag(StoreRet);
    ArgOffset++;
  }
  return Chain;
}

SDValue PIC16TargetLowering::
LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag,
                         const SmallVectorImpl<ISD::OutputArg> &Outs,
                         const SmallVectorImpl<SDValue> &OutVals,
                         DebugLoc dl, SelectionDAG &DAG) const {
  unsigned NumOps = Outs.size();
  std::string Name;
  SDValue Arg, StoreAt;
  EVT ArgVT;
  unsigned Size=0;

  // If call has no arguments then do nothing and return.
  if (NumOps == 0)
    return Chain; 

  // FIXME: This portion of code currently assumes only
  // primitive types being passed as arguments.

  // Legalize the address before use
  SDValue PtrLo, PtrHi;
  unsigned AddressOffset;
  int StoreOffset = 0;
  LegalizeAddress(ArgLabel, DAG, PtrLo, PtrHi, AddressOffset, dl);
  SDValue StoreRet;

  std::vector<SDValue> Ops;
  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
  for (unsigned i=0, Offset = 0; i<NumOps; i++) {
    // Get the argument
    Arg = OutVals[i];
    StoreOffset = (Offset + AddressOffset);
   
    // Store the argument on frame

    Ops.clear();
    Ops.push_back(Chain);
    Ops.push_back(Arg);
    Ops.push_back(PtrLo);
    Ops.push_back(PtrHi);
    Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8));
    Ops.push_back(InFlag);

    StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, dl, Tys, &Ops[0], Ops.size());

    Chain = getChain(StoreRet);
    InFlag = getOutFlag(StoreRet);

    // Update the frame offset to be used for next argument
    ArgVT = Arg.getValueType();
    Size = ArgVT.getSizeInBits();
    Size = Size/8;    // Calculate size in bytes
    Offset += Size;   // Increase the frame offset
  }
  return Chain;
}

SDValue PIC16TargetLowering::
LowerIndirectCallReturn(SDValue Chain, SDValue InFlag,
                        SDValue DataAddr_Lo, SDValue DataAddr_Hi,
                        const SmallVectorImpl<ISD::InputArg> &Ins,
                        DebugLoc dl, SelectionDAG &DAG,
                        SmallVectorImpl<SDValue> &InVals) const {
  unsigned RetVals = Ins.size();

  // If call does not have anything to return
  // then do nothing and go back.
  if (RetVals == 0)
    return Chain;

  // Call has something to return
  SDValue LoadRet;

  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
  for(unsigned i=0;i<RetVals;i++) {
    LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, dl, Tys, Chain, DataAddr_Lo,
                          DataAddr_Hi, DAG.getConstant(i, MVT::i8),
                          InFlag);
    InFlag = getOutFlag(LoadRet);
    Chain = getChain(LoadRet);
    InVals.push_back(LoadRet);
  }
  return Chain;
}

SDValue PIC16TargetLowering::
LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag,
                      const SmallVectorImpl<ISD::InputArg> &Ins,
                      DebugLoc dl, SelectionDAG &DAG,
                      SmallVectorImpl<SDValue> &InVals) const {

  // Currently handling primitive types only. They will come in
  // i8 parts
  unsigned RetVals = Ins.size();

  // Return immediately if the return type is void
  if (RetVals == 0)
    return Chain;

  // Call has something to return
  
  // Legalize the address before use
  SDValue LdLo, LdHi;
  unsigned LdOffset;
  LegalizeAddress(RetLabel, DAG, LdLo, LdHi, LdOffset, dl);

  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
  SDValue LoadRet;
 
  for(unsigned i=0, Offset=0;i<RetVals;i++) {

    LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, dl, Tys, Chain, LdLo, LdHi,
                          DAG.getConstant(LdOffset + Offset, MVT::i8),
                          InFlag);

    InFlag = getOutFlag(LoadRet);

    Chain = getChain(LoadRet);
    Offset++;
    InVals.push_back(LoadRet);
  }

  return Chain;
}

SDValue
PIC16TargetLowering::LowerReturn(SDValue Chain,
                                 CallingConv::ID CallConv, bool isVarArg,
                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
                                 const SmallVectorImpl<SDValue> &OutVals,
                                 DebugLoc dl, SelectionDAG &DAG) const {

  // Number of values to return 
  unsigned NumRet = Outs.size();

  // Function returns value always on stack with the offset starting
  // from 0 
  MachineFunction &MF = DAG.getMachineFunction();
  const Function *F = MF.getFunction();
  std::string FuncName = F->getName();

  const char *tmpName = ESNames::createESName(PAN::getFrameLabel(FuncName));
  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
  SDValue BS = DAG.getConstant(1, MVT::i8);
  SDValue RetVal;
  for(unsigned i=0;i<NumRet; ++i) {
    RetVal = OutVals[i];
    Chain =  DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, RetVal,
                        ES, BS,
                        DAG.getConstant (i, MVT::i8));
      
  }
  return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain);
}

void PIC16TargetLowering::
GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain, 
               SDValue &DataAddr_Lo, SDValue &DataAddr_Hi,
               SelectionDAG &DAG) const {
   assert (Callee.getOpcode() == PIC16ISD::PIC16Connect
           && "Don't know what to do of such callee!!");
   SDValue ZeroOperand = DAG.getConstant(0, MVT::i8);
   SDValue SeqStart  = DAG.getCALLSEQ_START(Chain, ZeroOperand);
   Chain = getChain(SeqStart);
   SDValue OperFlag = getOutFlag(SeqStart); // To manage the data dependency

   // Get the Lo and Hi part of code address
   SDValue Lo = Callee.getOperand(0);
   SDValue Hi = Callee.getOperand(1);

   SDValue Data_Lo, Data_Hi;
   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
   // Subtract 2 from Address to get the Lower part of DataAddress.
   SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
   Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, 
                         DAG.getConstant(2, MVT::i8));
   SDValue Ops[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)};
   Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, Ops, 3);
   SDValue PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi);
   Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH);
   SDValue Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee,
                              OperFlag);
   Chain = getChain(Call);
   OperFlag = getOutFlag(Call);
   SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
                                       OperFlag);
   Chain = getChain(SeqEnd);
   OperFlag = getOutFlag(SeqEnd);

   // Low part of Data Address 
   DataAddr_Lo = DAG.getNode(PIC16ISD::MTLO, dl, MVT::i8, Call, OperFlag);

   // Make the second call.
   SeqStart  = DAG.getCALLSEQ_START(Chain, ZeroOperand);
   Chain = getChain(SeqStart);
   OperFlag = getOutFlag(SeqStart); // To manage the data dependency

   // Subtract 1 from Address to get high part of data address.
   Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, 
                         DAG.getConstant(1, MVT::i8));
   SDValue HiOps[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)};
   Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
   PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi);

   // Use new Lo to make another CALLW
   Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH);
   Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee, OperFlag);
   Chain = getChain(Call);
   OperFlag = getOutFlag(Call);
   SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
                                        OperFlag);
   Chain = getChain(SeqEnd);
   OperFlag = getOutFlag(SeqEnd);
   // Hi part of Data Address
   DataAddr_Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Call, OperFlag);
}

SDValue
PIC16TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
                               CallingConv::ID CallConv, bool isVarArg,
                               bool &isTailCall,
                               const SmallVectorImpl<ISD::OutputArg> &Outs,
                               const SmallVectorImpl<SDValue> &OutVals,
                               const SmallVectorImpl<ISD::InputArg> &Ins,
                               DebugLoc dl, SelectionDAG &DAG,
                               SmallVectorImpl<SDValue> &InVals) const {
    // PIC16 target does not yet support tail call optimization.
    isTailCall = false;

    assert(Callee.getValueType() == MVT::i16 &&
           "Don't know how to legalize this call node!!!");

    // The flag to track if this is a direct or indirect call.
    bool IsDirectCall = true;    
    unsigned RetVals = Ins.size();
    unsigned NumArgs = Outs.size();

    SDValue DataAddr_Lo, DataAddr_Hi; 
    if (!isa<GlobalAddressSDNode>(Callee) &&
        !isa<ExternalSymbolSDNode>(Callee)) {
       IsDirectCall = false;    // This is indirect call

       // If this is an indirect call then to pass the arguments
       // and read the return value back, we need the data address
       // of the function being called.
       // To get the data address two more calls need to be made.

       // Come here for indirect calls
       SDValue Lo, Hi;
       // Indirect addresses. Get the hi and lo parts of ptr.
       GetExpandedParts(Callee, DAG, Lo, Hi);
       // Connect Lo and Hi parts of the callee with the PIC16Connect
       Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi);

       // Read DataAddress only if we have to pass arguments or 
       // read return value. 
       if ((RetVals > 0) || (NumArgs > 0)) 
         GetDataAddress(dl, Callee, Chain, DataAddr_Lo, DataAddr_Hi, DAG);
    }

    SDValue ZeroOperand = DAG.getConstant(0, MVT::i8);

    // Start the call sequence.
    // Carring the Constant 0 along the CALLSEQSTART
    // because there is nothing else to carry.
    SDValue SeqStart  = DAG.getCALLSEQ_START(Chain, ZeroOperand);
    Chain = getChain(SeqStart);
    SDValue OperFlag = getOutFlag(SeqStart); // To manage the data dependency
    std::string Name;

    // For any direct call - callee will be GlobalAddressNode or
    // ExternalSymbol
    SDValue ArgLabel, RetLabel;
    if (IsDirectCall) { 
       // Considering the GlobalAddressNode case here.
       if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
          const GlobalValue *GV = G->getGlobal();
          Callee = DAG.getTargetGlobalAddress(GV, dl, MVT::i8);
          Name = G->getGlobal()->getName();
       } else {// Considering the ExternalSymbol case here
          ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee);
          Callee = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); 
          Name = ES->getSymbol();
       }

       // Label for argument passing
       const char *argFrame = ESNames::createESName(PAN::getArgsLabel(Name));
       ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8);

       // Label for reading return value
       const char *retName = ESNames::createESName(PAN::getRetvalLabel(Name));
       RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8);
    } else {
       // if indirect call
       SDValue CodeAddr_Lo = Callee.getOperand(0);
       SDValue CodeAddr_Hi = Callee.getOperand(1);

       /*CodeAddr_Lo = DAG.getNode(ISD::ADD, dl, MVT::i8, CodeAddr_Lo,
                                 DAG.getConstant(2, MVT::i8));*/

       // move Hi part in PCLATH
       CodeAddr_Hi = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, CodeAddr_Hi);
       Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, CodeAddr_Lo,
                            CodeAddr_Hi);
    } 

    // Pass the argument to function before making the call.
    SDValue CallArgs;
    if (IsDirectCall) {
      CallArgs = LowerDirectCallArguments(ArgLabel, Chain, OperFlag,
                                          Outs, OutVals, dl, DAG);
      Chain = getChain(CallArgs);
      OperFlag = getOutFlag(CallArgs);
    } else {
      CallArgs = LowerIndirectCallArguments(Chain, OperFlag, DataAddr_Lo,
                                            DataAddr_Hi, Outs, OutVals, Ins,
                                            dl, DAG);
      Chain = getChain(CallArgs);
      OperFlag = getOutFlag(CallArgs);
    }

    SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
    SDValue PICCall = DAG.getNode(PIC16ISD::CALL, dl, Tys, Chain, Callee,
                                  OperFlag);
    Chain = getChain(PICCall);
    OperFlag = getOutFlag(PICCall);


    // Carrying the Constant 0 along the CALLSEQSTART
    // because there is nothing else to carry.
    SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
                                        OperFlag);
    Chain = getChain(SeqEnd);
    OperFlag = getOutFlag(SeqEnd);

    // Lower the return value reading after the call.
    if (IsDirectCall)
      return LowerDirectCallReturn(RetLabel, Chain, OperFlag,
                                   Ins, dl, DAG, InVals);
    else
      return LowerIndirectCallReturn(Chain, OperFlag, DataAddr_Lo,
                                     DataAddr_Hi, Ins, dl, DAG, InVals);
}

bool PIC16TargetLowering::isDirectLoad(const SDValue Op) const {
  if (Op.getOpcode() == PIC16ISD::PIC16Load)
    if (Op.getOperand(1).getOpcode() == ISD::TargetGlobalAddress
     || Op.getOperand(1).getOpcode() == ISD::TargetExternalSymbol)
      return true;
  return false;
}

// NeedToConvertToMemOp - Returns true if one of the operands of the
// operation 'Op' needs to be put into memory. Also returns the
// operand no. of the operand to be converted in 'MemOp'. Remember, PIC16 has 
// no instruction that can operation on two registers. Most insns take
// one register and one memory operand (addwf) / Constant (addlw).
bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp, 
                      SelectionDAG &DAG) const {
  // If one of the operand is a constant, return false.
  if (Op.getOperand(0).getOpcode() == ISD::Constant ||
      Op.getOperand(1).getOpcode() == ISD::Constant)
    return false;    

  // Return false if one of the operands is already a direct
  // load and that operand has only one use.
  if (isDirectLoad(Op.getOperand(0))) {
    if (Op.getOperand(0).hasOneUse()) {  
      // Legal and profitable folding check uses the NodeId of DAG nodes.
      // This NodeId is assigned by topological order. Therefore first 
      // assign topological order then perform legal and profitable check.
      // Note:- Though this ordering is done before begining with legalization,
      // newly added node during legalization process have NodeId=-1 (NewNode)
      // therefore before performing any check proper ordering of the node is
      // required.
      DAG.AssignTopologicalOrder();

      // Direct load operands are folded in binary operations. But before folding
      // verify if this folding is legal. Fold only if it is legal otherwise
      // convert this direct load to a separate memory operation.
      if (SelectionDAGISel::IsLegalToFold(Op.getOperand(0),
                                          Op.getNode(), Op.getNode(),
                                          CodeGenOpt::Default))
        return false;
      else 
        MemOp = 0;
    }
  }

  // For operations that are non-cummutative there is no need to check 
  // for right operand because folding right operand may result in 
  // incorrect operation. 
  if (! SelectionDAG::isCommutativeBinOp(Op.getOpcode()))
    return true;

  if (isDirectLoad(Op.getOperand(1))) {
    if (Op.getOperand(1).hasOneUse()) {
      // Legal and profitable folding check uses the NodeId of DAG nodes.
      // This NodeId is assigned by topological order. Therefore first 
      // assign topological order then perform legal and profitable check.
      // Note:- Though this ordering is done before begining with legalization,
      // newly added node during legalization process have NodeId=-1 (NewNode)
      // therefore before performing any check proper ordering of the node is
      // required.
      DAG.AssignTopologicalOrder();

      // Direct load operands are folded in binary operations. But before folding
      // verify if this folding is legal. Fold only if it is legal otherwise
      // convert this direct load to a separate memory operation.
      if (SelectionDAGISel::IsLegalToFold(Op.getOperand(1),
                                          Op.getNode(), Op.getNode(),
                                          CodeGenOpt::Default))
         return false;
      else 
         MemOp = 1; 
    }
  }
  return true;
}  

// LowerBinOp - Lower a commutative binary operation that does not
// affect status flag carry.
SDValue PIC16TargetLowering::LowerBinOp(SDValue Op, SelectionDAG &DAG) const {
  DebugLoc dl = Op.getDebugLoc();

  // We should have handled larger operands in type legalizer itself.
  assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");

  unsigned MemOp = 1;
  if (NeedToConvertToMemOp(Op, MemOp, DAG)) {
    // Put one value on stack.
    SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);

    return DAG.getNode(Op.getOpcode(), dl, MVT::i8, Op.getOperand(MemOp ^ 1),
    NewVal);
  }
  else {
    return Op;
  }
}

// LowerADD - Lower all types of ADD operations including the ones
// that affects carry.
SDValue PIC16TargetLowering::LowerADD(SDValue Op, SelectionDAG &DAG) const {
  // We should have handled larger operands in type legalizer itself.
  assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
  DebugLoc dl = Op.getDebugLoc();
  unsigned MemOp = 1;
  if (NeedToConvertToMemOp(Op, MemOp, DAG)) {
    // Put one value on stack.
    SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl);
    
    // ADDC and ADDE produce two results.
    SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);

    // ADDE has three operands, the last one is the carry bit.
    if (Op.getOpcode() == ISD::ADDE)
      return DAG.getNode(Op.getOpcode(), dl, Tys, Op.getOperand(MemOp ^ 1),
                         NewVal, Op.getOperand(2));
    // ADDC has two operands.
    else if (Op.getOpcode() == ISD::ADDC)
      return DAG.getNode(Op.getOpcode(), dl, Tys, Op.getOperand(MemOp ^ 1),
                         NewVal);
    // ADD it is. It produces only one result.
    else
      return DAG.getNode(Op.getOpcode(), dl, MVT::i8, Op.getOperand(MemOp ^ 1),
                         NewVal);
  }
  else
    return Op;
}

SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) const {
  DebugLoc dl = Op.getDebugLoc();
  // We should have handled larger operands in type legalizer itself.
  assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
  unsigned MemOp = 1;
  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);

  // Since we don't have an instruction for X - c , 
  // we can change it to X + (-c)
  ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
  if (C && (Op.getOpcode() == ISD::SUB))
    {
      return DAG.getNode(ISD::ADD, 
                         dl, MVT::i8, Op.getOperand(0), 
                         DAG.getConstant(0-(C->getZExtValue()), MVT::i8));
    }

  if (NeedToConvertToMemOp(Op, MemOp, DAG) ||
      (isDirectLoad(Op.getOperand(1)) && 
       (!isDirectLoad(Op.getOperand(0))) &&
       (Op.getOperand(0).getOpcode() != ISD::Constant)))
    {
      // Put first operand on stack.
      SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG, dl);
      
      switch (Op.getOpcode()) {
      default:
        assert (0 && "Opcode unknown."); 
      case ISD::SUBE:
        return DAG.getNode(Op.getOpcode(), 
                           dl, Tys, NewVal, Op.getOperand(1),
                           Op.getOperand(2));
        break;
      case ISD::SUBC:
        return DAG.getNode(Op.getOpcode(), 
                           dl, Tys, NewVal, Op.getOperand(1));
        break;
      case ISD::SUB:
        return DAG.getNode(Op.getOpcode(), 
                           dl, MVT::i8, NewVal, Op.getOperand(1));
        break;
      }
    }
  else 
    return Op;
}

void PIC16TargetLowering::InitReservedFrameCount(const Function *F,
                                                 SelectionDAG &DAG) const {
  MachineFunction &MF = DAG.getMachineFunction();
  PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>();

  unsigned NumArgs = F->arg_size();

  bool isVoidFunc = (F->getReturnType()->getTypeID() == Type::VoidTyID);

  if (isVoidFunc)
    FuncInfo->setReservedFrameCount(NumArgs);
  else
    FuncInfo->setReservedFrameCount(NumArgs + 1);
}

// LowerFormalArguments - Argument values are loaded from the
// <fname>.args + offset. All arguments are already broken to leaglized
// types, so the offset just runs from 0 to NumArgVals - 1.

SDValue
PIC16TargetLowering::LowerFormalArguments(SDValue Chain,
                                          CallingConv::ID CallConv,
                                          bool isVarArg,
                                      const SmallVectorImpl<ISD::InputArg> &Ins,
                                          DebugLoc dl,
                                          SelectionDAG &DAG,
                                          SmallVectorImpl<SDValue> &InVals)
                                            const {
  unsigned NumArgVals = Ins.size();

  // Get the callee's name to create the <fname>.args label to pass args.
  MachineFunction &MF = DAG.getMachineFunction();
  const Function *F = MF.getFunction();
  std::string FuncName = F->getName();

  // Reset the map of FI and TmpOffset 
  ResetTmpOffsetMap(DAG);
  // Initialize the ReserveFrameCount
  InitReservedFrameCount(F, DAG);

  // Create the <fname>.args external symbol.
  const char *tmpName = ESNames::createESName(PAN::getArgsLabel(FuncName));
  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);

  // Load arg values from the label + offset.
  SDVTList VTs  = DAG.getVTList (MVT::i8, MVT::Other);
  SDValue BS = DAG.getConstant(1, MVT::i8);
  for (unsigned i = 0; i < NumArgVals ; ++i) {
    SDValue Offset = DAG.getConstant(i, MVT::i8);
    SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS,
                                  Offset);
    Chain = getChain(PICLoad);
    InVals.push_back(PICLoad);
  }

  return Chain;
}

// Perform DAGCombine of PIC16Load.
// FIXME - Need a more elaborate comment here.
SDValue PIC16TargetLowering::
PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue Chain = N->getOperand(0); 
  if (N->hasNUsesOfValue(0, 0)) {
    DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
  }
  return SDValue();
}

// For all the functions with arguments some STORE nodes are generated 
// that store the argument on the frameindex. However in PIC16 the arguments
// are passed on stack only. Therefore these STORE nodes are redundant. 
// To remove these STORE nodes will be removed in PerformStoreCombine 
//
// Currently this function is doint nothing and will be updated for removing
// unwanted store operations
SDValue PIC16TargetLowering::
PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const {
  return SDValue(N, 0);
  /*
  // Storing an undef value is of no use, so remove it
  if (isStoringUndef(N, Chain, DAG)) {
    return Chain; // remove the store and return the chain
  }
  //else everything is ok.
  return SDValue(N, 0);
  */
}

SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
                                               DAGCombinerInfo &DCI) const {
  switch (N->getOpcode()) {
  case ISD::STORE:   
   return PerformStoreCombine(N, DCI); 
  case PIC16ISD::PIC16Load:   
    return PerformPIC16LoadCombine(N, DCI);
  }
  return SDValue();
}

static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) {
  switch (CC) {
  default: llvm_unreachable("Unknown condition code!");
  case ISD::SETNE:  return PIC16CC::NE;
  case ISD::SETEQ:  return PIC16CC::EQ;
  case ISD::SETGT:  return PIC16CC::GT;
  case ISD::SETGE:  return PIC16CC::GE;
  case ISD::SETLT:  return PIC16CC::LT;
  case ISD::SETLE:  return PIC16CC::LE;
  case ISD::SETULT: return PIC16CC::ULT;
  case ISD::SETULE: return PIC16CC::ULE;
  case ISD::SETUGE: return PIC16CC::UGE;
  case ISD::SETUGT: return PIC16CC::UGT;
  }
}

// Look at LHS/RHS/CC and see if they are a lowered setcc instruction.  If so
// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
                             ISD::CondCode CC, unsigned &SPCC) {
  if (isa<ConstantSDNode>(RHS) &&
      cast<ConstantSDNode>(RHS)->isNullValue() &&
      CC == ISD::SETNE &&
      (LHS.getOpcode() == PIC16ISD::SELECT_ICC &&
        LHS.getOperand(3).getOpcode() == PIC16ISD::SUBCC) &&
      isa<ConstantSDNode>(LHS.getOperand(0)) &&
      isa<ConstantSDNode>(LHS.getOperand(1)) &&
      cast<ConstantSDNode>(LHS.getOperand(0))->isOne() &&
      cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) {
    SDValue CMPCC = LHS.getOperand(3);
    SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
    LHS = CMPCC.getOperand(0);
    RHS = CMPCC.getOperand(1);
  }
}

// Returns appropriate CMP insn and corresponding condition code in PIC16CC
SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS, 
                                         unsigned CC, SDValue &PIC16CC, 
                                         SelectionDAG &DAG, DebugLoc dl) const {
  PIC16CC::CondCodes CondCode = (PIC16CC::CondCodes) CC;

  // PIC16 sub is literal - W. So Swap the operands and condition if needed.
  // i.e. a < 12 can be rewritten as 12 > a.
  if (RHS.getOpcode() == ISD::Constant) {

    SDValue Tmp = LHS;
    LHS = RHS;
    RHS = Tmp;

    switch (CondCode) {
    default: break;
    case PIC16CC::LT:
      CondCode = PIC16CC::GT; 
      break;
    case PIC16CC::GT:
      CondCode = PIC16CC::LT; 
      break;
    case PIC16CC::ULT:
      CondCode = PIC16CC::UGT; 
      break;
    case PIC16CC::UGT:
      CondCode = PIC16CC::ULT; 
      break;
    case PIC16CC::GE:
      CondCode = PIC16CC::LE; 
      break;
    case PIC16CC::LE:
      CondCode = PIC16CC::GE;
      break;
    case PIC16CC::ULE:
      CondCode = PIC16CC::UGE;
      break;
    case PIC16CC::UGE:
      CondCode = PIC16CC::ULE;
      break;
    }
  }

  PIC16CC = DAG.getConstant(CondCode, MVT::i8);

  // These are signed comparisons. 
  SDValue Mask = DAG.getConstant(128, MVT::i8);
  if (isSignedComparison(CondCode)) {
    LHS = DAG.getNode (ISD::XOR, dl, MVT::i8, LHS, Mask);
    RHS = DAG.getNode (ISD::XOR, dl, MVT::i8, RHS, Mask); 
  }

  SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
  // We can use a subtract operation to set the condition codes. But
  // we need to put one operand in memory if required.
  // Nothing to do if the first operand is already a valid type (direct load 
  // for subwf and literal for sublw) and it is used by this operation only. 
  if ((LHS.getOpcode() == ISD::Constant || isDirectLoad(LHS)) 
      && LHS.hasOneUse())
    return DAG.getNode(PIC16ISD::SUBCC, dl, VTs, LHS, RHS);

  // else convert the first operand to mem.
  LHS = ConvertToMemOperand (LHS, DAG, dl);
  return DAG.getNode(PIC16ISD::SUBCC, dl, VTs, LHS, RHS);
}


SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op,
                                            SelectionDAG &DAG) const {
  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
  SDValue TrueVal = Op.getOperand(2);
  SDValue FalseVal = Op.getOperand(3);
  unsigned ORIGCC = ~0;
  DebugLoc dl = Op.getDebugLoc();

  // If this is a select_cc of a "setcc", and if the setcc got lowered into
  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
  // i.e.
  // A setcc: lhs, rhs, cc is expanded by llvm to 
  // select_cc: result of setcc, 0, 1, 0, setne
  // We can think of it as:
  // select_cc: lhs, rhs, 1, 0, cc
  LookThroughSetCC(LHS, RHS, CC, ORIGCC);
  if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);

  SDValue PIC16CC;
  SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG, dl);

  return DAG.getNode (PIC16ISD::SELECT_ICC, dl, TrueVal.getValueType(), TrueVal,
                      FalseVal, PIC16CC, Cmp.getValue(1)); 
}

MachineBasicBlock *
PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
                                                 MachineBasicBlock *BB) const {
  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
  unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm();
  DebugLoc dl = MI->getDebugLoc();

  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
  // control-flow pattern.  The incoming instruction knows the destination vreg
  // to set, the condition code register to branch on, the true/false values to
  // select between, and a branch opcode to use.
  const BasicBlock *LLVM_BB = BB->getBasicBlock();
  MachineFunction::iterator It = BB;
  ++It;

  //  thisMBB:
  //  ...
  //   TrueVal = ...
  //   [f]bCC copy1MBB
  //   fallthrough --> copy0MBB
  MachineBasicBlock *thisMBB = BB;
  MachineFunction *F = BB->getParent();
  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
  BuildMI(BB, dl, TII.get(PIC16::pic16brcond)).addMBB(sinkMBB).addImm(CC);
  F->insert(It, copy0MBB);
  F->insert(It, sinkMBB);

  // Transfer the remainder of BB and its successor edges to sinkMBB.
  sinkMBB->splice(sinkMBB->begin(), BB,
                  llvm::next(MachineBasicBlock::iterator(MI)),
                  BB->end());
  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);

  // Next, add the true and fallthrough blocks as its successors.
  BB->addSuccessor(copy0MBB);
  BB->addSuccessor(sinkMBB);

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

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

  //  sinkMBB:
  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
  //  ...
  BB = sinkMBB;
  BuildMI(*BB, BB->begin(), dl,
          TII.get(PIC16::PHI), MI->getOperand(0).getReg())
    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);

  MI->eraseFromParent();   // The pseudo instruction is gone now.
  return BB;
}


SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
  SDValue Chain = Op.getOperand(0);
  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
  SDValue LHS = Op.getOperand(2);   // LHS of the condition.
  SDValue RHS = Op.getOperand(3);   // RHS of the condition.
  SDValue Dest = Op.getOperand(4);  // BB to jump to
  unsigned ORIGCC = ~0;
  DebugLoc dl = Op.getDebugLoc();

  // If this is a br_cc of a "setcc", and if the setcc got lowered into
  // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
  LookThroughSetCC(LHS, RHS, CC, ORIGCC);
  if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);

  // Get the Compare insn and condition code.
  SDValue PIC16CC;
  SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG, dl);

  return DAG.getNode(PIC16ISD::BRCOND, dl, MVT::Other, Chain, Dest, PIC16CC, 
                     Cmp.getValue(1));
}

