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>