[llvm] r177089 - [mips] Define two subclasses of MipsDAGToDAGISel. Mips16DAGToDAGISel is for

David Blaikie dblaikie at gmail.com
Thu Mar 14 16:13:02 PDT 2013


This commit added a few unused variables which breaks the Clang
-Werror build many of us depend on. I've removed them in r177129.
(please review to ensure these weren't meant to be used somewhere,
etc)

In future you might want to use Clang for your development & enable
the -Werror build in your chosen build system (both the configure and
cmake builds support a flag for enabling -Werror in the build)

- David

On Thu, Mar 14, 2013 at 11:27 AM, Akira Hatanaka <ahatanaka at mips.com> wrote:
> Author: ahatanak
> Date: Thu Mar 14 13:27:31 2013
> New Revision: 177089
>
> URL: http://llvm.org/viewvc/llvm-project?rev=177089&view=rev
> Log:
> [mips] Define two subclasses of MipsDAGToDAGISel. Mips16DAGToDAGISel is for
> mips16 and MipsSEDAGToDAGISel is for mips32/64.
>
> No functionality changes.
>
>
> Added:
>     llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
>     llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h
>     llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
>     llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h
> Modified:
>     llvm/trunk/lib/Target/Mips/CMakeLists.txt
>     llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
>
> Modified: llvm/trunk/lib/Target/Mips/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/CMakeLists.txt?rev=177089&r1=177088&r2=177089&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/Mips/CMakeLists.txt Thu Mar 14 13:27:31 2013
> @@ -16,7 +16,7 @@ add_public_tablegen_target(MipsCommonTab
>  add_llvm_target(MipsCodeGen
>    Mips16FrameLowering.cpp
>    Mips16InstrInfo.cpp
> -  Mips16ISelLowering.cpp
> +  Mips16ISelDAGToDAG.cpp
>    Mips16RegisterInfo.cpp
>    MipsAnalyzeImmediate.cpp
>    MipsAsmPrinter.cpp
> @@ -34,7 +34,7 @@ add_llvm_target(MipsCodeGen
>    MipsRegisterInfo.cpp
>    MipsSEFrameLowering.cpp
>    MipsSEInstrInfo.cpp
> -  MipsSEISelLowering.cpp
> +  MipsSEISelDAGToDAG.cpp
>    MipsSERegisterInfo.cpp
>    MipsSubtarget.cpp
>    MipsTargetMachine.cpp
>
> Added: llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp?rev=177089&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp (added)
> +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp Thu Mar 14 13:27:31 2013
> @@ -0,0 +1,308 @@
> +//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// Subclass of MipsDAGToDAGISel specialized for mips16.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#define DEBUG_TYPE "mips-isel"
> +#include "Mips16ISelDAGToDAG.h"
> +#include "Mips.h"
> +#include "MCTargetDesc/MipsBaseInfo.h"
> +#include "MipsAnalyzeImmediate.h"
> +#include "MipsMachineFunction.h"
> +#include "MipsRegisterInfo.h"
> +#include "llvm/CodeGen/MachineConstantPool.h"
> +#include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/SelectionDAGNodes.h"
> +#include "llvm/IR/GlobalValue.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/IR/Intrinsics.h"
> +#include "llvm/IR/Type.h"
> +#include "llvm/Support/CFG.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Target/TargetMachine.h"
> +using namespace llvm;
> +
> +/// Select multiply instructions.
> +std::pair<SDNode*, SDNode*>
> +Mips16DAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
> +                               bool HasLo, bool HasHi) {
> +  SDNode *Lo = 0, *Hi = 0;
> +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),
> +                                       N->getOperand(1));
> +  SDValue InFlag = SDValue(Mul, 0);
> +
> +  if (HasLo) {
> +    unsigned Opcode = Mips::Mflo16;
> +    Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);
> +    InFlag = SDValue(Lo, 1);
> +  }
> +  if (HasHi) {
> +    unsigned Opcode = Mips::Mfhi16;
> +    Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);
> +  }
> +  return std::make_pair(Lo, Hi);
> +}
> +
> +void Mips16DAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
> +
> +  if (!MipsFI->globalBaseRegSet())
> +    return;
> +
> +  MachineBasicBlock &MBB = MF.front();
> +  MachineBasicBlock::iterator I = MBB.begin();
> +  MachineRegisterInfo &RegInfo = MF.getRegInfo();
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
> +  unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();
> +  const TargetRegisterClass *RC =
> +    (const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
> +
> +  V0 = RegInfo.createVirtualRegister(RC);
> +  V1 = RegInfo.createVirtualRegister(RC);
> +  V2 = RegInfo.createVirtualRegister(RC);
> +
> +  BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)
> +    .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
> +  BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)
> +    .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
> +  BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
> +  BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
> +    .addReg(V1).addReg(V2);
> +}
> +
> +// Insert instructions to initialize the Mips16 SP Alias register in the
> +// first MBB of the function.
> +//
> +void Mips16DAGToDAGISel::InitMips16SPAliasReg(MachineFunction &MF) {
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
> +
> +  if (!MipsFI->mips16SPAliasRegSet())
> +    return;
> +
> +  MachineBasicBlock &MBB = MF.front();
> +  MachineBasicBlock::iterator I = MBB.begin();
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
> +  unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg();
> +
> +  BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg)
> +    .addReg(Mips::SP);
> +}
> +
> +void Mips16DAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) {
> +  InitGlobalBaseReg(MF);
> +  InitMips16SPAliasReg(MF);
> +}
> +
> +/// getMips16SPAliasReg - Output the instructions required to put the
> +/// SP into a Mips16 accessible aliased register.
> +SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() {
> +  unsigned Mips16SPAliasReg =
> +    MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg();
> +  return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy());
> +}
> +
> +void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {
> +  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy());
> +  if (Parent) {
> +    switch (Parent->getOpcode()) {
> +      case ISD::LOAD: {
> +        LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent);
> +        switch (SD->getMemoryVT().getSizeInBits()) {
> +        case 8:
> +        case 16:
> +          AliasReg = TM.getFrameLowering()->hasFP(*MF)?
> +            AliasFPReg: getMips16SPAliasReg();
> +          return;
> +        }
> +        break;
> +      }
> +      case ISD::STORE: {
> +        StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent);
> +        switch (SD->getMemoryVT().getSizeInBits()) {
> +        case 8:
> +        case 16:
> +          AliasReg = TM.getFrameLowering()->hasFP(*MF)?
> +            AliasFPReg: getMips16SPAliasReg();
> +          return;
> +        }
> +        break;
> +      }
> +    }
> +  }
> +  AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy());
> +  return;
> +
> +}
> +
> +bool Mips16DAGToDAGISel::SelectAddr16(
> +  SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset,
> +  SDValue &Alias) {
> +  EVT ValTy = Addr.getValueType();
> +
> +  Alias = CurDAG->getTargetConstant(0, ValTy);
> +
> +  // if Address is FI, get the TargetFrameIndex.
> +  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
> +    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> +    Offset = CurDAG->getTargetConstant(0, ValTy);
> +    getMips16SPRefReg(Parent, Alias);
> +    return true;
> +  }
> +  // on PIC code Load GA
> +  if (Addr.getOpcode() == MipsISD::Wrapper) {
> +    Base   = Addr.getOperand(0);
> +    Offset = Addr.getOperand(1);
> +    return true;
> +  }
> +  if (TM.getRelocationModel() != Reloc::PIC_) {
> +    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
> +        Addr.getOpcode() == ISD::TargetGlobalAddress))
> +      return false;
> +  }
> +  // Addresses of the form FI+const or FI|const
> +  if (CurDAG->isBaseWithConstantOffset(Addr)) {
> +    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
> +    if (isInt<16>(CN->getSExtValue())) {
> +
> +      // If the first operand is a FI, get the TargetFI Node
> +      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
> +                                  (Addr.getOperand(0))) {
> +        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> +        getMips16SPRefReg(Parent, Alias);
> +      }
> +      else
> +        Base = Addr.getOperand(0);
> +
> +      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
> +      return true;
> +    }
> +  }
> +  // Operand is a result from an ADD.
> +  if (Addr.getOpcode() == ISD::ADD) {
> +    // When loading from constant pools, load the lower address part in
> +    // the instruction itself. Example, instead of:
> +    //  lui $2, %hi($CPI1_0)
> +    //  addiu $2, $2, %lo($CPI1_0)
> +    //  lwc1 $f0, 0($2)
> +    // Generate:
> +    //  lui $2, %hi($CPI1_0)
> +    //  lwc1 $f0, %lo($CPI1_0)($2)
> +    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
> +        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
> +      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
> +      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
> +          isa<JumpTableSDNode>(Opnd0)) {
> +        Base = Addr.getOperand(0);
> +        Offset = Opnd0;
> +        return true;
> +      }
> +    }
> +
> +    // If an indexed floating point load/store can be emitted, return false.
> +    const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);
> +
> +    if (LS &&
> +        (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) &&
> +        Subtarget.hasFPIdx())
> +      return false;
> +  }
> +  Base   = Addr;
> +  Offset = CurDAG->getTargetConstant(0, ValTy);
> +  return true;
> +}
> +
> +/// Select instructions not customized! Used for
> +/// expanded, promoted and normal instructions
> +std::pair<bool, SDNode*> Mips16DAGToDAGISel::SelectNode(SDNode *Node) {
> +  unsigned Opcode = Node->getOpcode();
> +  DebugLoc dl = Node->getDebugLoc();
> +
> +  ///
> +  // Instruction Selection not handled by the auto-generated
> +  // tablegen selection should be handled here.
> +  ///
> +  EVT NodeTy = Node->getValueType(0);
> +  unsigned MultOpc;
> +
> +  switch(Opcode) {
> +  default: break;
> +
> +  case ISD::SUBE:
> +  case ISD::ADDE: {
> +    SDValue InFlag = Node->getOperand(2), CmpLHS;
> +    unsigned Opc = InFlag.getOpcode(); (void)Opc;
> +    assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
> +            (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
> +           "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
> +
> +    unsigned MOp;
> +    if (Opcode == ISD::ADDE) {
> +      CmpLHS = InFlag.getValue(0);
> +      MOp = Mips::AdduRxRyRz16;
> +    } else {
> +      CmpLHS = InFlag.getOperand(0);
> +      MOp = Mips::SubuRxRyRz16;
> +    }
> +
> +    SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
> +
> +    SDValue LHS = Node->getOperand(0);
> +    SDValue RHS = Node->getOperand(1);
> +
> +    EVT VT = LHS.getValueType();
> +
> +    unsigned Sltu_op = Mips::SltuRxRyRz16;
> +    SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);
> +    unsigned Addu_op = Mips::AdduRxRyRz16;
> +    SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,
> +                                              SDValue(Carry,0), RHS);
> +
> +    SDNode *Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
> +                                          SDValue(AddCarry,0));
> +    return std::make_pair(true, Result);
> +  }
> +
> +  /// Mul with two results
> +  case ISD::SMUL_LOHI:
> +  case ISD::UMUL_LOHI: {
> +    MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : Mips::MultRxRy16);
> +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,
> +                                                  true, true);
> +    if (!SDValue(Node, 0).use_empty())
> +      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
> +
> +    if (!SDValue(Node, 1).use_empty())
> +      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
> +
> +    return std::make_pair(true, (SDNode*)NULL);
> +  }
> +
> +  case ISD::MULHS:
> +  case ISD::MULHU: {
> +    MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16);
> +    SDNode *Result = SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;
> +    return std::make_pair(true, Result);
> +  }
> +  }
> +
> +  return std::make_pair(false, (SDNode*)NULL);
> +}
> +
> +FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM) {
> +  return new Mips16DAGToDAGISel(TM);
> +}
>
> Added: llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h?rev=177089&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h (added)
> +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h Thu Mar 14 13:27:31 2013
> @@ -0,0 +1,51 @@
> +//===---- Mips16ISelDAGToDAG.h - A Dag to Dag Inst Selector for Mips ------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// Subclass of MipsDAGToDAGISel specialized for mips16.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef MIPS16ISELDAGTODAG_H
> +#define MIPS16ISELDAGTODAG_H
> +
> +#include "MipsISelDAGToDAG.h"
> +
> +namespace llvm {
> +
> +class Mips16DAGToDAGISel : public MipsDAGToDAGISel {
> +public:
> +  explicit Mips16DAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {}
> +
> +private:
> +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,
> +                                         EVT Ty, bool HasLo, bool HasHi);
> +
> +  SDValue getMips16SPAliasReg();
> +
> +  void getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg);
> +
> +  virtual bool SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
> +                            SDValue &Offset, SDValue &Alias);
> +
> +  virtual std::pair<bool, SDNode*> SelectNode(SDNode *Node);
> +
> +  virtual void ProcessFunctionAfterISel(MachineFunction &MF);
> +
> +  // Insert instructions to initialize the global base register in the
> +  // first MBB of the function.
> +  void InitGlobalBaseReg(MachineFunction &MF);
> +
> +  void InitMips16SPAliasReg(MachineFunction &MF);
> +};
> +
> +FunctionPass *createMips16ISelDag(MipsTargetMachine &TM);
> +
> +}
> +
> +#endif
>
> Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=177089&r1=177088&r2=177089&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Thu Mar 14 13:27:31 2013
> @@ -12,19 +12,19 @@
>  //===----------------------------------------------------------------------===//
>
>  #define DEBUG_TYPE "mips-isel"
> +#include "MipsISelDAGToDAG.h"
> +#include "Mips16ISelDAGToDAG.h"
> +#include "MipsSEISelDAGToDAG.h"
>  #include "Mips.h"
>  #include "MCTargetDesc/MipsBaseInfo.h"
>  #include "MipsAnalyzeImmediate.h"
>  #include "MipsMachineFunction.h"
>  #include "MipsRegisterInfo.h"
> -#include "MipsSubtarget.h"
> -#include "MipsTargetMachine.h"
>  #include "llvm/CodeGen/MachineConstantPool.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/CodeGen/SelectionDAGNodes.h"
>  #include "llvm/IR/GlobalValue.h"
>  #include "llvm/IR/Instructions.h"
> @@ -45,265 +45,6 @@ using namespace llvm;
>  // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
>  // instructions for SelectionDAG operations.
>  //===----------------------------------------------------------------------===//
> -namespace {
> -
> -class MipsDAGToDAGISel : public SelectionDAGISel {
> -
> -  /// TM - Keep a reference to MipsTargetMachine.
> -  MipsTargetMachine &TM;
> -
> -  /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
> -  /// make the right decision when generating code for different targets.
> -  const MipsSubtarget &Subtarget;
> -
> -public:
> -  explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
> -  SelectionDAGISel(tm),
> -  TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
> -
> -  // Pass Name
> -  virtual const char *getPassName() const {
> -    return "MIPS DAG->DAG Pattern Instruction Selection";
> -  }
> -
> -  virtual bool runOnMachineFunction(MachineFunction &MF);
> -
> -private:
> -  // Include the pieces autogenerated from the target description.
> -  #include "MipsGenDAGISel.inc"
> -
> -  /// getTargetMachine - Return a reference to the TargetMachine, casted
> -  /// to the target-specific type.
> -  const MipsTargetMachine &getTargetMachine() {
> -    return static_cast<const MipsTargetMachine &>(TM);
> -  }
> -
> -  /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
> -  /// to the target-specific type.
> -  const MipsInstrInfo *getInstrInfo() {
> -    return getTargetMachine().getInstrInfo();
> -  }
> -
> -  SDNode *getGlobalBaseReg();
> -
> -  SDValue getMips16SPAliasReg();
> -
> -  void getMips16SPRefReg(SDNode *parent, SDValue &AliasReg);
> -
> -  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,
> -                                         EVT Ty, bool HasLo, bool HasHi);
> -
> -  SDNode *Select(SDNode *N);
> -
> -  // Complex Pattern.
> -  /// (reg + imm).
> -  bool selectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) const;
> -
> -  /// Fall back on this function if all else fails.
> -  bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const;
> -
> -  /// Match integer address pattern.
> -  bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const;
> -
> -  bool SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset,
> -       SDValue &Alias);
> -
> -  // getImm - Return a target constant with the specified value.
> -  inline SDValue getImm(const SDNode *Node, uint64_t Imm) {
> -    return CurDAG->getTargetConstant(Imm, Node->getValueType(0));
> -  }
> -
> -  void ProcessFunctionAfterISel(MachineFunction &MF);
> -  bool ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&);
> -  void InitGlobalBaseReg(MachineFunction &MF);
> -  void InitMips16SPAliasReg(MachineFunction &MF);
> -
> -  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
> -                                            char ConstraintCode,
> -                                            std::vector<SDValue> &OutOps);
> -};
> -
> -}
> -
> -// Insert instructions to initialize the global base register in the
> -// first MBB of the function. When the ABI is O32 and the relocation model is
> -// PIC, the necessary instructions are emitted later to prevent optimization
> -// passes from moving them.
> -void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
> -  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
> -
> -  if (!MipsFI->globalBaseRegSet())
> -    return;
> -
> -  MachineBasicBlock &MBB = MF.front();
> -  MachineBasicBlock::iterator I = MBB.begin();
> -  MachineRegisterInfo &RegInfo = MF.getRegInfo();
> -  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> -  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
> -  unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();
> -  const TargetRegisterClass *RC;
> -
> -  if (Subtarget.isABI_N64())
> -    RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass;
> -  else if (Subtarget.inMips16Mode())
> -    RC = (const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
> -  else
> -    RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass;
> -
> -  V0 = RegInfo.createVirtualRegister(RC);
> -  V1 = RegInfo.createVirtualRegister(RC);
> -  V2 = RegInfo.createVirtualRegister(RC);
> -
> -  if (Subtarget.isABI_N64()) {
> -    MF.getRegInfo().addLiveIn(Mips::T9_64);
> -    MBB.addLiveIn(Mips::T9_64);
> -
> -    // lui $v0, %hi(%neg(%gp_rel(fname)))
> -    // daddu $v1, $v0, $t9
> -    // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
> -    const GlobalValue *FName = MF.getFunction();
> -    BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
> -      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
> -    BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
> -      .addReg(Mips::T9_64);
> -    BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
> -      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
> -    return;
> -  }
> -
> -  if (Subtarget.inMips16Mode()) {
> -    BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)
> -      .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
> -    BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)
> -      .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
> -    BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
> -    BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
> -      .addReg(V1).addReg(V2);
> -    return;
> -  }
> -
> -  if (MF.getTarget().getRelocationModel() == Reloc::Static) {
> -    // Set global register to __gnu_local_gp.
> -    //
> -    // lui   $v0, %hi(__gnu_local_gp)
> -    // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
> -    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
> -      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
> -    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
> -      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
> -    return;
> -  }
> -
> -  MF.getRegInfo().addLiveIn(Mips::T9);
> -  MBB.addLiveIn(Mips::T9);
> -
> -  if (Subtarget.isABI_N32()) {
> -    // lui $v0, %hi(%neg(%gp_rel(fname)))
> -    // addu $v1, $v0, $t9
> -    // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
> -    const GlobalValue *FName = MF.getFunction();
> -    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
> -      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
> -    BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
> -    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
> -      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
> -    return;
> -  }
> -
> -  assert(Subtarget.isABI_O32());
> -
> -  // For O32 ABI, the following instruction sequence is emitted to initialize
> -  // the global base register:
> -  //
> -  //  0. lui   $2, %hi(_gp_disp)
> -  //  1. addiu $2, $2, %lo(_gp_disp)
> -  //  2. addu  $globalbasereg, $2, $t9
> -  //
> -  // We emit only the last instruction here.
> -  //
> -  // GNU linker requires that the first two instructions appear at the beginning
> -  // of a function and no instructions be inserted before or between them.
> -  // The two instructions are emitted during lowering to MC layer in order to
> -  // avoid any reordering.
> -  //
> -  // Register $2 (Mips::V0) is added to the list of live-in registers to ensure
> -  // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
> -  // reads it.
> -  MF.getRegInfo().addLiveIn(Mips::V0);
> -  MBB.addLiveIn(Mips::V0);
> -  BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
> -    .addReg(Mips::V0).addReg(Mips::T9);
> -}
> -
> -// Insert instructions to initialize the Mips16 SP Alias register in the
> -// first MBB of the function.
> -//
> -void MipsDAGToDAGISel::InitMips16SPAliasReg(MachineFunction &MF) {
> -  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
> -
> -  if (!MipsFI->mips16SPAliasRegSet())
> -    return;
> -
> -  MachineBasicBlock &MBB = MF.front();
> -  MachineBasicBlock::iterator I = MBB.begin();
> -  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> -  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
> -  unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg();
> -
> -  BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg)
> -    .addReg(Mips::SP);
> -}
> -
> -
> -bool MipsDAGToDAGISel::ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI,
> -                                              const MachineInstr& MI) {
> -  unsigned DstReg = 0, ZeroReg = 0;
> -
> -  // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".
> -  if ((MI.getOpcode() == Mips::ADDiu) &&
> -      (MI.getOperand(1).getReg() == Mips::ZERO) &&
> -      (MI.getOperand(2).getImm() == 0)) {
> -    DstReg = MI.getOperand(0).getReg();
> -    ZeroReg = Mips::ZERO;
> -  } else if ((MI.getOpcode() == Mips::DADDiu) &&
> -             (MI.getOperand(1).getReg() == Mips::ZERO_64) &&
> -             (MI.getOperand(2).getImm() == 0)) {
> -    DstReg = MI.getOperand(0).getReg();
> -    ZeroReg = Mips::ZERO_64;
> -  }
> -
> -  if (!DstReg)
> -    return false;
> -
> -  // Replace uses with ZeroReg.
> -  for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg),
> -       E = MRI->use_end(); U != E;) {
> -    MachineOperand &MO = U.getOperand();
> -    unsigned OpNo = U.getOperandNo();
> -    MachineInstr *MI = MO.getParent();
> -    ++U;
> -
> -    // Do not replace if it is a phi's operand or is tied to def operand.
> -    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())
> -      continue;
> -
> -    MO.setReg(ZeroReg);
> -  }
> -
> -  return true;
> -}
> -
> -void MipsDAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) {
> -  InitGlobalBaseReg(MF);
> -  InitMips16SPAliasReg(MF);
> -
> -  MachineRegisterInfo *MRI = &MF.getRegInfo();
> -
> -  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE;
> -       ++MFI)
> -    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I)
> -      ReplaceUsesWithZeroReg(MRI, *I);
> -}
>
>  bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
>    bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
> @@ -320,233 +61,38 @@ SDNode *MipsDAGToDAGISel::getGlobalBaseR
>    return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
>  }
>
> -/// getMips16SPAliasReg - Output the instructions required to put the
> -/// SP into a Mips16 accessible aliased register.
> -SDValue MipsDAGToDAGISel::getMips16SPAliasReg() {
> -  unsigned Mips16SPAliasReg =
> -    MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg();
> -  return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy());
> -}
> -
>  /// ComplexPattern used on MipsInstrInfo
>  /// Used on Mips Load/Store instructions
>  bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
>                                          SDValue &Offset) const {
> -  EVT ValTy = Addr.getValueType();
> -
> -  // if Address is FI, get the TargetFrameIndex.
> -  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
> -    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> -    Offset = CurDAG->getTargetConstant(0, ValTy);
> -    return true;
> -  }
> -
> -  // on PIC code Load GA
> -  if (Addr.getOpcode() == MipsISD::Wrapper) {
> -    Base   = Addr.getOperand(0);
> -    Offset = Addr.getOperand(1);
> -    return true;
> -  }
> -
> -  if (TM.getRelocationModel() != Reloc::PIC_) {
> -    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
> -        Addr.getOpcode() == ISD::TargetGlobalAddress))
> -      return false;
> -  }
> -
> -  // Addresses of the form FI+const or FI|const
> -  if (CurDAG->isBaseWithConstantOffset(Addr)) {
> -    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
> -    if (isInt<16>(CN->getSExtValue())) {
> -
> -      // If the first operand is a FI, get the TargetFI Node
> -      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
> -                                  (Addr.getOperand(0)))
> -        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> -      else
> -        Base = Addr.getOperand(0);
> -
> -      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
> -      return true;
> -    }
> -  }
> -
> -  // Operand is a result from an ADD.
> -  if (Addr.getOpcode() == ISD::ADD) {
> -    // When loading from constant pools, load the lower address part in
> -    // the instruction itself. Example, instead of:
> -    //  lui $2, %hi($CPI1_0)
> -    //  addiu $2, $2, %lo($CPI1_0)
> -    //  lwc1 $f0, 0($2)
> -    // Generate:
> -    //  lui $2, %hi($CPI1_0)
> -    //  lwc1 $f0, %lo($CPI1_0)($2)
> -    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
> -        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
> -      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
> -      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
> -          isa<JumpTableSDNode>(Opnd0)) {
> -        Base = Addr.getOperand(0);
> -        Offset = Opnd0;
> -        return true;
> -      }
> -    }
> -  }
> -
> +  llvm_unreachable("Unimplemented function.");
>    return false;
>  }
>
>  bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
>                                           SDValue &Offset) const {
> -  Base = Addr;
> -  Offset = CurDAG->getTargetConstant(0, Addr.getValueType());
> -  return true;
> +  llvm_unreachable("Unimplemented function.");
> +  return false;
>  }
>
>  bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
>                                       SDValue &Offset) const {
> -  return selectAddrRegImm(Addr, Base, Offset) ||
> -    selectAddrDefault(Addr, Base, Offset);
> -}
> -
> -void MipsDAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {
> -  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy());
> -  if (Parent) {
> -    switch (Parent->getOpcode()) {
> -      case ISD::LOAD: {
> -        LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent);
> -        switch (SD->getMemoryVT().getSizeInBits()) {
> -        case 8:
> -        case 16:
> -          AliasReg = TM.getFrameLowering()->hasFP(*MF)?
> -            AliasFPReg: getMips16SPAliasReg();
> -          return;
> -        }
> -        break;
> -      }
> -      case ISD::STORE: {
> -        StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent);
> -        switch (SD->getMemoryVT().getSizeInBits()) {
> -        case 8:
> -        case 16:
> -          AliasReg = TM.getFrameLowering()->hasFP(*MF)?
> -            AliasFPReg: getMips16SPAliasReg();
> -          return;
> -        }
> -        break;
> -      }
> -    }
> -  }
> -  AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy());
> -  return;
> -
> -}
> -bool MipsDAGToDAGISel::SelectAddr16(
> -  SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset,
> -  SDValue &Alias) {
> -  EVT ValTy = Addr.getValueType();
> -
> -  Alias = CurDAG->getTargetConstant(0, ValTy);
> -
> -  // if Address is FI, get the TargetFrameIndex.
> -  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
> -    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> -    Offset = CurDAG->getTargetConstant(0, ValTy);
> -    getMips16SPRefReg(Parent, Alias);
> -    return true;
> -  }
> -  // on PIC code Load GA
> -  if (Addr.getOpcode() == MipsISD::Wrapper) {
> -    Base   = Addr.getOperand(0);
> -    Offset = Addr.getOperand(1);
> -    return true;
> -  }
> -  if (TM.getRelocationModel() != Reloc::PIC_) {
> -    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
> -        Addr.getOpcode() == ISD::TargetGlobalAddress))
> -      return false;
> -  }
> -  // Addresses of the form FI+const or FI|const
> -  if (CurDAG->isBaseWithConstantOffset(Addr)) {
> -    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
> -    if (isInt<16>(CN->getSExtValue())) {
> -
> -      // If the first operand is a FI, get the TargetFI Node
> -      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
> -                                  (Addr.getOperand(0))) {
> -        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> -        getMips16SPRefReg(Parent, Alias);
> -      }
> -      else
> -        Base = Addr.getOperand(0);
> -
> -      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
> -      return true;
> -    }
> -  }
> -  // Operand is a result from an ADD.
> -  if (Addr.getOpcode() == ISD::ADD) {
> -    // When loading from constant pools, load the lower address part in
> -    // the instruction itself. Example, instead of:
> -    //  lui $2, %hi($CPI1_0)
> -    //  addiu $2, $2, %lo($CPI1_0)
> -    //  lwc1 $f0, 0($2)
> -    // Generate:
> -    //  lui $2, %hi($CPI1_0)
> -    //  lwc1 $f0, %lo($CPI1_0)($2)
> -    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
> -        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
> -      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
> -      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
> -          isa<JumpTableSDNode>(Opnd0)) {
> -        Base = Addr.getOperand(0);
> -        Offset = Opnd0;
> -        return true;
> -      }
> -    }
> -
> -    // If an indexed floating point load/store can be emitted, return false.
> -    const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);
> -
> -    if (LS &&
> -        (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) &&
> -        Subtarget.hasFPIdx())
> -      return false;
> -  }
> -  Base   = Addr;
> -  Offset = CurDAG->getTargetConstant(0, ValTy);
> -  return true;
> +  llvm_unreachable("Unimplemented function.");
> +  return false;
>  }
>
> -/// Select multiply instructions.
> -std::pair<SDNode*, SDNode*>
> -MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
> -                             bool HasLo, bool HasHi) {
> -  SDNode *Lo = 0, *Hi = 0;
> -  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),
> -                                       N->getOperand(1));
> -  SDValue InFlag = SDValue(Mul, 0);
> -
> -  if (HasLo) {
> -    unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mflo16 :
> -      (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
> -    Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);
> -    InFlag = SDValue(Lo, 1);
> -  }
> -  if (HasHi) {
> -    unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mfhi16 :
> -      (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64);
> -    Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);
> -  }
> -  return std::make_pair(Lo, Hi);
> +bool MipsDAGToDAGISel::SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
> +                                    SDValue &Offset, SDValue &Alias) {
> +  llvm_unreachable("Unimplemented function.");
> +  return false;
>  }
>
> -
>  /// Select instructions not customized! Used for
>  /// expanded, promoted and normal instructions
>  SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
>    unsigned Opcode = Node->getOpcode();
>    DebugLoc dl = Node->getDebugLoc();
> +  EVT NodeTy = Node->getValueType(0);
>
>    // Dump information about the Node being selected
>    DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
> @@ -557,167 +103,19 @@ SDNode* MipsDAGToDAGISel::Select(SDNode
>      return NULL;
>    }
>
> -  ///
> -  // Instruction Selection not handled by the auto-generated
> -  // tablegen selection should be handled here.
> -  ///
> -  EVT NodeTy = Node->getValueType(0);
> -  unsigned MultOpc;
> +  // See if subclasses can handle this node.
> +  std::pair<bool, SDNode*> Ret = SelectNode(Node);
> +
> +  if (Ret.first)
> +    return Ret.second;
>
>    switch(Opcode) {
>    default: break;
>
> -  case ISD::SUBE:
> -  case ISD::ADDE: {
> -    bool inMips16Mode = Subtarget.inMips16Mode();
> -    SDValue InFlag = Node->getOperand(2), CmpLHS;
> -    unsigned Opc = InFlag.getOpcode(); (void)Opc;
> -    assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
> -            (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
> -           "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
> -
> -    unsigned MOp;
> -    if (Opcode == ISD::ADDE) {
> -      CmpLHS = InFlag.getValue(0);
> -      if (inMips16Mode)
> -        MOp = Mips::AdduRxRyRz16;
> -      else
> -        MOp = Mips::ADDu;
> -    } else {
> -      CmpLHS = InFlag.getOperand(0);
> -      if (inMips16Mode)
> -        MOp = Mips::SubuRxRyRz16;
> -      else
> -        MOp = Mips::SUBu;
> -    }
> -
> -    SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
> -
> -    SDValue LHS = Node->getOperand(0);
> -    SDValue RHS = Node->getOperand(1);
> -
> -    EVT VT = LHS.getValueType();
> -
> -    unsigned Sltu_op = inMips16Mode? Mips::SltuRxRyRz16: Mips::SLTu;
> -    SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);
> -    unsigned Addu_op = inMips16Mode? Mips::AdduRxRyRz16 : Mips::ADDu;
> -    SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,
> -                                              SDValue(Carry,0), RHS);
> -
> -    return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
> -                                LHS, SDValue(AddCarry,0));
> -  }
> -
> -  /// Mul with two results
> -  case ISD::SMUL_LOHI:
> -  case ISD::UMUL_LOHI: {
> -    if (NodeTy == MVT::i32) {
> -      if (Subtarget.inMips16Mode())
> -        MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 :
> -                   Mips::MultRxRy16);
> -      else
> -        MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
> -    }
> -    else
> -      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);
> -
> -    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,
> -                                                  true, true);
> -
> -    if (!SDValue(Node, 0).use_empty())
> -      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
> -
> -    if (!SDValue(Node, 1).use_empty())
> -      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
> -
> -    return NULL;
> -  }
> -
> -  /// Special Muls
> -  case ISD::MUL: {
> -    // Mips32 has a 32-bit three operand mul instruction.
> -    if (Subtarget.hasMips32() && NodeTy == MVT::i32)
> -      break;
> -    return SelectMULT(Node, NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT,
> -                      dl, NodeTy, true, false).first;
> -  }
> -  case ISD::MULHS:
> -  case ISD::MULHU: {
> -    if (NodeTy == MVT::i32) {
> -      if (Subtarget.inMips16Mode())
> -        MultOpc = (Opcode == ISD::MULHU ?
> -                   Mips::MultuRxRy16 : Mips::MultRxRy16);
> -      else
> -        MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
> -    }
> -    else
> -      MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);
> -
> -    return SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;
> -  }
> -
>    // Get target GOT address.
>    case ISD::GLOBAL_OFFSET_TABLE:
>      return getGlobalBaseReg();
>
> -  case ISD::ConstantFP: {
> -    ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
> -    if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
> -      if (Subtarget.hasMips64()) {
> -        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
> -                                              Mips::ZERO_64, MVT::i64);
> -        return CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64, Zero);
> -      }
> -
> -      SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
> -                                            Mips::ZERO, MVT::i32);
> -      return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,
> -                                    Zero);
> -    }
> -    break;
> -  }
> -
> -  case ISD::Constant: {
> -    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);
> -    unsigned Size = CN->getValueSizeInBits(0);
> -
> -    if (Size == 32)
> -      break;
> -
> -    MipsAnalyzeImmediate AnalyzeImm;
> -    int64_t Imm = CN->getSExtValue();
> -
> -    const MipsAnalyzeImmediate::InstSeq &Seq =
> -      AnalyzeImm.Analyze(Imm, Size, false);
> -
> -    MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
> -    DebugLoc DL = CN->getDebugLoc();
> -    SDNode *RegOpnd;
> -    SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
> -                                                MVT::i64);
> -
> -    // The first instruction can be a LUi which is different from other
> -    // instructions (ADDiu, ORI and SLL) in that it does not have a register
> -    // operand.
> -    if (Inst->Opc == Mips::LUi64)
> -      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
> -    else
> -      RegOpnd =
> -        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
> -                               CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
> -                               ImmOpnd);
> -
> -    // The remaining instructions in the sequence are handled here.
> -    for (++Inst; Inst != Seq.end(); ++Inst) {
> -      ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
> -                                          MVT::i64);
> -      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
> -                                       SDValue(RegOpnd, 0), ImmOpnd);
> -    }
> -
> -    return RegOpnd;
> -  }
> -
>  #ifndef NDEBUG
>    case ISD::LOAD:
>    case ISD::STORE:
> @@ -726,31 +124,6 @@ SDNode* MipsDAGToDAGISel::Select(SDNode
>             "Unexpected unaligned loads/stores.");
>      break;
>  #endif
> -
> -  case MipsISD::ThreadPointer: {
> -    EVT PtrVT = TLI.getPointerTy();
> -    unsigned RdhwrOpc, SrcReg, DestReg;
> -
> -    if (PtrVT == MVT::i32) {
> -      RdhwrOpc = Mips::RDHWR;
> -      SrcReg = Mips::HWR29;
> -      DestReg = Mips::V1;
> -    } else {
> -      RdhwrOpc = Mips::RDHWR64;
> -      SrcReg = Mips::HWR29_64;
> -      DestReg = Mips::V1_64;
> -    }
> -
> -    SDNode *Rdhwr =
> -      CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),
> -                             Node->getValueType(0),
> -                             CurDAG->getRegister(SrcReg, PtrVT));
> -    SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
> -                                         SDValue(Rdhwr, 0));
> -    SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT);
> -    ReplaceUses(SDValue(Node, 0), ResNode);
> -    return ResNode.getNode();
> -  }
>    }
>
>    // Select the default instruction
> @@ -776,5 +149,8 @@ SelectInlineAsmMemoryOperand(const SDVal
>  /// createMipsISelDag - This pass converts a legalized DAG into a
>  /// MIPS-specific DAG, ready for instruction scheduling.
>  FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
> -  return new MipsDAGToDAGISel(TM);
> +  if (TM.getSubtargetImpl()->inMips16Mode())
> +    return llvm::createMips16ISelDag(TM);
> +
> +  return llvm::createMipsSEISelDag(TM);
>  }
>
> Added: llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp?rev=177089&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp (added)
> +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp Thu Mar 14 13:27:31 2013
> @@ -0,0 +1,463 @@
> +//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// Subclass of MipsDAGToDAGISel specialized for mips32/64.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#define DEBUG_TYPE "mips-isel"
> +#include "MipsSEISelDAGToDAG.h"
> +#include "Mips.h"
> +#include "MCTargetDesc/MipsBaseInfo.h"
> +#include "MipsAnalyzeImmediate.h"
> +#include "MipsMachineFunction.h"
> +#include "MipsRegisterInfo.h"
> +#include "llvm/CodeGen/MachineConstantPool.h"
> +#include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/SelectionDAGNodes.h"
> +#include "llvm/IR/GlobalValue.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/IR/Intrinsics.h"
> +#include "llvm/IR/Type.h"
> +#include "llvm/Support/CFG.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Target/TargetMachine.h"
> +using namespace llvm;
> +
> +
> +bool MipsSEDAGToDAGISel::ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI,
> +                                                const MachineInstr& MI) {
> +  unsigned DstReg = 0, ZeroReg = 0;
> +
> +  // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".
> +  if ((MI.getOpcode() == Mips::ADDiu) &&
> +      (MI.getOperand(1).getReg() == Mips::ZERO) &&
> +      (MI.getOperand(2).getImm() == 0)) {
> +    DstReg = MI.getOperand(0).getReg();
> +    ZeroReg = Mips::ZERO;
> +  } else if ((MI.getOpcode() == Mips::DADDiu) &&
> +             (MI.getOperand(1).getReg() == Mips::ZERO_64) &&
> +             (MI.getOperand(2).getImm() == 0)) {
> +    DstReg = MI.getOperand(0).getReg();
> +    ZeroReg = Mips::ZERO_64;
> +  }
> +
> +  if (!DstReg)
> +    return false;
> +
> +  // Replace uses with ZeroReg.
> +  for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg),
> +       E = MRI->use_end(); U != E;) {
> +    MachineOperand &MO = U.getOperand();
> +    unsigned OpNo = U.getOperandNo();
> +    MachineInstr *MI = MO.getParent();
> +    ++U;
> +
> +    // Do not replace if it is a phi's operand or is tied to def operand.
> +    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())
> +      continue;
> +
> +    MO.setReg(ZeroReg);
> +  }
> +
> +  return true;
> +}
> +
> +void MipsSEDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
> +
> +  if (!MipsFI->globalBaseRegSet())
> +    return;
> +
> +  MachineBasicBlock &MBB = MF.front();
> +  MachineBasicBlock::iterator I = MBB.begin();
> +  MachineRegisterInfo &RegInfo = MF.getRegInfo();
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
> +  unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
> +  const TargetRegisterClass *RC;
> +
> +  if (Subtarget.isABI_N64())
> +    RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass;
> +  else
> +    RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass;
> +
> +  V0 = RegInfo.createVirtualRegister(RC);
> +  V1 = RegInfo.createVirtualRegister(RC);
> +
> +  if (Subtarget.isABI_N64()) {
> +    MF.getRegInfo().addLiveIn(Mips::T9_64);
> +    MBB.addLiveIn(Mips::T9_64);
> +
> +    // lui $v0, %hi(%neg(%gp_rel(fname)))
> +    // daddu $v1, $v0, $t9
> +    // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
> +    const GlobalValue *FName = MF.getFunction();
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
> +    BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
> +      .addReg(Mips::T9_64);
> +    BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
> +    return;
> +  }
> +
> +  if (MF.getTarget().getRelocationModel() == Reloc::Static) {
> +    // Set global register to __gnu_local_gp.
> +    //
> +    // lui   $v0, %hi(__gnu_local_gp)
> +    // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
> +      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
> +      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
> +    return;
> +  }
> +
> +  MF.getRegInfo().addLiveIn(Mips::T9);
> +  MBB.addLiveIn(Mips::T9);
> +
> +  if (Subtarget.isABI_N32()) {
> +    // lui $v0, %hi(%neg(%gp_rel(fname)))
> +    // addu $v1, $v0, $t9
> +    // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
> +    const GlobalValue *FName = MF.getFunction();
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
> +    return;
> +  }
> +
> +  assert(Subtarget.isABI_O32());
> +
> +  // For O32 ABI, the following instruction sequence is emitted to initialize
> +  // the global base register:
> +  //
> +  //  0. lui   $2, %hi(_gp_disp)
> +  //  1. addiu $2, $2, %lo(_gp_disp)
> +  //  2. addu  $globalbasereg, $2, $t9
> +  //
> +  // We emit only the last instruction here.
> +  //
> +  // GNU linker requires that the first two instructions appear at the beginning
> +  // of a function and no instructions be inserted before or between them.
> +  // The two instructions are emitted during lowering to MC layer in order to
> +  // avoid any reordering.
> +  //
> +  // Register $2 (Mips::V0) is added to the list of live-in registers to ensure
> +  // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
> +  // reads it.
> +  MF.getRegInfo().addLiveIn(Mips::V0);
> +  MBB.addLiveIn(Mips::V0);
> +  BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
> +    .addReg(Mips::V0).addReg(Mips::T9);
> +}
> +
> +void MipsSEDAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) {
> +  InitGlobalBaseReg(MF);
> +
> +  MachineRegisterInfo *MRI = &MF.getRegInfo();
> +
> +  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE;
> +       ++MFI)
> +    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I)
> +      ReplaceUsesWithZeroReg(MRI, *I);
> +}
> +
> +/// Select multiply instructions.
> +std::pair<SDNode*, SDNode*>
> +MipsSEDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
> +                               bool HasLo, bool HasHi) {
> +  SDNode *Lo = 0, *Hi = 0;
> +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),
> +                                       N->getOperand(1));
> +  SDValue InFlag = SDValue(Mul, 0);
> +
> +  if (HasLo) {
> +    unsigned Opcode = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
> +    Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);
> +    InFlag = SDValue(Lo, 1);
> +  }
> +  if (HasHi) {
> +    unsigned Opcode = (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64);
> +    Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);
> +  }
> +  return std::make_pair(Lo, Hi);
> +}
> +
> +/// ComplexPattern used on MipsInstrInfo
> +/// Used on Mips Load/Store instructions
> +bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
> +                                          SDValue &Offset) const {
> +  EVT ValTy = Addr.getValueType();
> +
> +  // if Address is FI, get the TargetFrameIndex.
> +  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
> +    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> +    Offset = CurDAG->getTargetConstant(0, ValTy);
> +    return true;
> +  }
> +
> +  // on PIC code Load GA
> +  if (Addr.getOpcode() == MipsISD::Wrapper) {
> +    Base   = Addr.getOperand(0);
> +    Offset = Addr.getOperand(1);
> +    return true;
> +  }
> +
> +  if (TM.getRelocationModel() != Reloc::PIC_) {
> +    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
> +        Addr.getOpcode() == ISD::TargetGlobalAddress))
> +      return false;
> +  }
> +
> +  // Addresses of the form FI+const or FI|const
> +  if (CurDAG->isBaseWithConstantOffset(Addr)) {
> +    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
> +    if (isInt<16>(CN->getSExtValue())) {
> +
> +      // If the first operand is a FI, get the TargetFI Node
> +      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
> +                                  (Addr.getOperand(0)))
> +        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
> +      else
> +        Base = Addr.getOperand(0);
> +
> +      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
> +      return true;
> +    }
> +  }
> +
> +  // Operand is a result from an ADD.
> +  if (Addr.getOpcode() == ISD::ADD) {
> +    // When loading from constant pools, load the lower address part in
> +    // the instruction itself. Example, instead of:
> +    //  lui $2, %hi($CPI1_0)
> +    //  addiu $2, $2, %lo($CPI1_0)
> +    //  lwc1 $f0, 0($2)
> +    // Generate:
> +    //  lui $2, %hi($CPI1_0)
> +    //  lwc1 $f0, %lo($CPI1_0)($2)
> +    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
> +        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
> +      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
> +      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
> +          isa<JumpTableSDNode>(Opnd0)) {
> +        Base = Addr.getOperand(0);
> +        Offset = Opnd0;
> +        return true;
> +      }
> +    }
> +  }
> +
> +  return false;
> +}
> +
> +bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
> +                                           SDValue &Offset) const {
> +  Base = Addr;
> +  Offset = CurDAG->getTargetConstant(0, Addr.getValueType());
> +  return true;
> +}
> +
> +bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
> +                                       SDValue &Offset) const {
> +  return selectAddrRegImm(Addr, Base, Offset) ||
> +    selectAddrDefault(Addr, Base, Offset);
> +}
> +
> +std::pair<bool, SDNode*> MipsSEDAGToDAGISel::SelectNode(SDNode *Node) {
> +  unsigned Opcode = Node->getOpcode();
> +  DebugLoc dl = Node->getDebugLoc();
> +
> +  ///
> +  // Instruction Selection not handled by the auto-generated
> +  // tablegen selection should be handled here.
> +  ///
> +  EVT NodeTy = Node->getValueType(0);
> +  SDNode *Result;
> +  unsigned MultOpc;
> +
> +  switch(Opcode) {
> +  default: break;
> +
> +  case ISD::SUBE:
> +  case ISD::ADDE: {
> +    SDValue InFlag = Node->getOperand(2), CmpLHS;
> +    unsigned Opc = InFlag.getOpcode(); (void)Opc;
> +    assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
> +            (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
> +           "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
> +
> +    unsigned MOp;
> +    if (Opcode == ISD::ADDE) {
> +      CmpLHS = InFlag.getValue(0);
> +      MOp = Mips::ADDu;
> +    } else {
> +      CmpLHS = InFlag.getOperand(0);
> +      MOp = Mips::SUBu;
> +    }
> +
> +    SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
> +
> +    SDValue LHS = Node->getOperand(0);
> +    SDValue RHS = Node->getOperand(1);
> +
> +    EVT VT = LHS.getValueType();
> +
> +    unsigned Sltu_op = Mips::SLTu;
> +    SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);
> +    unsigned Addu_op = Mips::ADDu;
> +    SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,
> +                                              SDValue(Carry,0), RHS);
> +
> +    Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
> +                                  SDValue(AddCarry,0));
> +    return std::make_pair(true, Result);
> +  }
> +
> +  /// Mul with two results
> +  case ISD::SMUL_LOHI:
> +  case ISD::UMUL_LOHI: {
> +    if (NodeTy == MVT::i32)
> +      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
> +    else
> +      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);
> +
> +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,
> +                                                  true, true);
> +
> +    if (!SDValue(Node, 0).use_empty())
> +      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
> +
> +    if (!SDValue(Node, 1).use_empty())
> +      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
> +
> +    return std::make_pair(true, (SDNode*)NULL);
> +  }
> +
> +  /// Special Muls
> +  case ISD::MUL: {
> +    // Mips32 has a 32-bit three operand mul instruction.
> +    if (Subtarget.hasMips32() && NodeTy == MVT::i32)
> +      break;
> +    MultOpc = NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT;
> +    Result = SelectMULT(Node, MultOpc, dl, NodeTy, true, false).first;
> +    return std::make_pair(true, Result);
> +  }
> +  case ISD::MULHS:
> +  case ISD::MULHU: {
> +    if (NodeTy == MVT::i32)
> +      MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
> +    else
> +      MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);
> +
> +    Result = SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;
> +    return std::make_pair(true, Result);
> +  }
> +
> +  case ISD::ConstantFP: {
> +    ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
> +    if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
> +      if (Subtarget.hasMips64()) {
> +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
> +                                              Mips::ZERO_64, MVT::i64);
> +        Result = CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64, Zero);
> +      } else {
> +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
> +                                              Mips::ZERO, MVT::i32);
> +        Result = CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,
> +                                        Zero);
> +      }
> +
> +      return std::make_pair(true, Result);
> +    }
> +    break;
> +  }
> +
> +  case ISD::Constant: {
> +    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);
> +    unsigned Size = CN->getValueSizeInBits(0);
> +
> +    if (Size == 32)
> +      break;
> +
> +    MipsAnalyzeImmediate AnalyzeImm;
> +    int64_t Imm = CN->getSExtValue();
> +
> +    const MipsAnalyzeImmediate::InstSeq &Seq =
> +      AnalyzeImm.Analyze(Imm, Size, false);
> +
> +    MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
> +    DebugLoc DL = CN->getDebugLoc();
> +    SDNode *RegOpnd;
> +    SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
> +                                                MVT::i64);
> +
> +    // The first instruction can be a LUi which is different from other
> +    // instructions (ADDiu, ORI and SLL) in that it does not have a register
> +    // operand.
> +    if (Inst->Opc == Mips::LUi64)
> +      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
> +    else
> +      RegOpnd =
> +        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
> +                               CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
> +                               ImmOpnd);
> +
> +    // The remaining instructions in the sequence are handled here.
> +    for (++Inst; Inst != Seq.end(); ++Inst) {
> +      ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
> +                                          MVT::i64);
> +      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
> +                                       SDValue(RegOpnd, 0), ImmOpnd);
> +    }
> +
> +    return std::make_pair(true, RegOpnd);
> +  }
> +
> +  case MipsISD::ThreadPointer: {
> +    EVT PtrVT = TLI.getPointerTy();
> +    unsigned RdhwrOpc, SrcReg, DestReg;
> +
> +    if (PtrVT == MVT::i32) {
> +      RdhwrOpc = Mips::RDHWR;
> +      SrcReg = Mips::HWR29;
> +      DestReg = Mips::V1;
> +    } else {
> +      RdhwrOpc = Mips::RDHWR64;
> +      SrcReg = Mips::HWR29_64;
> +      DestReg = Mips::V1_64;
> +    }
> +
> +    SDNode *Rdhwr =
> +      CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),
> +                             Node->getValueType(0),
> +                             CurDAG->getRegister(SrcReg, PtrVT));
> +    SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
> +                                         SDValue(Rdhwr, 0));
> +    SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT);
> +    ReplaceUses(SDValue(Node, 0), ResNode);
> +    return std::make_pair(true, ResNode.getNode());
> +  }
> +  }
> +
> +  return std::make_pair(false, (SDNode*)NULL);
> +}
> +
> +FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) {
> +  return new MipsSEDAGToDAGISel(TM);
> +}
>
> Added: llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h?rev=177089&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h (added)
> +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h Thu Mar 14 13:27:31 2013
> @@ -0,0 +1,54 @@
> +//===-- MipsSEISelDAGToDAG.h - A Dag to Dag Inst Selector for MipsSE -----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// Subclass of MipsDAGToDAGISel specialized for mips32/64.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef MIPSSEISELDAGTODAG_H
> +#define MIPSSEISELDAGTODAG_H
> +
> +#include "MipsISelDAGToDAG.h"
> +
> +namespace llvm {
> +
> +class MipsSEDAGToDAGISel : public MipsDAGToDAGISel {
> +
> +public:
> +  explicit MipsSEDAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {}
> +
> +private:
> +  bool ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&);
> +
> +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,
> +                                         EVT Ty, bool HasLo, bool HasHi);
> +
> +  virtual bool selectAddrRegImm(SDValue Addr, SDValue &Base,
> +                                SDValue &Offset) const;
> +
> +  virtual bool selectAddrDefault(SDValue Addr, SDValue &Base,
> +                                 SDValue &Offset) const;
> +
> +  virtual bool selectIntAddr(SDValue Addr, SDValue &Base,
> +                             SDValue &Offset) const;
> +
> +  virtual std::pair<bool, SDNode*> SelectNode(SDNode *Node);
> +
> +  virtual void ProcessFunctionAfterISel(MachineFunction &MF);
> +
> +  // Insert instructions to initialize the global base register in the
> +  // first MBB of the function.
> +  void InitGlobalBaseReg(MachineFunction &MF);
> +};
> +
> +FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM);
> +
> +}
> +
> +#endif
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list