#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include <queue>
-#include <set>
-
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
/// TM - Keep a reference to MipsTargetMachine.
MipsTargetMachine &TM;
- /// MipsLowering - This object fully describes how to lower LLVM code to an
- /// Mips-specific SelectionDAG.
- MipsTargetLowering MipsLowering;
-
/// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
/// make the right decision when generating code for different targets.
const MipsSubtarget &Subtarget;
public:
explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
- SelectionDAGISel(MipsLowering),
- TM(tm), MipsLowering(*TM.getTargetLowering()),
- Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
+ SelectionDAGISel(tm),
+ TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
- virtual void InstructionSelect(SelectionDAG &SD);
+ virtual void InstructionSelect();
// Pass Name
virtual const char *getPassName() const {
// Include the pieces autogenerated from the target description.
#include "MipsGenDAGISel.inc"
- SDValue getGlobalBaseReg();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const MipsTargetMachine &getTargetMachine() {
+ return static_cast<const MipsTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const MipsInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
SDNode *Select(SDValue N);
// Complex Pattern.
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void MipsDAGToDAGISel::
-InstructionSelect(SelectionDAG &SD)
-{
+void MipsDAGToDAGISel::InstructionSelect() {
DEBUG(BB->dump());
// Codegen the basic block.
- #ifndef NDEBUG
- DOUT << "===== Instruction selection begins:\n";
- Indent = 0;
- #endif
+ DEBUG(errs() << "===== Instruction selection begins:\n");
+ DEBUG(Indent = 0);
// Select target instructions for the DAG.
- SD.setRoot(SelectRoot(SD.getRoot()));
+ SelectRoot(*CurDAG);
- #ifndef NDEBUG
- DOUT << "===== Instruction selection ends:\n";
- #endif
+ DEBUG(errs() << "===== Instruction selection ends:\n");
- SD.RemoveDeadNodes();
+ CurDAG->RemoveDeadNodes();
}
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
-SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
- MachineFunction* MF = BB->getParent();
- unsigned GP = 0;
- for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
- ee = MF->getRegInfo().livein_end(); ii != ee; ++ii)
- if (ii->first == Mips::GP) {
- GP = ii->second;
- break;
- }
- assert(GP && "GOT PTR not in liveins");
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- GP, MVT::i32);
+SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
/// ComplexPattern used on MipsInstrInfo
Base = Addr.getOperand(0);
}
- Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
+ Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
return true;
}
}
/// Select instructions not customized! Used for
/// expanded, promoted and normal instructions
-SDNode* MipsDAGToDAGISel::
-Select(SDValue N)
-{
- SDNode *Node = N.Val;
+SDNode* MipsDAGToDAGISel::Select(SDValue N) {
+ SDNode *Node = N.getNode();
unsigned Opcode = Node->getOpcode();
+ DebugLoc dl = Node->getDebugLoc();
// Dump information about the Node being selected
- #ifndef NDEBUG
- DOUT << std::string(Indent, ' ') << "Selecting: ";
- DEBUG(Node->dump(CurDAG));
- DOUT << "\n";
- Indent += 2;
- #endif
+ DEBUG(errs().indent(Indent) << "Selecting: ";
+ Node->dump(CurDAG);
+ errs() << "\n");
+ DEBUG(Indent += 2);
// If we have a custom node, we already have selected!
if (Node->isMachineOpcode()) {
- #ifndef NDEBUG
- DOUT << std::string(Indent-2, ' ') << "== ";
- DEBUG(Node->dump(CurDAG));
- DOUT << "\n";
- Indent -= 2;
- #endif
+ DEBUG(errs().indent(Indent-2) << "== ";
+ Node->dump(CurDAG);
+ errs() << "\n");
+ DEBUG(Indent -= 2);
return NULL;
}
case ISD::SUBE:
case ISD::ADDE: {
SDValue InFlag = Node->getOperand(2), CmpLHS;
- unsigned Opc = InFlag.getOpcode(), MOp;
-
+ unsigned Opc = InFlag.getOpcode(); Opc=Opc;
assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
(Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
"(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
+ unsigned MOp;
if (Opcode == ISD::ADDE) {
CmpLHS = InFlag.getValue(0);
MOp = Mips::ADDu;
SDValue LHS = Node->getOperand(0);
SDValue RHS = Node->getOperand(1);
- AddToISelQueue(LHS);
- AddToISelQueue(RHS);
- MVT VT = LHS.getValueType();
- SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, VT, Ops, 2);
- SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, VT,
+ EVT VT = LHS.getValueType();
+ SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, dl, VT, Ops, 2);
+ SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, dl, VT,
SDValue(Carry,0), RHS);
- return CurDAG->SelectNodeTo(N.Val, MOp, VT, MVT::Flag,
+ return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag,
LHS, SDValue(AddCarry,0));
}
case ISD::UMUL_LOHI: {
SDValue Op1 = Node->getOperand(0);
SDValue Op2 = Node->getOperand(1);
- AddToISelQueue(Op1);
- AddToISelQueue(Op2);
unsigned Op;
if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI)
else
Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
- SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
+ SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2);
SDValue InFlag = SDValue(Node, 0);
- SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, MVT::i32,
+ SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32,
MVT::Flag, InFlag);
InFlag = SDValue(Lo,1);
- SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
+ SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag);
if (!N.getValue(0).use_empty())
ReplaceUses(N.getValue(0), SDValue(Lo,0));
case ISD::MULHU: {
SDValue MulOp1 = Node->getOperand(0);
SDValue MulOp2 = Node->getOperand(1);
- AddToISelQueue(MulOp1);
- AddToISelQueue(MulOp2);
unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
- SDNode *MulNode = CurDAG->getTargetNode(MulOp, MVT::Flag, MulOp1, MulOp2);
+ SDNode *MulNode = CurDAG->getTargetNode(MulOp, dl,
+ MVT::Flag, MulOp1, MulOp2);
SDValue InFlag = SDValue(MulNode, 0);
if (MulOp == ISD::MUL)
- return CurDAG->getTargetNode(Mips::MFLO, MVT::i32, InFlag);
+ return CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32, InFlag);
else
- return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
+ return CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag);
}
/// Div/Rem operations
case ISD::UDIV: {
SDValue Op1 = Node->getOperand(0);
SDValue Op2 = Node->getOperand(1);
- AddToISelQueue(Op1);
- AddToISelQueue(Op2);
unsigned Op, MOp;
if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) {
Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
MOp = Mips::MFHI;
}
- SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
+ SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2);
SDValue InFlag = SDValue(Node, 0);
- return CurDAG->getTargetNode(MOp, MVT::i32, InFlag);
+ return CurDAG->getTargetNode(MOp, dl, MVT::i32, InFlag);
}
// Get target GOT address.
- case ISD::GLOBAL_OFFSET_TABLE: {
- SDValue Result = getGlobalBaseReg();
- ReplaceUses(N, Result);
- return NULL;
- }
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
/// Handle direct and indirect calls when using PIC. On PIC, when
/// GOT is smaller than about 64k (small code) the GA target is
/// be loaded with 3 instructions.
case MipsISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
- //bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
SDValue Chain = Node->getOperand(0);
SDValue Callee = Node->getOperand(1);
- AddToISelQueue(Chain);
SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
SDValue InFlag(0, 0);
// Use load to get GOT target
SDValue Ops[] = { Callee, GPReg, Chain };
- SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, MVT::i32,
+ SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, dl, MVT::i32,
MVT::Other, Ops, 3), 0);
Chain = Load.getValue(1);
- AddToISelQueue(Chain);
// Call target must be on T9
- Chain = CurDAG->getCopyToReg(Chain, T9Reg, Load, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
} else
/// Indirect call
- Chain = CurDAG->getCopyToReg(Chain, T9Reg, Callee, InFlag);
-
- AddToISelQueue(Chain);
+ Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
// Emit Jump and Link Register
- SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, MVT::Other,
+ SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, dl, MVT::Other,
MVT::Flag, T9Reg, Chain);
Chain = SDValue(ResNode, 0);
InFlag = SDValue(ResNode, 1);
// Select the default instruction
SDNode *ResNode = SelectCode(N);
- #ifndef NDEBUG
- DOUT << std::string(Indent-2, ' ') << "=> ";
- if (ResNode == NULL || ResNode == N.Val)
- DEBUG(N.Val->dump(CurDAG));
+ DEBUG(errs().indent(Indent-2) << "=> ");
+ if (ResNode == NULL || ResNode == N.getNode())
+ DEBUG(N.getNode()->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
- DOUT << "\n";
- Indent -= 2;
- #endif
+ DEBUG(errs() << "\n");
+ DEBUG(Indent -= 2);
return ResNode;
}