//===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the Hexagon target.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "hexagon-isel"
#include "HexagonISelLowering.h"
#include "HexagonTargetMachine.h"
#include "llvm/Intrinsics.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"

using namespace llvm;


//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//

//===--------------------------------------------------------------------===//
/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
/// instructions for SelectionDAG operations.
///
namespace {
class HexagonDAGToDAGISel : public SelectionDAGISel {
  /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
  /// make the right decision when generating code for different targets.
  const HexagonSubtarget &Subtarget;

  // Keep a reference to HexagonTargetMachine.
  HexagonTargetMachine& TM;
  const HexagonInstrInfo *TII;

public:
  explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine)
    : SelectionDAGISel(targetmachine),
      Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
      TM(targetmachine),
      TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {

  }

  SDNode *Select(SDNode *N);

  // Complex Pattern Selectors.
  bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
  bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
  bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);

  virtual const char *getPassName() const {
    return "Hexagon DAG->DAG Pattern Instruction Selection";
  }

  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
  /// inline asm expressions.
  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
                                            char ConstraintCode,
                                            std::vector<SDValue> &OutOps);
  bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);

  SDNode *SelectLoad(SDNode *N);
  SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
  SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
  SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
                                        DebugLoc dl);
  SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
                                        DebugLoc dl);
  SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
  SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
  SDNode *SelectStore(SDNode *N);
  SDNode *SelectSHL(SDNode *N);
  SDNode *SelectSelect(SDNode *N);
  SDNode *SelectTruncate(SDNode *N);
  SDNode *SelectMul(SDNode *N);
  SDNode *SelectZeroExtend(SDNode *N);
  SDNode *SelectIntrinsicWOChain(SDNode *N);
  SDNode *SelectConstant(SDNode *N);
  SDNode *SelectAdd(SDNode *N);

  // Include the pieces autogenerated from the target description.
#include "HexagonGenDAGISel.inc"
};
}  // end anonymous namespace


/// createHexagonISelDag - This pass converts a legalized DAG into a
/// Hexagon-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
  return new HexagonDAGToDAGISel(TM);
}

static bool IsS11_0_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isInt<11>(v);
}


static bool IsS11_1_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,1>(v);
}


static bool IsS11_2_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,2>(v);
}


static bool IsS11_3_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,3>(v);
}


static bool IsU6_0_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isUInt<6>(v);
}


static bool IsU6_1_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedUInt<6,1>(v);
}


static bool IsU6_2_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedUInt<6,2>(v);
}


// Intrinsics that return a a predicate.
static unsigned doesIntrinsicReturnPredicate(unsigned ID)
{
  switch (ID) {
    default:
      return 0;
    case Intrinsic::hexagon_C2_cmpeq:
    case Intrinsic::hexagon_C2_cmpgt:
    case Intrinsic::hexagon_C2_cmpgtu:
    case Intrinsic::hexagon_C2_cmpgtup:
    case Intrinsic::hexagon_C2_cmpgtp:
    case Intrinsic::hexagon_C2_cmpeqp:
    case Intrinsic::hexagon_C2_bitsset:
    case Intrinsic::hexagon_C2_bitsclr:
    case Intrinsic::hexagon_C2_cmpeqi:
    case Intrinsic::hexagon_C2_cmpgti:
    case Intrinsic::hexagon_C2_cmpgtui:
    case Intrinsic::hexagon_C2_cmpgei:
    case Intrinsic::hexagon_C2_cmpgeui:
    case Intrinsic::hexagon_C2_cmplt:
    case Intrinsic::hexagon_C2_cmpltu:
    case Intrinsic::hexagon_C2_bitsclri:
    case Intrinsic::hexagon_C2_and:
    case Intrinsic::hexagon_C2_or:
    case Intrinsic::hexagon_C2_xor:
    case Intrinsic::hexagon_C2_andn:
    case Intrinsic::hexagon_C2_not:
    case Intrinsic::hexagon_C2_orn:
    case Intrinsic::hexagon_C2_pxfer_map:
    case Intrinsic::hexagon_C2_any8:
    case Intrinsic::hexagon_C2_all8:
    case Intrinsic::hexagon_A2_vcmpbeq:
    case Intrinsic::hexagon_A2_vcmpbgtu:
    case Intrinsic::hexagon_A2_vcmpheq:
    case Intrinsic::hexagon_A2_vcmphgt:
    case Intrinsic::hexagon_A2_vcmphgtu:
    case Intrinsic::hexagon_A2_vcmpweq:
    case Intrinsic::hexagon_A2_vcmpwgt:
    case Intrinsic::hexagon_A2_vcmpwgtu:
    case Intrinsic::hexagon_C2_tfrrp:
    case Intrinsic::hexagon_S2_tstbit_i:
    case Intrinsic::hexagon_S2_tstbit_r:
      return 1;
  }
}


// Intrinsics that have predicate operands.
static unsigned doesIntrinsicContainPredicate(unsigned ID)
{
  switch (ID) {
    default:
      return 0;
    case Intrinsic::hexagon_C2_tfrpr:
      return Hexagon::TFR_RsPd;
    case Intrinsic::hexagon_C2_and:
      return Hexagon::AND_pp;
    case Intrinsic::hexagon_C2_xor:
      return Hexagon::XOR_pp;
    case Intrinsic::hexagon_C2_or:
      return Hexagon::OR_pp;
    case Intrinsic::hexagon_C2_not:
      return Hexagon::NOT_p;
    case Intrinsic::hexagon_C2_any8:
      return Hexagon::ANY_pp;
    case Intrinsic::hexagon_C2_all8:
      return Hexagon::ALL_pp;
    case Intrinsic::hexagon_C2_vitpack:
      return Hexagon::VITPACK_pp;
    case Intrinsic::hexagon_C2_mask:
      return Hexagon::MASK_p;
    case Intrinsic::hexagon_C2_mux:
      return Hexagon::MUX_rr;

      // Mapping hexagon_C2_muxir to MUX_pri.  This is pretty weird - but
      // that's how it's mapped in q6protos.h.
    case Intrinsic::hexagon_C2_muxir:
      return Hexagon::MUX_ri;

      // Mapping hexagon_C2_muxri to MUX_pir.  This is pretty weird - but
      // that's how it's mapped in q6protos.h.
    case Intrinsic::hexagon_C2_muxri:
      return Hexagon::MUX_ir;

    case Intrinsic::hexagon_C2_muxii:
      return Hexagon::MUX_ii;
    case Intrinsic::hexagon_C2_vmux:
      return Hexagon::VMUX_prr64;
    case Intrinsic::hexagon_S2_valignrb:
      return Hexagon::VALIGN_rrp;
    case Intrinsic::hexagon_S2_vsplicerb:
      return Hexagon::VSPLICE_rrp;
  }
}


static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
  if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
    return true;
  }
  if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
    return true;
  }
  if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
    return true;
  }
  if (MemType == MVT::i8 && isInt<11>(Offset)) {
    return true;
  }
  return false;
}


//
// Try to lower loads of GlobalAdresses into base+offset loads.  Custom
// lowering for GlobalAddress nodes has already turned it into a
// CONST32.
//
SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
  SDValue Chain = LD->getChain();
  SDNode* Const32 = LD->getBasePtr().getNode();
  unsigned Opcode = 0;

  if (Const32->getOpcode() == HexagonISD::CONST32 &&
      ISD::isNormalLoad(LD)) {
    SDValue Base = Const32->getOperand(0);
    EVT LoadedVT = LD->getMemoryVT();
    int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
    if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
      MVT PointerTy = TLI.getPointerTy();
      const GlobalValue* GV =
        cast<GlobalAddressSDNode>(Base)->getGlobal();
      SDValue TargAddr =
        CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
      SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
                                               dl, PointerTy,
                                               TargAddr);
      // Figure out base + offset opcode
      if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
      else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
      else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
      else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
      else assert (0 && "unknown memory type");

      // Build indexed load.
      SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
      SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                              LD->getValueType(0),
                                              MVT::Other,
                                              SDValue(NewBase,0),
                                              TargetConstOff,
                                              Chain);
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
      ReplaceUses(LD, Result);
      return Result;
    }
  }

  return SelectCode(LD);
}


SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
                                                           unsigned Opcode,
                                                           DebugLoc dl)
{
  SDValue Chain = LD->getChain();
  EVT LoadedVT = LD->getMemoryVT();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  SDValue N1 = LD->getOperand(1);
  SDValue CPTmpN1_0;
  SDValue CPTmpN1_1;
  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
      N1.getNode()->getValueType(0) == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
      SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
                                                MVT::Other, Base, TargetConst,
                                                Chain);
      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
                                                SDValue(Result_1, 0));
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
      const SDValue Froms[] = { SDValue(LD, 0),
                                SDValue(LD, 1),
                                SDValue(LD, 2)
      };
      const SDValue Tos[]   = { SDValue(Result_2, 0),
                                SDValue(Result_1, 1),
                                SDValue(Result_1, 2)
      };
      ReplaceUses(Froms, Tos, 3);
      return Result_2;
    } 
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                              MVT::Other, Base, TargetConst0,
                                              Chain);
    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
                                                MVT::i64, SDValue(Result_1, 0));
    SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
                                              MVT::i32, Base, TargetConstVal,
                                                SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_2, 0),
                              SDValue(Result_3, 0),
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_2;
  }
  return SelectCode(LD);
}


SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
                                                           unsigned Opcode,
                                                           DebugLoc dl)
{
  SDValue Chain = LD->getChain();
  EVT LoadedVT = LD->getMemoryVT();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  SDValue N1 = LD->getOperand(1);
  SDValue CPTmpN1_0;
  SDValue CPTmpN1_1;
  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
      N1.getNode()->getValueType(0) == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
      SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                                MVT::i32, MVT::Other, Base,
                                                TargetConstVal, Chain);
      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                                                TargetConst0);
      SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                                MVT::i64, MVT::Other,
                                                SDValue(Result_2,0),
                                                SDValue(Result_1,0));
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
      const SDValue Froms[] = { SDValue(LD, 0),
                                SDValue(LD, 1),
                                SDValue(LD, 2)
      };
      const SDValue Tos[]   = { SDValue(Result_3, 0),
                                SDValue(Result_1, 1),
                                SDValue(Result_1, 2)
      };
      ReplaceUses(Froms, Tos, 3);
      return Result_3;
    }

    // Generate an indirect load.
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                              MVT::Other,
                                              Base, TargetConst0, Chain);
    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                                              TargetConst0);
    SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                              MVT::i64, MVT::Other,
                                              SDValue(Result_2,0),
                                              SDValue(Result_1,0));
    // Add offset to base.
    SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                              Base, TargetConstVal,
                                              SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_3, 0), // Load value.
                              SDValue(Result_4, 0), // New address.
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_3;
  }

  return SelectCode(LD);
}


SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
  SDValue Chain = LD->getChain();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  // Get the constant value.
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  EVT LoadedVT = LD->getMemoryVT();
  unsigned Opcode = 0;

  // Check for zero ext loads.
  bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);

  // Figure out the opcode.
  if (LoadedVT == MVT::i64) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = Hexagon::POST_LDrid;
    else
      Opcode = Hexagon::LDrid;
  } else if (LoadedVT == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = Hexagon::POST_LDriw;
    else
      Opcode = Hexagon::LDriw;
  } else if (LoadedVT == MVT::i16) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
    else
      Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
  } else if (LoadedVT == MVT::i8) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
    else
      Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
  } else
    assert (0 && "unknown memory type");

  // For zero ext i64 loads, we need to add combine instructions.
  if (LD->getValueType(0) == MVT::i64 &&
      LD->getExtensionType() == ISD::ZEXTLOAD) {
    return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
  }
  if (LD->getValueType(0) == MVT::i64 &&
             LD->getExtensionType() == ISD::SEXTLOAD) {
    // Handle sign ext i64 loads.
    return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
  }
  if (TII->isValidAutoIncImm(LoadedVT, Val)) {
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                            LD->getValueType(0),
                                            MVT::i32, MVT::Other, Base,
                                            TargetConstVal, Chain);
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result, 0),
                              SDValue(Result, 1),
                              SDValue(Result, 2)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result;
  } else {
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
                                              LD->getValueType(0),
                                              MVT::Other, Base, TargetConst0,
                                              Chain);
    SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                              Base, TargetConstVal,
                                              SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_1, 0),
                              SDValue(Result_2, 0),
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_1;
  }
}


SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
  SDNode *result;
  DebugLoc dl = N->getDebugLoc();
  LoadSDNode *LD = cast<LoadSDNode>(N);
  ISD::MemIndexedMode AM = LD->getAddressingMode();

  // Handle indexed loads.
  if (AM != ISD::UNINDEXED) {
    result = SelectIndexedLoad(LD, dl);
  } else {
    result = SelectBaseOffsetLoad(LD, dl);
  }

  return result;
}


SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
  SDValue Chain = ST->getChain();
  SDValue Base = ST->getBasePtr();
  SDValue Offset = ST->getOffset();
  SDValue Value = ST->getValue();
  SDNode *OffsetNode = Offset.getNode();
  // Get the constant value.
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  EVT StoredVT = ST->getMemoryVT();

  // Offset value must be within representable range
  // and must have correct alignment properties.
  if (TII->isValidAutoIncImm(StoredVT, Val)) {
    SDValue Ops[] = { Value, Base,
                      CurDAG->getTargetConstant(Val, MVT::i32), Chain};
    unsigned Opcode = 0;

    // Figure out the post inc version of opcode.
    if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
    else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
    else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
    else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
    else assert (0 && "unknown memory type");

    // Build post increment store.
    SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                            MVT::Other, Ops, 4);
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = ST->getMemOperand();
    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);

    ReplaceUses(ST, Result);
    ReplaceUses(SDValue(ST,1), SDValue(Result,1));
    return Result;
  }

  // Note: Order of operands matches the def of instruction:
  // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
  // and it differs for POST_ST* for instance.
  SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
                    Chain};
  unsigned Opcode = 0;

  // Figure out the opcode.
  if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
  else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw;
  else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
  else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
  else assert (0 && "unknown memory type");

  // Build regular store.
  SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
  SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
                                            4);
  // Build splitted incriment instruction.
  SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                            Base,
                                            TargetConstVal,
                                            SDValue(Result_1, 0));
  MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
  MemOp[0] = ST->getMemOperand();
  cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);

  ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
  ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
  return Result_2;
}


SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
                                                   DebugLoc dl) {
  SDValue Chain = ST->getChain();
  SDNode* Const32 = ST->getBasePtr().getNode();
  SDValue Value = ST->getValue();
  unsigned Opcode = 0;

  // Try to lower stores of GlobalAdresses into indexed stores.  Custom
  // lowering for GlobalAddress nodes has already turned it into a
  // CONST32.  Avoid truncating stores for the moment.  Post-inc stores
  // do the same.  Don't think there's a reason for it, so will file a
  // bug to fix.
  if ((Const32->getOpcode() == HexagonISD::CONST32) &&
      !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
    SDValue Base = Const32->getOperand(0);
    if (Base.getOpcode() == ISD::TargetGlobalAddress) {
      EVT StoredVT = ST->getMemoryVT();
      int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
      if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
        MVT PointerTy = TLI.getPointerTy();
        const GlobalValue* GV =
          cast<GlobalAddressSDNode>(Base)->getGlobal();
        SDValue TargAddr =
          CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
        SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
                                                 dl, PointerTy,
                                                 TargAddr);

        // Figure out base + offset opcode
        if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
        else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
        else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
        else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
        else assert (0 && "unknown memory type");

        SDValue Ops[] = {SDValue(NewBase,0),
                         CurDAG->getTargetConstant(Offset,PointerTy),
                         Value, Chain};
        // build indexed store
        SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                                MVT::Other, Ops, 4);
        MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
        MemOp[0] = ST->getMemOperand();
        cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
        ReplaceUses(ST, Result);
        return Result;
      }
    }
  }

  return SelectCode(ST);
}


SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  StoreSDNode *ST = cast<StoreSDNode>(N);
  ISD::MemIndexedMode AM = ST->getAddressingMode();

  // Handle indexed stores.
  if (AM != ISD::UNINDEXED) {
    return SelectIndexedStore(ST, dl);
  }
   
  return SelectBaseOffsetStore(ST, dl);
}

SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();

  //
  // %conv.i = sext i32 %tmp1 to i64
  // %conv2.i = sext i32 %add to i64
  // %mul.i = mul nsw i64 %conv2.i, %conv.i
  //
  //   --- match with the following ---
  //
  // %mul.i = mpy (%tmp1, %add)
  //

  if (N->getValueType(0) == MVT::i64) {
    // Shifting a i64 signed multiply.
    SDValue MulOp0 = N->getOperand(0);
    SDValue MulOp1 = N->getOperand(1);

    SDValue OP0;
    SDValue OP1;

    // Handle sign_extend and sextload.
    if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
      SDValue Sext0 = MulOp0.getOperand(0);
      if (Sext0.getNode()->getValueType(0) != MVT::i32) {
        SelectCode(N);
      }

      OP0 = Sext0;
    } else if (MulOp0.getOpcode() == ISD::LOAD) {
      LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
      if (LD->getMemoryVT() != MVT::i32 ||
          LD->getExtensionType() != ISD::SEXTLOAD ||
          LD->getAddressingMode() != ISD::UNINDEXED) {
        SelectCode(N);
      }

      SDValue Chain = LD->getChain();
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                            MVT::Other,
                                            LD->getBasePtr(), TargetConst0,
                                            Chain), 0);
    } else {
      return SelectCode(N);
    }

    // Same goes for the second operand.
    if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
      SDValue Sext1 = MulOp1.getOperand(0);
      if (Sext1.getNode()->getValueType(0) != MVT::i32) {
        return SelectCode(N);
      }

      OP1 = Sext1;
    } else if (MulOp1.getOpcode() == ISD::LOAD) {
      LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
      if (LD->getMemoryVT() != MVT::i32 ||
          LD->getExtensionType() != ISD::SEXTLOAD ||
          LD->getAddressingMode() != ISD::UNINDEXED) {
        return SelectCode(N);
      }

      SDValue Chain = LD->getChain();
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                            MVT::Other,
                                            LD->getBasePtr(), TargetConst0,
                                            Chain), 0);
    } else {
      return SelectCode(N);
    }

    // Generate a mpy instruction.
    SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
                                            OP0, OP1);
    ReplaceUses(N, Result);
    return Result;
  }

  return SelectCode(N);
}


SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDValue N0 = N->getOperand(0);
  if (N0.getOpcode() == ISD::SETCC) {
    SDValue N00 = N0.getOperand(0);
    if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
      SDValue N000 = N00.getOperand(0);
      SDValue N001 = N00.getOperand(1);
      if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
        SDValue N01 = N0.getOperand(1);
        SDValue N02 = N0.getOperand(2);

        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
        // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
        // IntRegs:i32:$src2)
        // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
        // Pattern complexity = 9  cost = 1  size = 0.
        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
          SDValue N1 = N->getOperand(1);
          if (N01 == N1) {
            SDValue N2 = N->getOperand(2);
            if (N000 == N2 &&
                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
                                                        MVT::i32, N000);
              SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
                                                      MVT::i32,
                                                      SDValue(SextNode, 0),
                                                      N1);
              ReplaceUses(N, Result);
              return Result;
            }
          }
        }

        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
        // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
        // IntRegs:i32:$src2)
        // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
        // Pattern complexity = 9  cost = 1  size = 0.
        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
          SDValue N1 = N->getOperand(1);
          if (N01 == N1) {
            SDValue N2 = N->getOperand(2);
            if (N000 == N2 &&
                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
                                                        MVT::i32, N000);
              SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
                                                      MVT::i32,
                                                      SDValue(SextNode, 0),
                                                      N1);
              ReplaceUses(N, Result);
              return Result;
            }
          }
        }
      }
    }
  }

  return SelectCode(N);
}


SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDValue Shift = N->getOperand(0);

  //
  // %conv.i = sext i32 %tmp1 to i64
  // %conv2.i = sext i32 %add to i64
  // %mul.i = mul nsw i64 %conv2.i, %conv.i
  // %shr5.i = lshr i64 %mul.i, 32
  // %conv3.i = trunc i64 %shr5.i to i32
  //
  //   --- match with the following ---
  //
  // %conv3.i = mpy (%tmp1, %add)
  //
  // Trunc to i32.
  if (N->getValueType(0) == MVT::i32) {
    // Trunc from i64.
    if (Shift.getNode()->getValueType(0) == MVT::i64) {
      // Trunc child is logical shift right.
      if (Shift.getOpcode() != ISD::SRL) {
        return SelectCode(N);
      }

      SDValue ShiftOp0 = Shift.getOperand(0);
      SDValue ShiftOp1 = Shift.getOperand(1);

      // Shift by const 32
      if (ShiftOp1.getOpcode() != ISD::Constant) {
        return SelectCode(N);
      }

      int32_t ShiftConst =
        cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
      if (ShiftConst != 32) {
        return SelectCode(N);
      }

      // Shifting a i64 signed multiply
      SDValue Mul = ShiftOp0;
      if (Mul.getOpcode() != ISD::MUL) {
        return SelectCode(N);
      }

      SDValue MulOp0 = Mul.getOperand(0);
      SDValue MulOp1 = Mul.getOperand(1);

      SDValue OP0;
      SDValue OP1;

      // Handle sign_extend and sextload
      if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
        SDValue Sext0 = MulOp0.getOperand(0);
        if (Sext0.getNode()->getValueType(0) != MVT::i32) {
          return SelectCode(N);
        }

        OP0 = Sext0;
      } else if (MulOp0.getOpcode() == ISD::LOAD) {
        LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
        if (LD->getMemoryVT() != MVT::i32 ||
            LD->getExtensionType() != ISD::SEXTLOAD ||
            LD->getAddressingMode() != ISD::UNINDEXED) {
          return SelectCode(N);
        }

        SDValue Chain = LD->getChain();
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                              MVT::Other,
                                              LD->getBasePtr(),
                                              TargetConst0, Chain), 0);
      } else {
        return SelectCode(N);
      }

      // Same goes for the second operand.
      if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
        SDValue Sext1 = MulOp1.getOperand(0);
        if (Sext1.getNode()->getValueType(0) != MVT::i32)
          return SelectCode(N);

        OP1 = Sext1;
      } else if (MulOp1.getOpcode() == ISD::LOAD) {
        LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
        if (LD->getMemoryVT() != MVT::i32 ||
            LD->getExtensionType() != ISD::SEXTLOAD ||
            LD->getAddressingMode() != ISD::UNINDEXED) {
          return SelectCode(N);
        }

        SDValue Chain = LD->getChain();
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                              MVT::Other,
                                              LD->getBasePtr(),
                                              TargetConst0, Chain), 0);
      } else {
        return SelectCode(N);
      }

      // Generate a mpy instruction.
      SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
                                              OP0, OP1);
      ReplaceUses(N, Result);
      return Result;
    }
  }

  return SelectCode(N);
}


SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) == MVT::i32) {
    SDValue Shl_0 = N->getOperand(0);
    SDValue Shl_1 = N->getOperand(1);
    // RHS is const.
    if (Shl_1.getOpcode() == ISD::Constant) {
      if (Shl_0.getOpcode() == ISD::MUL) {
        SDValue Mul_0 = Shl_0.getOperand(0); // Val
        SDValue Mul_1 = Shl_0.getOperand(1); // Const
        // RHS of mul is const.
        if (Mul_1.getOpcode() == ISD::Constant) {
          int32_t ShlConst =
            cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
          int32_t MulConst =
            cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
          int32_t ValConst = MulConst << ShlConst;
          SDValue Val = CurDAG->getTargetConstant(ValConst,
                                                  MVT::i32);
          if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
            if (isInt<9>(CN->getSExtValue())) {
              SDNode* Result =
                CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
                                       MVT::i32, Mul_0, Val);
              ReplaceUses(N, Result);
              return Result;
            }

        }
      } else if (Shl_0.getOpcode() == ISD::SUB) {
        SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
        SDValue Sub_1 = Shl_0.getOperand(1); // Val
        if (Sub_0.getOpcode() == ISD::Constant) {
          int32_t SubConst =
            cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
          if (SubConst == 0) {
            if (Sub_1.getOpcode() == ISD::SHL) {
              SDValue Shl2_0 = Sub_1.getOperand(0); // Val
              SDValue Shl2_1 = Sub_1.getOperand(1); // Const
              if (Shl2_1.getOpcode() == ISD::Constant) {
                int32_t ShlConst =
                  cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
                int32_t Shl2Const =
                  cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
                int32_t ValConst = 1 << (ShlConst+Shl2Const);
                SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
                if (ConstantSDNode *CN =
                    dyn_cast<ConstantSDNode>(Val.getNode()))
                  if (isInt<9>(CN->getSExtValue())) {
                    SDNode* Result =
                      CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
                                             Shl2_0, Val);
                    ReplaceUses(N, Result);
                    return Result;
                  }
              }
            }
          }
        }
      }
    }
  }
  return SelectCode(N);
}


//
// If there is an zero_extend followed an intrinsic in DAG (this means - the
// result of the intrinsic is predicate); convert the zero_extend to
// transfer instruction.
//
// Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
// converted into a MUX as predicate registers defined as 1 bit in the
// compiler. Architecture defines them as 8-bit registers.
// We want to preserve all the lower 8-bits and, not just 1 LSB bit.
//
SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDNode *IsIntrinsic = N->getOperand(0).getNode();
  if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
    unsigned ID =
      cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
    if (doesIntrinsicReturnPredicate(ID)) {
      // Now we need to differentiate target data types.
      if (N->getValueType(0) == MVT::i64) {
        // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
                                                  MVT::i32,
                                                  SDValue(IsIntrinsic, 0));
        SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
                                                  MVT::i32,
                                                  TargetConst0);
        SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                                  MVT::i64, MVT::Other,
                                                  SDValue(Result_2, 0),
                                                  SDValue(Result_1, 0));
        ReplaceUses(N, Result_3);
        return Result_3;
      }
      if (N->getValueType(0) == MVT::i32) {
        // Convert the zero_extend to Rs = Pd
        SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
                                              MVT::i32,
                                              SDValue(IsIntrinsic, 0));
        ReplaceUses(N, RsPd);
        return RsPd;
      }
      llvm_unreachable("Unexpected value type");
    }
  }
  return SelectCode(N);
}


//
// Checking for intrinsics which have predicate registers as operand(s)
// and lowering to the actual intrinsic.
//
SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
  unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);

  // We are concerned with only those intrinsics that have predicate registers
  // as at least one of the operands.
  if (IntrinsicWithPred) {
    SmallVector<SDValue, 8> Ops;
    const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
    const TargetRegisterInfo *TRI = TM.getRegisterInfo();

    // Iterate over all the operands of the intrinsics.
    // For PredRegs, do the transfer.
    // For Double/Int Regs, just preserve the value
    // For immediates, lower it.
    for (unsigned i = 1; i < N->getNumOperands(); ++i) {
      SDNode *Arg = N->getOperand(i).getNode();
      const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI);

      if (RC == Hexagon::IntRegsRegisterClass ||
          RC == Hexagon::DoubleRegsRegisterClass) {
        Ops.push_back(SDValue(Arg, 0));
      } else if (RC == Hexagon::PredRegsRegisterClass) {
        // Do the transfer.
        SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
                                              SDValue(Arg, 0));
        Ops.push_back(SDValue(PdRs,0));
      } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
        // This is immediate operand. Lower it here making sure that we DO have
        // const SDNode for immediate value.
        int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
        SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
        Ops.push_back(SDVal);
      } else {
        llvm_unreachable("Unimplemented");
      }
    }
    EVT ReturnValueVT = N->getValueType(0);
    SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
                                            ReturnValueVT,
                                            Ops.data(), Ops.size());
    ReplaceUses(N, Result);
    return Result;
  }
  return SelectCode(N);
}


//
// Map predicate true (encoded as -1 in LLVM) to a XOR.
//
SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) == MVT::i1) {
    SDNode* Result;
    int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
    if (Val == -1) {
      // Create the IntReg = 1 node.
      SDNode* IntRegTFR =
        CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                               CurDAG->getTargetConstant(0, MVT::i32));

      // Pd = IntReg
      SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
                                          SDValue(IntRegTFR, 0));

      // not(Pd)
      SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
                                             SDValue(Pd, 0));

      // xor(not(Pd))
      Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
                                      SDValue(Pd, 0), SDValue(NotPd, 0));

      // We have just built:
      // Rs = Pd
      // Pd = xor(not(Pd), Pd)

      ReplaceUses(N, Result);
      return Result;
    }
  }

  return SelectCode(N);
}


//
// Map add followed by a asr -> asr +=.
//
SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) != MVT::i32) {
    return SelectCode(N);
  }
  // Identify nodes of the form: add(asr(...)).
  SDNode* Src1 = N->getOperand(0).getNode();
  if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
      || Src1->getValueType(0) != MVT::i32) {
    return SelectCode(N);
  }

  // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
  // Rd and Rd' are assigned to the same register
  SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_rr_acc, dl, MVT::i32,
                                          N->getOperand(1),
                                          Src1->getOperand(0),
                                          Src1->getOperand(1));
  ReplaceUses(N, Result);

  return Result;
}


SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
  if (N->isMachineOpcode())
    return NULL;   // Already selected.


  switch (N->getOpcode()) {
  case ISD::Constant:
    return SelectConstant(N);

  case ISD::ADD:
    return SelectAdd(N);

  case ISD::SHL:
    return SelectSHL(N);

  case ISD::LOAD:
    return SelectLoad(N);

  case ISD::STORE:
    return SelectStore(N);

  case ISD::SELECT:
    return SelectSelect(N);

  case ISD::TRUNCATE:
    return SelectTruncate(N);

  case ISD::MUL:
    return SelectMul(N);

  case ISD::ZERO_EXTEND:
    return SelectZeroExtend(N);

  case ISD::INTRINSIC_WO_CHAIN:
    return SelectIntrinsicWOChain(N);
  }

  return SelectCode(N);
}


//
// Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
// to define these instructions.
//
bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
                                       SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return true;
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return true;
}


bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_0_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_0_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_1_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_1_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_2_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_2_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_0_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_0_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_1_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_1_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_2_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_2_Offset(Offset.getNode()));
}


bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
                                           SDValue &Offset) {

  if (Addr.getOpcode() != ISD::ADD) {
    return(SelectADDRriS11_2(Addr, Base, Offset));
  }

  return SelectADDRriS11_2(Addr, Base, Offset);
}


bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_3_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_3_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
                                       SDValue &R2) {
  if (Addr.getOpcode() == ISD::FrameIndex) return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (Addr.getOpcode() == ISD::ADD) {
    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      if (isInt<13>(CN->getSExtValue()))
        return false;  // Let the reg+imm pattern catch this!
    R1 = Addr.getOperand(0);
    R2 = Addr.getOperand(1);
    return true;
  }

  R1 = Addr;

  return true;
}


// Handle generic address case. It is accessed from inlined asm =m constraints,
// which could have any kind of pointer.
bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
                                          SDValue &Base, SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return true;
  }

  if (Addr.getOpcode() == ISD::ADD) {
    Base = Addr.getOperand(0);
    Offset = Addr.getOperand(1);
    return true;
  }

  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return true;
}


bool HexagonDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
                             std::vector<SDValue> &OutOps) {
  SDValue Op0, Op1;

  switch (ConstraintCode) {
  case 'o':   // Offsetable.
  case 'v':   // Not offsetable.
  default: return true;
  case 'm':   // Memory.
    if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
      return true;
    break;
  }

  OutOps.push_back(Op0);
  OutOps.push_back(Op1);
  return false;
}
