OK, I will see if I can switch to building with clang.<br><br>Thank you for the fix.<br><br><div class="gmail_quote">On Thu, Mar 14, 2013 at 5:15 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"><div class="im">On Thu, Mar 14, 2013 at 4:52 PM, Akira Hatanaka <<a href="mailto:ahatanak@gmail.com">ahatanak@gmail.com</a>> wrote:<br>

> 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>
<br>
</div>I believe most of the core developers just self-host with recent Clang<br>
builds & never build with GCC (except, potentially, for whatever<br>
in-house automated builds they may have going on)<br>
<div class="im"><br>
> I was wondering if there are cases where gcc correctly issues a warning but<br>
> clang doesn't.<br>
<br>
</div>Most of the cases where GCC issues warnings that Clang doesn't it's<br>
because there's a deliberate choice not to emit those warnings from<br>
Clang because they're considered bad for some reason (in most of these<br>
cases the LLVM build system has been modified to disable these bad<br>
warnings when compiling with GCC). If that's not the case, then it's a<br>
Clang bug we're likely to fix in short order.<br>
<br>
While a few developers care about building Clang warning-free with GCC<br>
(& have devoted bots to the task, cleaned up/disabled bad GCC<br>
warnincgs , far more care about Clang building warning-free with<br>
Clang.<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
><br>
> On Thu, Mar 14, 2013 at 4:13 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
>><br>
>> 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>
>><br>
>> - David<br>
>><br>
>> On Thu, Mar 14, 2013 at 11:27 AM, Akira Hatanaka <<a href="mailto:ahatanaka@mips.com">ahatanaka@mips.com</a>><br>
>> 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<br>
>> > 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:<br>
>> > <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>
>> > ==============================================================================<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:<br>
>> > <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>
>> > ==============================================================================<br>
>> > --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp (added)<br>
>> > +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.cpp Thu Mar 14<br>
>> > 13:27:31 2013<br>
>> > @@ -0,0 +1,308 @@<br>
>> > +//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16<br>
>> > ----===//<br>
>> > +//<br>
>> > +//                     The LLVM Compiler Infrastructure<br>
>> > +//<br>
>> > +// This file is distributed under the University of Illinois Open<br>
>> > Source<br>
>> > +// License. See LICENSE.TXT for details.<br>
>> > +//<br>
>> ><br>
>> > +//===----------------------------------------------------------------------===//<br>
>> > +//<br>
>> > +// Subclass of MipsDAGToDAGISel specialized for mips16.<br>
>> > +//<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,<br>
>> > EVT Ty,<br>
>> > +                               bool HasLo, bool HasHi) {<br>
>> > +  SDNode *Lo = 0, *Hi = 0;<br>
>> > +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue,<br>
>> > 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<br>
>> > 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>
>> > {<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<br>
>> > &AliasReg) {<br>
>> > +  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0,<br>
>> > 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) ||<br>
>> > 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<br>
>> > false.<br>
>> > +    const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);<br>
>> > +<br>
>> > +    if (LS &&<br>
>> > +        (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() ==<br>
>> > 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,<br>
>> > 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 :<br>
>> > Mips::MultRxRy16);<br>
>> > +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl,<br>
>> > 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 :<br>
>> > Mips::MultRxRy16);<br>
>> > +    SDNode *Result = SelectMULT(Node, MultOpc, dl, NodeTy, false,<br>
>> > 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:<br>
>> > <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>
>> > ==============================================================================<br>
>> > --- llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h (added)<br>
>> > +++ llvm/trunk/lib/Target/Mips/Mips16ISelDAGToDAG.h Thu Mar 14 13:27:31<br>
>> > 2013<br>
>> > @@ -0,0 +1,51 @@<br>
>> > +//===---- Mips16ISelDAGToDAG.h - A Dag to Dag Inst Selector for Mips<br>
>> > ------===//<br>
>> > +//<br>
>> > +//                     The LLVM Compiler Infrastructure<br>
>> > +//<br>
>> > +// This file is distributed under the University of Illinois Open<br>
>> > Source<br>
>> > +// License. See LICENSE.TXT for details.<br>
>> > +//<br>
>> ><br>
>> > +//===----------------------------------------------------------------------===//<br>
>> > +//<br>
>> > +// Subclass of MipsDAGToDAGISel specialized for mips16.<br>
>> > +//<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) :<br>
>> > MipsDAGToDAGISel(TM) {}<br>
>> > +<br>
>> > +private:<br>
>> > +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc,<br>
>> > DebugLoc dl,<br>
>> > +                                         EVT Ty, bool HasLo, bool<br>
>> > 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:<br>
>> > <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>
>> > ==============================================================================<br>
>> > --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original)<br>
>> > +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Thu Mar 14 13:27:31<br>
>> > 2013<br>
>> > @@ -12,19 +12,19 @@<br>
>> ><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>
>> > //===----------------------------------------------------------------------===//<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<br>
>> > can<br>
>> > -  /// make the right decision when generating code for different<br>
>> > 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,<br>
>> > 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,<br>
>> > DebugLoc dl,<br>
>> > -                                         EVT Ty, bool HasLo, bool<br>
>> > HasHi);<br>
>> > -<br>
>> > -  SDNode *Select(SDNode *N);<br>
>> > -<br>
>> > -  // Complex Pattern.<br>
>> > -  /// (reg + imm).<br>
>> > -  bool selectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset)<br>
>> > const;<br>
>> > -<br>
>> > -  /// Fall back on this function if all else fails.<br>
>> > -  bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset)<br>
>> > const;<br>
>> > -<br>
>> > -  /// Match integer address pattern.<br>
>> > -  bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset)<br>
>> > const;<br>
>> > -<br>
>> > -  bool SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base, SDValue<br>
>> > &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<br>
>> > 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><br>
>> > &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<br>
>> > model is<br>
>> > -// PIC, the necessary instructions are emitted later to prevent<br>
>> > 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),<br>
>> > 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),<br>
>> > 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),<br>
>> > 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<br>
>> > 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<br>
>> > beginning<br>
>> > -  // of a function and no instructions be inserted before or between<br>
>> > them.<br>
>> > -  // The two instructions are emitted during lowering to MC layer in<br>
>> > order to<br>
>> > -  // avoid any reordering.<br>
>> > -  //<br>
>> > -  // Register $2 (Mips::V0) is added to the list of live-in registers<br>
>> > to ensure<br>
>> > -  // the value instruction 1 (addiu) defines is valid when instruction<br>
>> > 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<br>
>> > 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<br>
>> > operand.<br>
>> > -    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) ||<br>
>> > 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<br>
>> > != MFE;<br>
>> > -       ++MFI)<br>
>> > -    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end();<br>
>> > ++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,<br>
>> > 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) ||<br>
>> > 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<br>
>> > &AliasReg) {<br>
>> > -  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0,<br>
>> > 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) ||<br>
>> > 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<br>
>> > false.<br>
>> > -    const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);<br>
>> > -<br>
>> > -    if (LS &&<br>
>> > -        (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() ==<br>
>> > 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<br>
>> > Ty,<br>
>> > -                             bool HasLo, bool HasHi) {<br>
>> > -  SDNode *Lo = 0, *Hi = 0;<br>
>> > -  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue,<br>
>> > 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<br>
>> > &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 :<br>
>> > Mips::MULT);<br>
>> > -    }<br>
>> > -    else<br>
>> > -      MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu :<br>
>> > Mips::DMULT);<br>
>> > -<br>
>> > -    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl,<br>
>> > 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 :<br>
>> > 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>
>> > {<br>
>> > -      if (Subtarget.hasMips64()) {<br>
>> > -        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),<br>
>> > 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,<br>
>> > 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 =<br>
>> > 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<br>
>> > register<br>
>> > -    // operand.<br>
>> > -    if (Inst->Opc == Mips::LUi64)<br>
>> > -      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
>> > ImmOpnd);<br>
>> > -    else<br>
>> > -      RegOpnd =<br>
>> > -        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
>> > -                               CurDAG->getRegister(Mips::ZERO_64,<br>
>> > MVT::i64),<br>
>> > -                               ImmOpnd);<br>
>> > -<br>
>> > -    // The remaining instructions in the sequence are handled here.<br>
>> > -    for (++Inst; Inst != Seq.end(); ++Inst) {<br>
>> > -      ImmOpnd =<br>
>> > 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,<br>
>> > DestReg,<br>
>> > -                                         SDValue(Rdhwr, 0));<br>
>> > -    SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg,<br>
>> > 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:<br>
>> > <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>
>> > ==============================================================================<br>
>> > --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp (added)<br>
>> > +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp Thu Mar 14<br>
>> > 13:27:31 2013<br>
>> > @@ -0,0 +1,463 @@<br>
>> > +//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE<br>
>> > ----===//<br>
>> > +//<br>
>> > +//                     The LLVM Compiler Infrastructure<br>
>> > +//<br>
>> > +// This file is distributed under the University of Illinois Open<br>
>> > Source<br>
>> > +// License. See LICENSE.TXT for details.<br>
>> > +//<br>
>> ><br>
>> > +//===----------------------------------------------------------------------===//<br>
>> > +//<br>
>> > +// Subclass of MipsDAGToDAGISel specialized for mips32/64.<br>
>> > +//<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<br>
>> > *MRI,<br>
>> > +                                                const MachineInstr& MI)<br>
>> > {<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<br>
>> > operand.<br>
>> > +    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) ||<br>
>> > 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),<br>
>> > 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),<br>
>> > 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<br>
>> > 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<br>
>> > beginning<br>
>> > +  // of a function and no instructions be inserted before or between<br>
>> > them.<br>
>> > +  // The two instructions are emitted during lowering to MC layer in<br>
>> > order to<br>
>> > +  // avoid any reordering.<br>
>> > +  //<br>
>> > +  // Register $2 (Mips::V0) is added to the list of live-in registers<br>
>> > to ensure<br>
>> > +  // the value instruction 1 (addiu) defines is valid when instruction<br>
>> > 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>
>> > {<br>
>> > +  InitGlobalBaseReg(MF);<br>
>> > +<br>
>> > +  MachineRegisterInfo *MRI = &MF.getRegInfo();<br>
>> > +<br>
>> > +  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI<br>
>> > != MFE;<br>
>> > +       ++MFI)<br>
>> > +    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end();<br>
>> > ++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,<br>
>> > EVT Ty,<br>
>> > +                               bool HasLo, bool HasHi) {<br>
>> > +  SDNode *Lo = 0, *Hi = 0;<br>
>> > +  SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue,<br>
>> > 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) ||<br>
>> > 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 :<br>
>> > Mips::DMULT);<br>
>> > +<br>
>> > +    std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl,<br>
>> > 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>
>> > {<br>
>> > +      if (Subtarget.hasMips64()) {<br>
>> > +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),<br>
>> > dl,<br>
>> > +                                              Mips::ZERO_64, MVT::i64);<br>
>> > +        Result = CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64,<br>
>> > Zero);<br>
>> > +      } else {<br>
>> > +        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),<br>
>> > dl,<br>
>> > +                                              Mips::ZERO, MVT::i32);<br>
>> > +        Result = CurDAG->getMachineNode(Mips::BuildPairF64, dl,<br>
>> > 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 =<br>
>> > 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<br>
>> > register<br>
>> > +    // operand.<br>
>> > +    if (Inst->Opc == Mips::LUi64)<br>
>> > +      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
>> > ImmOpnd);<br>
>> > +    else<br>
>> > +      RegOpnd =<br>
>> > +        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,<br>
>> > +                               CurDAG->getRegister(Mips::ZERO_64,<br>
>> > MVT::i64),<br>
>> > +                               ImmOpnd);<br>
>> > +<br>
>> > +    // The remaining instructions in the sequence are handled here.<br>
>> > +    for (++Inst; Inst != Seq.end(); ++Inst) {<br>
>> > +      ImmOpnd =<br>
>> > 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,<br>
>> > DestReg,<br>
>> > +                                         SDValue(Rdhwr, 0));<br>
>> > +    SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg,<br>
>> > 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:<br>
>> > <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>
>> > ==============================================================================<br>
>> > --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h (added)<br>
>> > +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.h Thu Mar 14 13:27:31<br>
>> > 2013<br>
>> > @@ -0,0 +1,54 @@<br>
>> > +//===-- MipsSEISelDAGToDAG.h - A Dag to Dag Inst Selector for MipsSE<br>
>> > -----===//<br>
>> > +//<br>
>> > +//                     The LLVM Compiler Infrastructure<br>
>> > +//<br>
>> > +// This file is distributed under the University of Illinois Open<br>
>> > Source<br>
>> > +// License. See LICENSE.TXT for details.<br>
>> > +//<br>
>> ><br>
>> > +//===----------------------------------------------------------------------===//<br>
>> > +//<br>
>> > +// Subclass of MipsDAGToDAGISel specialized for mips32/64.<br>
>> > +//<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) :<br>
>> > MipsDAGToDAGISel(TM) {}<br>
>> > +<br>
>> > +private:<br>
>> > +  bool ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, const<br>
>> > MachineInstr&);<br>
>> > +<br>
>> > +  std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc,<br>
>> > DebugLoc dl,<br>
>> > +                                         EVT Ty, bool HasLo, bool<br>
>> > 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>
><br>
><br>
</div></div></blockquote></div><br>