Ejemplo n.º 1
0
static bool printOperand(raw_ostream &OS, const SelectionDAG *G,
                         const SDValue Value) {
  if (shouldPrintInline(*Value.getNode())) {
    OS << Value->getOperationName(G) << ':';
    Value->print_types(OS, G);
    Value->print_details(OS, G);
    return true;
  } else {
    OS << PrintNodeId(*Value.getNode());
    if (unsigned RN = Value.getResNo())
      OS << ':' << RN;
    return false;
  }
}
Ejemplo n.º 2
0
/// getVR - Return the virtual register corresponding to the specified result
/// of the specified node.
unsigned ScheduleDAGSDNodes::getVR(SDValue Op,
                                   DenseMap<SDValue, unsigned> &VRBaseMap) {
  if (Op.isMachineOpcode() &&
      Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
    // Add an IMPLICIT_DEF instruction before every use.
    unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo());
    // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
    // does not include operand register class info.
    if (!VReg) {
      const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType());
      VReg = MRI.createVirtualRegister(RC);
    }
    BuildMI(BB, Op.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF),VReg);
    return VReg;
  }

  DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op);
  assert(I != VRBaseMap.end() && "Node emitted out of order - late");
  return I->second;
}
Ejemplo n.º 3
0
/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
/// implicit physical register output.
void InstrEmitter::
EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned,
                unsigned SrcReg, DenseMap<SDValue, unsigned> &VRBaseMap) {
  unsigned VRBase = 0;
  if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
    // Just use the input register directly!
    SDValue Op(Node, ResNo);
    if (IsClone)
      VRBaseMap.erase(Op);
    bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second;
    (void)isNew; // Silence compiler warning.
    assert(isNew && "Node emitted out of order - early");
    return;
  }

  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
  // the CopyToReg'd destination register instead of creating a new vreg.
  bool MatchReg = true;
  const TargetRegisterClass *UseRC = nullptr;
  MVT VT = Node->getSimpleValueType(ResNo);

  // Stick to the preferred register classes for legal types.
  if (TLI->isTypeLegal(VT))
    UseRC = TLI->getRegClassFor(VT);

  if (!IsClone && !IsCloned)
    for (SDNode *User : Node->uses()) {
      bool Match = true;
      if (User->getOpcode() == ISD::CopyToReg &&
          User->getOperand(2).getNode() == Node &&
          User->getOperand(2).getResNo() == ResNo) {
        unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
        if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
          VRBase = DestReg;
          Match = false;
        } else if (DestReg != SrcReg)
          Match = false;
      } else {
        for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
          SDValue Op = User->getOperand(i);
          if (Op.getNode() != Node || Op.getResNo() != ResNo)
            continue;
          MVT VT = Node->getSimpleValueType(Op.getResNo());
          if (VT == MVT::Other || VT == MVT::Glue)
            continue;
          Match = false;
          if (User->isMachineOpcode()) {
            const MCInstrDesc &II = TII->get(User->getMachineOpcode());
            const TargetRegisterClass *RC = nullptr;
            if (i+II.getNumDefs() < II.getNumOperands()) {
              RC = TRI->getAllocatableClass(
                TII->getRegClass(II, i+II.getNumDefs(), TRI, *MF));
            }
            if (!UseRC)
              UseRC = RC;
            else if (RC) {
              const TargetRegisterClass *ComRC =
                TRI->getCommonSubClass(UseRC, RC, VT.SimpleTy);
              // If multiple uses expect disjoint register classes, we emit
              // copies in AddRegisterOperand.
              if (ComRC)
                UseRC = ComRC;
            }
          }
        }
      }
      MatchReg &= Match;
      if (VRBase)
        break;
    }

  const TargetRegisterClass *SrcRC = nullptr, *DstRC = nullptr;
  SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT);

  // Figure out the register class to create for the destreg.
  if (VRBase) {
    DstRC = MRI->getRegClass(VRBase);
  } else if (UseRC) {
    assert(TRI->isTypeLegalForClass(*UseRC, VT) &&
           "Incompatible phys register def and uses!");
    DstRC = UseRC;
  } else {
    DstRC = TLI->getRegClassFor(VT);
  }

  // If all uses are reading from the src physical register and copying the
  // register is either impossible or very expensive, then don't create a copy.
  if (MatchReg && SrcRC->getCopyCost() < 0) {
    VRBase = SrcReg;
  } else {
    // Create the reg, emit the copy.
    VRBase = MRI->createVirtualRegister(DstRC);
    BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY),
            VRBase).addReg(SrcReg);
  }

  SDValue Op(Node, ResNo);
  if (IsClone)
    VRBaseMap.erase(Op);
  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
  (void)isNew; // Silence compiler warning.
  assert(isNew && "Node emitted out of order - early");
}
Ejemplo n.º 4
0
/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
/// implicit physical register output.
void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
                                         bool IsClone, bool IsCloned,
                                         unsigned SrcReg,
                                         DenseMap<SDValue, unsigned> &VRBaseMap) {
  unsigned VRBase = 0;
  if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
    // Just use the input register directly!
    SDValue Op(Node, ResNo);
    if (IsClone)
      VRBaseMap.erase(Op);
    bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second;
    isNew = isNew; // Silence compiler warning.
    assert(isNew && "Node emitted out of order - early");
    return;
  }

  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
  // the CopyToReg'd destination register instead of creating a new vreg.
  bool MatchReg = true;
  const TargetRegisterClass *UseRC = NULL;
  if (!IsClone && !IsCloned)
    for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
         UI != E; ++UI) {
      SDNode *User = *UI;
      bool Match = true;
      if (User->getOpcode() == ISD::CopyToReg && 
          User->getOperand(2).getNode() == Node &&
          User->getOperand(2).getResNo() == ResNo) {
        unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
        if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
          VRBase = DestReg;
          Match = false;
        } else if (DestReg != SrcReg)
          Match = false;
      } else {
        for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
          SDValue Op = User->getOperand(i);
          if (Op.getNode() != Node || Op.getResNo() != ResNo)
            continue;
          MVT VT = Node->getValueType(Op.getResNo());
          if (VT == MVT::Other || VT == MVT::Flag)
            continue;
          Match = false;
          if (User->isMachineOpcode()) {
            const TargetInstrDesc &II = TII->get(User->getMachineOpcode());
            const TargetRegisterClass *RC =
              getInstrOperandRegClass(TRI, II, i+II.getNumDefs());
            if (!UseRC)
              UseRC = RC;
            else if (RC) {
              if (UseRC->hasSuperClass(RC))
                UseRC = RC;
              else
                assert((UseRC == RC || RC->hasSuperClass(UseRC)) &&
                       "Multiple uses expecting different register classes!");
            }
          }
        }
      }
      MatchReg &= Match;
      if (VRBase)
        break;
    }

  MVT VT = Node->getValueType(ResNo);
  const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
  SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT);
  
  // Figure out the register class to create for the destreg.
  if (VRBase) {
    DstRC = MRI.getRegClass(VRBase);
  } else if (UseRC) {
    assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
    DstRC = UseRC;
  } else {
    DstRC = TLI->getRegClassFor(VT);
  }
    
  // If all uses are reading from the src physical register and copying the
  // register is either impossible or very expensive, then don't create a copy.
  if (MatchReg && SrcRC->getCopyCost() < 0) {
    VRBase = SrcReg;
  } else {
    // Create the reg, emit the copy.
    VRBase = MRI.createVirtualRegister(DstRC);
    bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
                                     DstRC, SrcRC);
    // If the target didn't handle the copy with different register
    // classes and the destination is a subset of the source,
    // try a normal same-RC copy.
    if (!Emitted && DstRC->hasSuperClass(SrcRC))
      Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
                                  SrcRC, SrcRC);

    assert(Emitted && "Unable to issue a copy instruction!\n");
  }

  SDValue Op(Node, ResNo);
  if (IsClone)
    VRBaseMap.erase(Op);
  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
  isNew = isNew; // Silence compiler warning.
  assert(isNew && "Node emitted out of order - early");
}
Ejemplo n.º 5
0
SDNode *HSAILDAGToDAGISel::SelectImageIntrinsic(SDNode *Node) {
  SDValue Chain = Node->getOperand(0);
  SDNode *ResNode;

  unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
  bool hasSampler = false;

  if (IntNo == HSAILIntrinsic::HSAIL_rd_imgf_1d_s32) {
    SDLoc SL;
    const SDValue Ops[] = {
      CurDAG->getTargetConstant(1, SL, MVT::i1),                 // v4
      CurDAG->getTargetConstant(BRIG_TYPE_ROIMG, SL, MVT::i32),  // imageType
      CurDAG->getTargetConstant(BRIG_TYPE_S32, SL, MVT::i32),    // coordType
      CurDAG->getTargetConstant(BRIG_GEOMETRY_1D, SL, MVT::i32), // geometry
      CurDAG->getTargetConstant(0, SL, MVT::i32),                // equiv
      Node->getOperand(2),                                       // image
      Node->getOperand(3),                                       // sampler
      Node->getOperand(4),                                       // coordWidth
      CurDAG->getTargetConstant(BRIG_TYPE_F32, SL, MVT::i32),    // destType
      Chain
    };

    return CurDAG->SelectNodeTo(Node, HSAIL::RDIMAGE, Node->getVTList(), Ops);
  }

  if (HSAILIntrinsicInfo::isReadImage((HSAILIntrinsic::ID)IntNo)) {
    hasSampler = true;
  } else if (!HSAILIntrinsicInfo::isLoadImage((HSAILIntrinsic::ID)IntNo)) {
    return SelectCode(Node);
  }

  if (((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_rd_imgf_2ddepth_f32) ||
      ((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_rd_imgf_2ddepth_s32) ||
      ((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_ld_imgf_2ddepth_u32) ||
      ((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_rd_imgf_2dadepth_f32) ||
      ((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_rd_imgf_2dadepth_s32) ||
      ((HSAILIntrinsic::ID)IntNo) ==
          (HSAILIntrinsic::HSAIL_ld_imgf_2dadepth_u32)) {
    assert(Node->getNumValues() == 2);
  } else {
    assert(Node->getNumValues() == 5);
  }
  SmallVector<SDValue, 6> NewOps;

  unsigned OpIndex = 2;

  SDValue Img = Node->getOperand(OpIndex++);
  int ResNo = Img.getResNo();
  SDValue ImgHandle = Img.getValue(ResNo);
  NewOps.push_back(ImgHandle);

  if (hasSampler) {
    SDValue Smp = Node->getOperand(OpIndex++);
    SDValue SmpHandle = Smp.getValue(Smp.getResNo());
    NewOps.push_back(SmpHandle);
  }

  while (OpIndex < Node->getNumOperands()) {
    SDValue Coord = Node->getOperand(OpIndex++);
    NewOps.push_back(Coord);
  }

  NewOps.push_back(Chain);

  ResNode = CurDAG->SelectNodeTo(Node, getImageInstr((HSAILIntrinsic::ID)IntNo),
                                 Node->getVTList(), NewOps);
  return ResNode;
}
Ejemplo n.º 6
0
SDNode *CoffeeDAGToDAGISel::SelectBRCONDOp(SDNode *N) {

    SDValue Chain = N->getOperand(0); // Chain
    SDValue N1 = N->getOperand(1); // Destination
    SDValue N2 = N->getOperand(2); // CondCode as constant
    SDValue N3 = N->getOperand(3); // CC regsiter to check --> CR0
    SDValue InFlag = N->getOperand(4); // glue
    assert(N1.getOpcode() == ISD::BasicBlock);
    assert(N2.getOpcode() == ISD::Constant);
    assert(N3.getOpcode() == ISD::Register);

    DebugLoc dl = N->getDebugLoc();

    ISD::CondCode cc = (ISD::CondCode)cast<ConstantSDNode>(N2)->getZExtValue();

    // The main logic here follows ARM implementation but unlike ARM,
    // Coffee has dedicated branch instructions for each situations while
    // ARM has one instruction which take CondCode as operands.
    unsigned Opc = 0;
    switch (cc) {
    default:
        llvm_unreachable("coffee:: unexpected condition code");
        break;
    case ISD::SETEQ:
    case ISD::SETUEQ:
    case ISD::SETOEQ:
        Opc = Coffee::BEQ;
        break;
    case ISD::SETGT:
    case ISD::SETUGT:
    case ISD::SETOGT:
        Opc = Coffee::BGT;
        break;
    case ISD::SETGE:
    case ISD::SETUGE:
    case ISD::SETOGE:
        Opc = Coffee::BEGT;
        break;
    case ISD::SETLT:
    case ISD::SETULT:
    case ISD::SETOLT:
        Opc = Coffee::BLT;
        break;
    case ISD::SETLE:
    case ISD::SETULE:
    case ISD::SETOLE:
        Opc = Coffee::BELT;
        break;
    case ISD::SETNE:
    case ISD::SETUNE:
    case ISD::SETONE:
        Opc = Coffee::BNE;
        break;
    }

    SDValue Ops[] = { N3, N1, Chain, InFlag };

    // TODO: do we need output glue here ?
    SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
                                             MVT::Glue, Ops, 4);

    /***NOTE**/
    // Is replaceUses function meant for Chain Node ?

    Chain = SDValue(ResNode, 0);
    ReplaceUses(SDValue(N, 0),
                SDValue(Chain.getNode(), Chain.getResNo()));
    return NULL;

}
/// LowerCCCCallTo - functions arguments are copied from virtual regs to
/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
/// TODO: sret.
SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG,
        unsigned CC) {
    CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
    SDValue Chain  = TheCall->getChain();
    SDValue Callee = TheCall->getCallee();
    bool isVarArg  = TheCall->isVarArg();
    DebugLoc dl = Op.getDebugLoc();

    // Analyze operands of the call, assigning locations to each operand.
    SmallVector<CCValAssign, 16> ArgLocs;
    CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);

    CCInfo.AnalyzeCallOperands(TheCall, CC_MSP430);

    // Get a count of how many bytes are to be pushed on the stack.
    unsigned NumBytes = CCInfo.getNextStackOffset();

    Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
                                 getPointerTy(), true));

    SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
    SmallVector<SDValue, 12> MemOpChains;
    SDValue StackPtr;

    // Walk the register/memloc assignments, inserting copies/loads.
    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
        CCValAssign &VA = ArgLocs[i];

        // Arguments start after the 5 first operands of ISD::CALL
        SDValue Arg = TheCall->getArg(i);

        // Promote the value if needed.
        switch (VA.getLocInfo()) {
        default:
            assert(0 && "Unknown loc info!");
        case CCValAssign::Full:
            break;
        case CCValAssign::SExt:
            Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
            break;
        case CCValAssign::ZExt:
            Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
            break;
        case CCValAssign::AExt:
            Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
            break;
        }

        // Arguments that can be passed on register must be kept at RegsToPass
        // vector
        if (VA.isRegLoc()) {
            RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
        } else {
            assert(VA.isMemLoc());

            if (StackPtr.getNode() == 0)
                StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());

            SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
                                         StackPtr,
                                         DAG.getIntPtrConstant(VA.getLocMemOffset()));


            MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
                                               PseudoSourceValue::getStack(),
                                               VA.getLocMemOffset()));
        }
    }

    // Transform all store nodes into one single node because all store nodes are
    // independent of each other.
    if (!MemOpChains.empty())
        Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
                            &MemOpChains[0], MemOpChains.size());

    // Build a sequence of copy-to-reg nodes chained together with token chain and
    // flag operands which copy the outgoing args into registers.  The InFlag in
    // necessary since all emited instructions must be stuck together.
    SDValue InFlag;
    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
        Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
                                 RegsToPass[i].second, InFlag);
        InFlag = Chain.getValue(1);
    }

    // If the callee is a GlobalAddress node (quite common, every direct call is)
    // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
    // Likewise ExternalSymbol -> TargetExternalSymbol.
    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
        Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16);
    else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
        Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);

    // Returns a chain & a flag for retval copy to use.
    SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
    SmallVector<SDValue, 8> Ops;
    Ops.push_back(Chain);
    Ops.push_back(Callee);

    // Add argument registers to the end of the list so that they are
    // known live into the call.
    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
        Ops.push_back(DAG.getRegister(RegsToPass[i].first,
                                      RegsToPass[i].second.getValueType()));

    if (InFlag.getNode())
        Ops.push_back(InFlag);

    Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
    InFlag = Chain.getValue(1);

    // Create the CALLSEQ_END node.
    Chain = DAG.getCALLSEQ_END(Chain,
                               DAG.getConstant(NumBytes, getPointerTy(), true),
                               DAG.getConstant(0, getPointerTy(), true),
                               InFlag);
    InFlag = Chain.getValue(1);

    // Handle result values, copying them out of physregs into vregs that we
    // return.
    return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG),
                   Op.getResNo());
}
/// LowerCCCArguments - transform physical registers into virtual registers and
/// generate load operations for arguments places on the stack.
// FIXME: struct return stuff
// FIXME: varargs
SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op,
        SelectionDAG &DAG) {
    MachineFunction &MF = DAG.getMachineFunction();
    MachineFrameInfo *MFI = MF.getFrameInfo();
    MachineRegisterInfo &RegInfo = MF.getRegInfo();
    SDValue Root = Op.getOperand(0);
    bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
    unsigned CC = MF.getFunction()->getCallingConv();
    DebugLoc dl = Op.getDebugLoc();

    // Assign locations to all of the incoming arguments.
    SmallVector<CCValAssign, 16> ArgLocs;
    CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
    CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430);

    assert(!isVarArg && "Varargs not supported yet");

    SmallVector<SDValue, 16> ArgValues;
    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
        CCValAssign &VA = ArgLocs[i];
        if (VA.isRegLoc()) {
            // Arguments passed in registers
            MVT RegVT = VA.getLocVT();
            switch (RegVT.getSimpleVT()) {
            default:
                cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
                     << RegVT.getSimpleVT()
                     << "\n";
                abort();
            case MVT::i16:
                unsigned VReg =
                    RegInfo.createVirtualRegister(MSP430::GR16RegisterClass);
                RegInfo.addLiveIn(VA.getLocReg(), VReg);
                SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT);

                // If this is an 8-bit value, it is really passed promoted to 16
                // bits. Insert an assert[sz]ext to capture this, then truncate to the
                // right size.
                if (VA.getLocInfo() == CCValAssign::SExt)
                    ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
                                           DAG.getValueType(VA.getValVT()));
                else if (VA.getLocInfo() == CCValAssign::ZExt)
                    ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
                                           DAG.getValueType(VA.getValVT()));

                if (VA.getLocInfo() != CCValAssign::Full)
                    ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);

                ArgValues.push_back(ArgValue);
            }
        } else {
            // Sanity check
            assert(VA.isMemLoc());
            // Load the argument to a virtual register
            unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
            if (ObjSize > 2) {
                cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
                     << VA.getLocVT().getSimpleVT()
                     << "\n";
            }
            // Create the frame index object for this incoming parameter...
            int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset());

            // Create the SelectionDAG nodes corresponding to a load
            //from this parameter
            SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
            ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN,
                                            PseudoSourceValue::getFixedStack(FI), 0));
        }
    }

    ArgValues.push_back(Root);

    // Return the new list of results.
    return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
                       &ArgValues[0], ArgValues.size()).getValue(Op.getResNo());
}
// selectMSUB -
// Transforms a subgraph in CurDAG if the following pattern is found:
//  (addc Lo0, multLo), (sube Hi0, multHi),
// where,
//  multHi/Lo: product of multiplication
//  Lo0: initial value of Lo register
//  Hi0: initial value of Hi register
// Return true if pattern matching was successful.
static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
  // SUBENode's second operand must be a flag output of an SUBC node in order
  // for the matching to be successful.
  SDNode *SUBCNode = SUBENode->getOperand(2).getNode();

  if (SUBCNode->getOpcode() != ISD::SUBC)
    return false;

  SDValue MultHi = SUBENode->getOperand(1);
  SDValue MultLo = SUBCNode->getOperand(1);
  SDNode *MultNode = MultHi.getNode();
  unsigned MultOpc = MultHi.getOpcode();

  // MultHi and MultLo must be generated by the same node,
  if (MultLo.getNode() != MultNode)
    return false;

  // and it must be a multiplication.
  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
    return false;

  // MultLo amd MultHi must be the first and second output of MultNode
  // respectively.
  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
    return false;

  // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
  // of the values of MultNode, in which case MultNode will be removed in later
  // phases.
  // If there exist users other than SUBENode or SUBCNode, this function returns
  // here, which will result in MultNode being mapped to a single MULT
  // instruction node rather than a pair of MULT and MSUB instructions being
  // produced.
  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
    return false;

  SDLoc DL(SUBENode);

  // Initialize accumulator.
  SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
                                  SUBCNode->getOperand(0),
                                  SUBENode->getOperand(0));

  // create MipsSub(u) node
  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;

  SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
                                 MultNode->getOperand(0),// Factor 0
                                 MultNode->getOperand(1),// Factor 1
                                 ACCIn);

  // replace uses of sube and subc here
  if (!SDValue(SUBCNode, 0).use_empty()) {
    SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
    SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
                                    LoIdx);
    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
  }
  if (!SDValue(SUBENode, 0).use_empty()) {
    SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
    SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
                                    HiIdx);
    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
  }

  return true;
}