These variables are not meant to be used anywhere and can be removed safely.<br><br>Do people normally build llvm once with clang or twice with clang and gcc?<br>I was wondering if there are cases where gcc correctly issues a warning but clang doesn't.<br>
<br><div class="gmail_quote">On Thu, Mar 14, 2013 at 4:13 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This commit added a few unused variables which breaks the Clang<br>
-Werror build many of us depend on. I've removed them in r177129.<br>
(please review to ensure these weren't meant to be used somewhere,<br>
etc)<br>
<br>
In future you might want to use Clang for your development & enable<br>
the -Werror build in your chosen build system (both the configure and<br>
cmake builds support a flag for enabling -Werror in the build)<br>
<span class="HOEnZb"><font color="#888888"><br>
- David<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On Thu, Mar 14, 2013 at 11:27 AM, Akira Hatanaka <<a href="mailto:ahatanaka@mips.com">ahatanaka@mips.com</a>> wrote:<br>
> Author: ahatanak<br>
> Date: Thu Mar 14 13:27:31 2013<br>
> New Revision: 177089<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=177089&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=177089&view=rev</a><br>
> Log:<br>
> [mips] Define two subclasses of MipsDAGToDAGISel. Mips16DAGToDAGISel is for<br>
> mips16 and MipsSEDAGToDAGISel is for mips32/64.<br>
><br>
> No functionality changes.<br>
><br>
><br>
> Added:<br>
>     llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp<br>
>     llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h<br>
>     llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp<br>
>     llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h<br>
> Modified:<br>
>     llvm/trunk/lib/Target/Mips/CMakeLists.txt<br>
>     llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp<br>
><br>
> Modified: llvm/trunk/lib/Target/Mips/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/CMakeLists.txt?rev=177089&r1=177088&r2=177089&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/CMakeLists.txt?rev=177089&r1=177088&r2=177089&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/Mips/CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/Target/Mips/CMakeLists.txt Thu Mar 14 13:27:31 2013<br>
> @@ -16,7 +16,7 @@ add_public_tablegen_target(MipsCommonTab<br>
>  add_llvm_target(MipsCodeGen<br>
>    Mips16FrameLowering.cpp<br>
>    Mips16InstrInfo.cpp<br>
> -  Mips16ISelLowering.cpp<br>
> +  Mips16ISelDAGToDAG.cpp<br>
>    Mips16RegisterInfo.cpp<br>
>    MipsAnalyzeImmediate.cpp<br>
>    MipsAsmPrinter.cpp<br>
> @@ -34,7 +34,7 @@ add_llvm_target(MipsCodeGen<br>
>    MipsRegisterInfo.cpp<br>
>    MipsSEFrameLowering.cpp<br>
>    MipsSEInstrInfo.cpp<br>
> -  MipsSEISelLowering.cpp<br>
> +  MipsSEISelDAGToDAG.cpp<br>
>    MipsSERegisterInfo.cpp<br>
>    MipsSubtarget.cpp<br>
>    MipsTargetMachine.cpp<br>
><br>
> Added: llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp?rev=177089&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp?rev=177089&view=auto</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp (added)<br>
> +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp Thu Mar 14 13:27:31 2013<br>
> @@ -0,0 +1,308 @@<br>
> +//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// Subclass of MipsDAGToDAGISel specialized for mips16.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#define DEBUG_TYPE "mips-isel"<br>
> +#include "Mips16ISelDAGToDAG.h"<br>
> +#include "Mips.h"<br>
> +#include "MCTargetDesc/MipsBaseInfo.h"<br>
> +#include "MipsAnalyzeImmediate.h"<br>
> +#include "MipsMachineFunction.h"<br>
> +#include "MipsRegisterInfo.h"<br>
> +#include "llvm/CodeGen/MachineConstantPool.h"<br>
> +#include "llvm/CodeGen/MachineFrameInfo.h"<br>
> +#include "llvm/CodeGen/MachineFunction.h"<br>
> +#include "llvm/CodeGen/MachineInstrBuilder.h"<br>
> +#include "llvm/CodeGen/MachineRegisterInfo.h"<br>
> +#include "llvm/CodeGen/SelectionDAGNodes.h"<br>
> +#include "llvm/IR/GlobalValue.h"<br>
> +#include "llvm/IR/Instructions.h"<br>
> +#include "llvm/IR/Intrinsics.h"<br>
> +#include "llvm/IR/Type.h"<br>
> +#include "llvm/Support/CFG.h"<br>
> +#include "llvm/Support/Debug.h"<br>
> +#include "llvm/Support/ErrorHandling.h"<br>
> +#include "llvm/Support/raw_ostream.h"<br>
> +#include "llvm/Target/TargetMachine.h"<br>
> +using namespace llvm;<br>
> +<br>
> +/// Select multiply instructions.<br>
> +std::pair<SDNode*, SDNode*><br>
> +Mips16DAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,<br>
> +                               bool HasLo, bool HasHi) {<br>
> +  SDNode *Lo = 0, *Hi = 0;<br>
> +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),<br>
> +                                       N->getOperand(1));<br>
> +  SDValue InFlag = SDValue(Mul, 0);<br>
> +<br>
> +  if (HasLo) {<br>
> +    unsigned Opcode = Mips::Mflo16;<br>
> +    Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);<br>
> +    InFlag = SDValue(Lo, 1);<br>
> +  }<br>
> +  if (HasHi) {<br>
> +    unsigned Opcode = Mips::Mfhi16;<br>
> +    Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);<br>
> +  }<br>
> +  return std::make_pair(Lo, Hi);<br>
> +}<br>
> +<br>
> +void Mips16DAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {<br>
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();<br>
> +<br>
> +  if (!MipsFI->globalBaseRegSet())<br>
> +    return;<br>
> +<br>
> +  MachineBasicBlock &MBB = MF.front();<br>
> +  MachineBasicBlock::iterator I = MBB.begin();<br>
> +  MachineRegisterInfo &RegInfo = MF.getRegInfo();<br>
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();<br>
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();<br>
> +  unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();<br>
> +  const TargetRegisterClass *RC =<br>
> +    (const TargetRegisterClass*)&Mips::CPU16RegsRegClass;<br>
> +<br>
> +  V0 = RegInfo.createVirtualRegister(RC);<br>
> +  V1 = RegInfo.createVirtualRegister(RC);<br>
> +  V2 = RegInfo.createVirtualRegister(RC);<br>
> +<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)<br>
> +    .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)<br>
> +    .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)<br>
> +    .addReg(V1).addReg(V2);<br>
> +}<br>
> +<br>
> +// Insert instructions to initialize the Mips16 SP Alias register in the<br>
> +// first MBB of the function.<br>
> +//<br>
> +void Mips16DAGToDAGISel::InitMips16SPAliasReg(MachineFunction &MF) {<br>
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();<br>
> +<br>
> +  if (!MipsFI->mips16SPAliasRegSet())<br>
> +    return;<br>
> +<br>
> +  MachineBasicBlock &MBB = MF.front();<br>
> +  MachineBasicBlock::iterator I = MBB.begin();<br>
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();<br>
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();<br>
> +  unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg();<br>
> +<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg)<br>
> +    .addReg(Mips::SP);<br>
> +}<br>
> +<br>
> +void Mips16DAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) {<br>
> +  InitGlobalBaseReg(MF);<br>
> +  InitMips16SPAliasReg(MF);<br>
> +}<br>
> +<br>
> +/// getMips16SPAliasReg - Output the instructions required to put the<br>
> +/// SP into a Mips16 accessible aliased register.<br>
> +SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() {<br>
> +  unsigned Mips16SPAliasReg =<br>
> +    MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg();<br>
> +  return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy());<br>
> +}<br>
> +<br>
> +void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {<br>
> +  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy());<br>
> +  if (Parent) {<br>
> +    switch (Parent->getOpcode()) {<br>
> +      case ISD::LOAD: {<br>
> +        LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent);<br>
> +        switch (SD->getMemoryVT().getSizeInBits()) {<br>
> +        case 8:<br>
> +        case 16:<br>
> +          AliasReg = TM.getFrameLowering()->hasFP(*MF)?<br>
> +            AliasFPReg: getMips16SPAliasReg();<br>
> +          return;<br>
> +        }<br>
> +        break;<br>
> +      }<br>
> +      case ISD::STORE: {<br>
> +        StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent);<br>
> +        switch (SD->getMemoryVT().getSizeInBits()) {<br>
> +        case 8:<br>
> +        case 16:<br>
> +          AliasReg = TM.getFrameLowering()->hasFP(*MF)?<br>
> +            AliasFPReg: getMips16SPAliasReg();<br>
> +          return;<br>
> +        }<br>
> +        break;<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +  AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy());<br>
> +  return;<br>
> +<br>
> +}<br>
> +<br>
> +bool Mips16DAGToDAGISel::SelectAddr16(<br>
> +  SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset,<br>
> +  SDValue &Alias) {<br>
> +  EVT ValTy = Addr.getValueType();<br>
> +<br>
> +  Alias = CurDAG->getTargetConstant(0, ValTy);<br>
> +<br>
> +  // if Address is FI, get the TargetFrameIndex.<br>
> +  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {<br>
> +    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);<br>
> +    Offset = CurDAG->getTargetConstant(0, ValTy);<br>
> +    getMips16SPRefReg(Parent, Alias);<br>
> +    return true;<br>
> +  }<br>
> +  // on PIC code Load GA<br>
> +  if (Addr.getOpcode() == MipsISD::Wrapper) {<br>
> +    Base   = Addr.getOperand(0);<br>
> +    Offset = Addr.getOperand(1);<br>
> +    return true;<br>
> +  }<br>
> +  if (TM.getRelocationModel() != Reloc::PIC_) {<br>
> +    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||<br>
> +        Addr.getOpcode() == ISD::TargetGlobalAddress))<br>
> +      return false;<br>
> +  }<br>
> +  // Addresses of the form FI+const or FI|const<br>
> +  if (CurDAG->isBaseWithConstantOffset(Addr)) {<br>
> +    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));<br>
> +    if (isInt<16>(CN->getSExtValue())) {<br>
> +<br>
> +      // If the first operand is a FI, get the TargetFI Node<br>
> +      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode><br>
> +                                  (Addr.getOperand(0))) {<br>
> +        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);<br>
> +        getMips16SPRefReg(Parent, Alias);<br>
> +      }<br>
> +      else<br>
> +        Base = Addr.getOperand(0);<br>
> +<br>
> +      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);<br>
> +      return true;<br>
> +    }<br>
> +  }<br>
> +  // Operand is a result from an ADD.<br>
> +  if (Addr.getOpcode() == ISD::ADD) {<br>
> +    // When loading from constant pools, load the lower address part in<br>
> +    // the instruction itself. Example, instead of:<br>
> +    //  lui $2, %hi($CPI1_0)<br>
> +    //  addiu $2, $2, %lo($CPI1_0)<br>
> +    //  lwc1 $f0, 0($2)<br>
> +    // Generate:<br>
> +    //  lui $2, %hi($CPI1_0)<br>
> +    //  lwc1 $f0, %lo($CPI1_0)($2)<br>
> +    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||<br>
> +        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {<br>
> +      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);<br>
> +      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||<br>
> +          isa<JumpTableSDNode>(Opnd0)) {<br>
> +        Base = Addr.getOperand(0);<br>
> +        Offset = Opnd0;<br>
> +        return true;<br>
> +      }<br>
> +    }<br>
> +<br>
> +    // If an indexed floating point load/store can be emitted, return false.<br>
> +    const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);<br>
> +<br>
> +    if (LS &&<br>
> +        (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) &&<br>
> +        Subtarget.hasFPIdx())<br>
> +      return false;<br>
> +  }<br>
> +  Base   = Addr;<br>
> +  Offset = CurDAG->getTargetConstant(0, ValTy);<br>
> +  return true;<br>
> +}<br>
> +<br>
> +/// Select instructions not customized! Used for<br>
> +/// expanded, promoted and normal instructions<br>
> +std::pair<bool, SDNode*> Mips16DAGToDAGISel::SelectNode(SDNode *Node) {<br>
> +  unsigned Opcode = Node->getOpcode();<br>
> +  DebugLoc dl = Node->getDebugLoc();<br>
> +<br>
> +  ///<br>
> +  // Instruction Selection not handled by the auto-generated<br>
> +  // tablegen selection should be handled here.<br>
> +  ///<br>
> +  EVT NodeTy = Node->getValueType(0);<br>
> +  unsigned MultOpc;<br>
> +<br>
> +  switch(Opcode) {<br>
> +  default: break;<br>
> +<br>
> +  case ISD::SUBE:<br>
> +  case ISD::ADDE: {<br>
> +    SDValue InFlag = Node->getOperand(2), CmpLHS;<br>
> +    unsigned Opc = InFlag.getOpcode(); (void)Opc;<br>
> +    assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||<br>
> +            (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&<br>
> +           "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");<br>
> +<br>
> +    unsigned MOp;<br>
> +    if (Opcode == ISD::ADDE) {<br>
> +      CmpLHS = InFlag.getValue(0);<br>
> +      MOp = Mips::AdduRxRyRz16;<br>
> +    } else {<br>
> +      CmpLHS = InFlag.getOperand(0);<br>
> +      MOp = Mips::SubuRxRyRz16;<br>
> +    }<br>
> +<br>
> +    SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };<br>
> +<br>
> +    SDValue LHS = Node->getOperand(0);<br>
> +    SDValue RHS = Node->getOperand(1);<br>
> +<br>
> +    EVT VT = LHS.getValueType();<br>
> +<br>
> +    unsigned Sltu_op = Mips::SltuRxRyRz16;<br>
> +    SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);<br>
> +    unsigned Addu_op = Mips::AdduRxRyRz16;<br>
> +    SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,<br>
> +                                              SDValue(Carry,0), RHS);<br>
> +<br>
> +    SDNode *Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,<br>
> +                                          SDValue(AddCarry,0));<br>
> +    return std::make_pair(true, Result);<br>
> +  }<br>
> +<br>
> +  /// Mul with two results<br>
> +  case ISD::SMUL_LOHI:<br>
> +  case ISD::UMUL_LOHI: {<br>
> +    MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : Mips::MultRxRy16);<br>
> +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,<br>
> +                                                  true, true);<br>
> +    if (!SDValue(Node, 0).use_empty())<br>
> +      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));<br>
> +<br>
> +    if (!SDValue(Node, 1).use_empty())<br>
> +      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));<br>
> +<br>
> +    return std::make_pair(true, (SDNode*)NULL);<br>
> +  }<br>
> +<br>
> +  case ISD::MULHS:<br>
> +  case ISD::MULHU: {<br>
> +    MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16);<br>
> +    SDNode *Result = SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;<br>
> +    return std::make_pair(true, Result);<br>
> +  }<br>
> +  }<br>
> +<br>
> +  return std::make_pair(false, (SDNode*)NULL);<br>
> +}<br>
> +<br>
> +FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM) {<br>
> +  return new Mips16DAGToDAGISel(TM);<br>
> +}<br>
><br>
> Added: llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h?rev=177089&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h?rev=177089&view=auto</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h (added)<br>
> +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h Thu Mar 14 13:27:31 2013<br>
> @@ -0,0 +1,51 @@<br>
> +//===---- Mips16ISelDAGToDAG.h - A Dag to Dag Inst Selector for Mips ------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// Subclass of MipsDAGToDAGISel specialized for mips16.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef MIPS16ISELDAGTODAG_H<br>
> +#define MIPS16ISELDAGTODAG_H<br>
> +<br>
> +#include "MipsISelDAGToDAG.h"<br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +class Mips16DAGToDAGISel : public MipsDAGToDAGISel {<br>
> +public:<br>
> +  explicit Mips16DAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {}<br>
> +<br>
> +private:<br>
> +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,<br>
> +                                         EVT Ty, bool HasLo, bool HasHi);<br>
> +<br>
> +  SDValue getMips16SPAliasReg();<br>
> +<br>
> +  void getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg);<br>
> +<br>
> +  virtual bool SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base,<br>
> +                            SDValue &Offset, SDValue &Alias);<br>
> +<br>
> +  virtual std::pair<bool, SDNode*> SelectNode(SDNode *Node);<br>
> +<br>
> +  virtual void ProcessFunctionAfterISel(MachineFunction &MF);<br>
> +<br>
> +  // Insert instructions to initialize the global base register in the<br>
> +  // first MBB of the function.<br>
> +  void InitGlobalBaseReg(MachineFunction &MF);<br>
> +<br>
> +  void InitMips16SPAliasReg(MachineFunction &MF);<br>
> +};<br>
> +<br>
> +FunctionPass *createMips16ISelDag(MipsTargetMachine &TM);<br>
> +<br>
> +}<br>
> +<br>
> +#endif<br>
><br>
> Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=177089&r1=177088&r2=177089&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=177089&r1=177088&r2=177089&view=diff</a><br>

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

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp (added)<br>
> +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp Thu Mar 14 13:27:31 2013<br>
> @@ -0,0 +1,463 @@<br>
> +//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// Subclass of MipsDAGToDAGISel specialized for mips32/64.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#define DEBUG_TYPE "mips-isel"<br>
> +#include "MipsSEISelDAGToDAG.h"<br>
> +#include "Mips.h"<br>
> +#include "MCTargetDesc/MipsBaseInfo.h"<br>
> +#include "MipsAnalyzeImmediate.h"<br>
> +#include "MipsMachineFunction.h"<br>
> +#include "MipsRegisterInfo.h"<br>
> +#include "llvm/CodeGen/MachineConstantPool.h"<br>
> +#include "llvm/CodeGen/MachineFrameInfo.h"<br>
> +#include "llvm/CodeGen/MachineFunction.h"<br>
> +#include "llvm/CodeGen/MachineInstrBuilder.h"<br>
> +#include "llvm/CodeGen/MachineRegisterInfo.h"<br>
> +#include "llvm/CodeGen/SelectionDAGNodes.h"<br>
> +#include "llvm/IR/GlobalValue.h"<br>
> +#include "llvm/IR/Instructions.h"<br>
> +#include "llvm/IR/Intrinsics.h"<br>
> +#include "llvm/IR/Type.h"<br>
> +#include "llvm/Support/CFG.h"<br>
> +#include "llvm/Support/Debug.h"<br>
> +#include "llvm/Support/ErrorHandling.h"<br>
> +#include "llvm/Support/raw_ostream.h"<br>
> +#include "llvm/Target/TargetMachine.h"<br>
> +using namespace llvm;<br>
> +<br>
> +<br>
> +bool MipsSEDAGToDAGISel::ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI,<br>
> +                                                const MachineInstr& MI) {<br>
> +  unsigned DstReg = 0, ZeroReg = 0;<br>
> +<br>
> +  // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".<br>
> +  if ((MI.getOpcode() == Mips::ADDiu) &&<br>
> +      (MI.getOperand(1).getReg() == Mips::ZERO) &&<br>
> +      (MI.getOperand(2).getImm() == 0)) {<br>
> +    DstReg = MI.getOperand(0).getReg();<br>
> +    ZeroReg = Mips::ZERO;<br>
> +  } else if ((MI.getOpcode() == Mips::DADDiu) &&<br>
> +             (MI.getOperand(1).getReg() == Mips::ZERO_64) &&<br>
> +             (MI.getOperand(2).getImm() == 0)) {<br>
> +    DstReg = MI.getOperand(0).getReg();<br>
> +    ZeroReg = Mips::ZERO_64;<br>
> +  }<br>
> +<br>
> +  if (!DstReg)<br>
> +    return false;<br>
> +<br>
> +  // Replace uses with ZeroReg.<br>
> +  for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg),<br>
> +       E = MRI->use_end(); U != E;) {<br>
> +    MachineOperand &MO = U.getOperand();<br>
> +    unsigned OpNo = U.getOperandNo();<br>
> +    MachineInstr *MI = MO.getParent();<br>
> +    ++U;<br>
> +<br>
> +    // Do not replace if it is a phi's operand or is tied to def operand.<br>
> +    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())<br>
> +      continue;<br>
> +<br>
> +    MO.setReg(ZeroReg);<br>
> +  }<br>
> +<br>
> +  return true;<br>
> +}<br>
> +<br>
> +void MipsSEDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {<br>
> +  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();<br>
> +<br>
> +  if (!MipsFI->globalBaseRegSet())<br>
> +    return;<br>
> +<br>
> +  MachineBasicBlock &MBB = MF.front();<br>
> +  MachineBasicBlock::iterator I = MBB.begin();<br>
> +  MachineRegisterInfo &RegInfo = MF.getRegInfo();<br>
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();<br>
> +  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();<br>
> +  unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();<br>
> +  const TargetRegisterClass *RC;<br>
> +<br>
> +  if (Subtarget.isABI_N64())<br>
> +    RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass;<br>
> +  else<br>
> +    RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass;<br>
> +<br>
> +  V0 = RegInfo.createVirtualRegister(RC);<br>
> +  V1 = RegInfo.createVirtualRegister(RC);<br>
> +<br>
> +  if (Subtarget.isABI_N64()) {<br>
> +    MF.getRegInfo().addLiveIn(Mips::T9_64);<br>
> +    MBB.addLiveIn(Mips::T9_64);<br>
> +<br>
> +    // lui $v0, %hi(%neg(%gp_rel(fname)))<br>
> +    // daddu $v1, $v0, $t9<br>
> +    // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))<br>
> +    const GlobalValue *FName = MF.getFunction();<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)<br>
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)<br>
> +      .addReg(Mips::T9_64);<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)<br>
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);<br>
> +    return;<br>
> +  }<br>
> +<br>
> +  if (MF.getTarget().getRelocationModel() == Reloc::Static) {<br>
> +    // Set global register to __gnu_local_gp.<br>
> +    //<br>
> +    // lui   $v0, %hi(__gnu_local_gp)<br>
> +    // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)<br>
> +      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)<br>
> +      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);<br>
> +    return;<br>
> +  }<br>
> +<br>
> +  MF.getRegInfo().addLiveIn(Mips::T9);<br>
> +  MBB.addLiveIn(Mips::T9);<br>
> +<br>
> +  if (Subtarget.isABI_N32()) {<br>
> +    // lui $v0, %hi(%neg(%gp_rel(fname)))<br>
> +    // addu $v1, $v0, $t9<br>
> +    // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))<br>
> +    const GlobalValue *FName = MF.getFunction();<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)<br>
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);<br>
> +    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)<br>
> +      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);<br>
> +    return;<br>
> +  }<br>
> +<br>
> +  assert(Subtarget.isABI_O32());<br>
> +<br>
> +  // For O32 ABI, the following instruction sequence is emitted to initialize<br>
> +  // the global base register:<br>
> +  //<br>
> +  //  0. lui   $2, %hi(_gp_disp)<br>
> +  //  1. addiu $2, $2, %lo(_gp_disp)<br>
> +  //  2. addu  $globalbasereg, $2, $t9<br>
> +  //<br>
> +  // We emit only the last instruction here.<br>
> +  //<br>
> +  // GNU linker requires that the first two instructions appear at the beginning<br>
> +  // of a function and no instructions be inserted before or between them.<br>
> +  // The two instructions are emitted during lowering to MC layer in order to<br>
> +  // avoid any reordering.<br>
> +  //<br>
> +  // Register $2 (Mips::V0) is added to the list of live-in registers to ensure<br>
> +  // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)<br>
> +  // reads it.<br>
> +  MF.getRegInfo().addLiveIn(Mips::V0);<br>
> +  MBB.addLiveIn(Mips::V0);<br>
> +  BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)<br>
> +    .addReg(Mips::V0).addReg(Mips::T9);<br>
> +}<br>
> +<br>
> +void MipsSEDAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) {<br>
> +  InitGlobalBaseReg(MF);<br>
> +<br>
> +  MachineRegisterInfo *MRI = &MF.getRegInfo();<br>
> +<br>
> +  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE;<br>
> +       ++MFI)<br>
> +    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I)<br>
> +      ReplaceUsesWithZeroReg(MRI, *I);<br>
> +}<br>
> +<br>
> +/// Select multiply instructions.<br>
> +std::pair<SDNode*, SDNode*><br>
> +MipsSEDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,<br>
> +                               bool HasLo, bool HasHi) {<br>
> +  SDNode *Lo = 0, *Hi = 0;<br>
> +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),<br>
> +                                       N->getOperand(1));<br>
> +  SDValue InFlag = SDValue(Mul, 0);<br>
> +<br>
> +  if (HasLo) {<br>
> +    unsigned Opcode = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);<br>
> +    Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);<br>
> +    InFlag = SDValue(Lo, 1);<br>
> +  }<br>
> +  if (HasHi) {<br>
> +    unsigned Opcode = (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64);<br>
> +    Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);<br>
> +  }<br>
> +  return std::make_pair(Lo, Hi);<br>
> +}<br>
> +<br>
> +/// ComplexPattern used on MipsInstrInfo<br>
> +/// Used on Mips Load/Store instructions<br>
> +bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,<br>
> +                                          SDValue &Offset) const {<br>
> +  EVT ValTy = Addr.getValueType();<br>
> +<br>
> +  // if Address is FI, get the TargetFrameIndex.<br>
> +  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {<br>
> +    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);<br>
> +    Offset = CurDAG->getTargetConstant(0, ValTy);<br>
> +    return true;<br>
> +  }<br>
> +<br>
> +  // on PIC code Load GA<br>
> +  if (Addr.getOpcode() == MipsISD::Wrapper) {<br>
> +    Base   = Addr.getOperand(0);<br>
> +    Offset = Addr.getOperand(1);<br>
> +    return true;<br>
> +  }<br>
> +<br>
> +  if (TM.getRelocationModel() != Reloc::PIC_) {<br>
> +    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||<br>
> +        Addr.getOpcode() == ISD::TargetGlobalAddress))<br>
> +      return false;<br>
> +  }<br>
> +<br>
> +  // Addresses of the form FI+const or FI|const<br>
> +  if (CurDAG->isBaseWithConstantOffset(Addr)) {<br>
> +    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));<br>
> +    if (isInt<16>(CN->getSExtValue())) {<br>
> +<br>
> +      // If the first operand is a FI, get the TargetFI Node<br>
> +      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode><br>
> +                                  (Addr.getOperand(0)))<br>
> +        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);<br>
> +      else<br>
> +        Base = Addr.getOperand(0);<br>
> +<br>
> +      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);<br>
> +      return true;<br>
> +    }<br>
> +  }<br>
> +<br>
> +  // Operand is a result from an ADD.<br>
> +  if (Addr.getOpcode() == ISD::ADD) {<br>
> +    // When loading from constant pools, load the lower address part in<br>
> +    // the instruction itself. Example, instead of:<br>
> +    //  lui $2, %hi($CPI1_0)<br>
> +    //  addiu $2, $2, %lo($CPI1_0)<br>
> +    //  lwc1 $f0, 0($2)<br>
> +    // Generate:<br>
> +    //  lui $2, %hi($CPI1_0)<br>
> +    //  lwc1 $f0, %lo($CPI1_0)($2)<br>
> +    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||<br>
> +        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {<br>
> +      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);<br>
> +      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||<br>
> +          isa<JumpTableSDNode>(Opnd0)) {<br>
> +        Base = Addr.getOperand(0);<br>
> +        Offset = Opnd0;<br>
> +        return true;<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +<br>
> +  return false;<br>
> +}<br>
> +<br>
> +bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,<br>
> +                                           SDValue &Offset) const {<br>
> +  Base = Addr;<br>
> +  Offset = CurDAG->getTargetConstant(0, Addr.getValueType());<br>
> +  return true;<br>
> +}<br>
> +<br>
> +bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,<br>
> +                                       SDValue &Offset) const {<br>
> +  return selectAddrRegImm(Addr, Base, Offset) ||<br>
> +    selectAddrDefault(Addr, Base, Offset);<br>
> +}<br>
> +<br>
> +std::pair<bool, SDNode*> MipsSEDAGToDAGISel::SelectNode(SDNode *Node) {<br>
> +  unsigned Opcode = Node->getOpcode();<br>
> +  DebugLoc dl = Node->getDebugLoc();<br>
> +<br>
> +  ///<br>
> +  // Instruction Selection not handled by the auto-generated<br>
> +  // tablegen selection should be handled here.<br>
> +  ///<br>
> +  EVT NodeTy = Node->getValueType(0);<br>
> +  SDNode *Result;<br>
> +  unsigned MultOpc;<br>
> +<br>
> +  switch(Opcode) {<br>
> +  default: break;<br>
> +<br>
> +  case ISD::SUBE:<br>
> +  case ISD::ADDE: {<br>
> +    SDValue InFlag = Node->getOperand(2), CmpLHS;<br>
> +    unsigned Opc = InFlag.getOpcode(); (void)Opc;<br>
> +    assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||<br>
> +            (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&<br>
> +           "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");<br>
> +<br>
> +    unsigned MOp;<br>
> +    if (Opcode == ISD::ADDE) {<br>
> +      CmpLHS = InFlag.getValue(0);<br>
> +      MOp = Mips::ADDu;<br>
> +    } else {<br>
> +      CmpLHS = InFlag.getOperand(0);<br>
> +      MOp = Mips::SUBu;<br>
> +    }<br>
> +<br>
> +    SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };<br>
> +<br>
> +    SDValue LHS = Node->getOperand(0);<br>
> +    SDValue RHS = Node->getOperand(1);<br>
> +<br>
> +    EVT VT = LHS.getValueType();<br>
> +<br>
> +    unsigned Sltu_op = Mips::SLTu;<br>
> +    SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2);<br>
> +    unsigned Addu_op = Mips::ADDu;<br>
> +    SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT,<br>
> +                                              SDValue(Carry,0), RHS);<br>
> +<br>
> +    Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,<br>
> +                                  SDValue(AddCarry,0));<br>
> +    return std::make_pair(true, Result);<br>
> +  }<br>
> +<br>
> +  /// Mul with two results<br>
> +  case ISD::SMUL_LOHI:<br>
> +  case ISD::UMUL_LOHI: {<br>
> +    if (NodeTy == MVT::i32)<br>
> +      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);<br>
> +    else<br>
> +      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);<br>
> +<br>
> +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,<br>
> +                                                  true, true);<br>
> +<br>
> +    if (!SDValue(Node, 0).use_empty())<br>
> +      ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));<br>
> +<br>
> +    if (!SDValue(Node, 1).use_empty())<br>
> +      ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));<br>
> +<br>
> +    return std::make_pair(true, (SDNode*)NULL);<br>
> +  }<br>
> +<br>
> +  /// Special Muls<br>
> +  case ISD::MUL: {<br>
> +    // Mips32 has a 32-bit three operand mul instruction.<br>
> +    if (Subtarget.hasMips32() && NodeTy == MVT::i32)<br>
> +      break;<br>
> +    MultOpc = NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT;<br>
> +    Result = SelectMULT(Node, MultOpc, dl, NodeTy, true, false).first;<br>
> +    return std::make_pair(true, Result);<br>
> +  }<br>
> +  case ISD::MULHS:<br>
> +  case ISD::MULHU: {<br>
> +    if (NodeTy == MVT::i32)<br>
> +      MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);<br>
> +    else<br>
> +      MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);<br>
> +<br>
> +    Result = SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;<br>
> +    return std::make_pair(true, Result);<br>
> +  }<br>
> +<br>
> +  case ISD::ConstantFP: {<br>
> +    ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);<br>
> +    if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {<br>
> +      if (Subtarget.hasMips64()) {<br>
> +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,<br>
> +                                              Mips::ZERO_64, MVT::i64);<br>
> +        Result = CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64, Zero);<br>
> +      } else {<br>
> +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,<br>
> +                                              Mips::ZERO, MVT::i32);<br>
> +        Result = CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,<br>
> +                                        Zero);<br>
> +      }<br>
> +<br>
> +      return std::make_pair(true, Result);<br>
> +    }<br>
> +    break;<br>
> +  }<br>
> +<br>
> +  case ISD::Constant: {<br>
> +    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);<br>
> +    unsigned Size = CN->getValueSizeInBits(0);<br>
> +<br>
> +    if (Size == 32)<br>
> +      break;<br>
> +<br>
> +    MipsAnalyzeImmediate AnalyzeImm;<br>
> +    int64_t Imm = CN->getSExtValue();<br>
> +<br>
> +    const MipsAnalyzeImmediate::InstSeq &Seq =<br>
> +      AnalyzeImm.Analyze(Imm, Size, false);<br>
> +<br>
> +    MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();<br>
> +    DebugLoc DL = CN->getDebugLoc();<br>
> +    SDNode *RegOpnd;<br>
> +    SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),<br>
> +                                                MVT::i64);<br>
> +<br>
> +    // The first instruction can be a LUi which is different from other<br>
> +    // instructions (ADDiu, ORI and SLL) in that it does not have a register<br>
> +    // operand.<br>
> +    if (Inst->Opc == Mips::LUi64)<br>
> +      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);<br>
> +    else<br>
> +      RegOpnd =<br>
> +        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
> +                               CurDAG->getRegister(Mips::ZERO_64, MVT::i64),<br>
> +                               ImmOpnd);<br>
> +<br>
> +    // The remaining instructions in the sequence are handled here.<br>
> +    for (++Inst; Inst != Seq.end(); ++Inst) {<br>
> +      ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),<br>
> +                                          MVT::i64);<br>
> +      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
> +                                       SDValue(RegOpnd, 0), ImmOpnd);<br>
> +    }<br>
> +<br>
> +    return std::make_pair(true, RegOpnd);<br>
> +  }<br>
> +<br>
> +  case MipsISD::ThreadPointer: {<br>
> +    EVT PtrVT = TLI.getPointerTy();<br>
> +    unsigned RdhwrOpc, SrcReg, DestReg;<br>
> +<br>
> +    if (PtrVT == MVT::i32) {<br>
> +      RdhwrOpc = Mips::RDHWR;<br>
> +      SrcReg = Mips::HWR29;<br>
> +      DestReg = Mips::V1;<br>
> +    } else {<br>
> +      RdhwrOpc = Mips::RDHWR64;<br>
> +      SrcReg = Mips::HWR29_64;<br>
> +      DestReg = Mips::V1_64;<br>
> +    }<br>
> +<br>
> +    SDNode *Rdhwr =<br>
> +      CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),<br>
> +                             Node->getValueType(0),<br>
> +                             CurDAG->getRegister(SrcReg, PtrVT));<br>
> +    SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,<br>
> +                                         SDValue(Rdhwr, 0));<br>
> +    SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT);<br>
> +    ReplaceUses(SDValue(Node, 0), ResNode);<br>
> +    return std::make_pair(true, ResNode.getNode());<br>
> +  }<br>
> +  }<br>
> +<br>
> +  return std::make_pair(false, (SDNode*)NULL);<br>
> +}<br>
> +<br>
> +FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) {<br>
> +  return new MipsSEDAGToDAGISel(TM);<br>
> +}<br>
><br>
> Added: llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h?rev=177089&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h?rev=177089&view=auto</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h (added)<br>
> +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h Thu Mar 14 13:27:31 2013<br>
> @@ -0,0 +1,54 @@<br>
> +//===-- MipsSEISelDAGToDAG.h - A Dag to Dag Inst Selector for MipsSE -----===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// Subclass of MipsDAGToDAGISel specialized for mips32/64.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef MIPSSEISELDAGTODAG_H<br>
> +#define MIPSSEISELDAGTODAG_H<br>
> +<br>
> +#include "MipsISelDAGToDAG.h"<br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +class MipsSEDAGToDAGISel : public MipsDAGToDAGISel {<br>
> +<br>
> +public:<br>
> +  explicit MipsSEDAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {}<br>
> +<br>
> +private:<br>
> +  bool ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&);<br>
> +<br>
> +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,<br>
> +                                         EVT Ty, bool HasLo, bool HasHi);<br>
> +<br>
> +  virtual bool selectAddrRegImm(SDValue Addr, SDValue &Base,<br>
> +                                SDValue &Offset) const;<br>
> +<br>
> +  virtual bool selectAddrDefault(SDValue Addr, SDValue &Base,<br>
> +                                 SDValue &Offset) const;<br>
> +<br>
> +  virtual bool selectIntAddr(SDValue Addr, SDValue &Base,<br>
> +                             SDValue &Offset) const;<br>
> +<br>
> +  virtual std::pair<bool, SDNode*> SelectNode(SDNode *Node);<br>
> +<br>
> +  virtual void ProcessFunctionAfterISel(MachineFunction &MF);<br>
> +<br>
> +  // Insert instructions to initialize the global base register in the<br>
> +  // first MBB of the function.<br>
> +  void InitGlobalBaseReg(MachineFunction &MF);<br>
> +};<br>
> +<br>
> +FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM);<br>
> +<br>
> +}<br>
> +<br>
> +#endif<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br>