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