Added JumpTable support
Fixed some AsmPrinter issues
Added GLOBAL_OFFSET_TABLE Node handle.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44024 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 440d3e3..d12d30b 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -55,6 +55,9 @@
setSetCCResultType(MVT::i32);
setSetCCResultContents(ZeroOrOneSetCCResult);
+ // JumpTable targets must use GOT when using PIC_
+ setUsesGlobalOffsetTable(true);
+
// Set up the register classes
addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass);
@@ -62,6 +65,7 @@
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::RET, MVT::Other, Custom);
+ setOperationAction(ISD::JumpTable, MVT::i32, Custom);
// Load extented operations for i1 types must be promoted
setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
@@ -119,6 +123,7 @@
case ISD::RET: return LowerRET(Op, DAG);
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
+ case ISD::JumpTable: return LowerJumpTable(Op, DAG);
}
return SDOperand();
}
@@ -175,6 +180,29 @@
assert(0 && "TLS not implemented for MIPS.");
}
+SDOperand MipsTargetLowering::
+LowerJumpTable(SDOperand Op, SelectionDAG &DAG)
+{
+ SDOperand ResNode;
+ SDOperand HiPart;
+
+ MVT::ValueType PtrVT = Op.getValueType();
+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+ SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
+
+ if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
+ const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32);
+ SDOperand Ops[] = { JTI };
+ HiPart = DAG.getNode(MipsISD::Hi, VTs, 1, Ops, 1);
+ } else // Emit Load from Global Pointer
+ HiPart = DAG.getLoad(MVT::i32, DAG.getEntryNode(), JTI, NULL, 0);
+
+ SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, JTI);
+ ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
+
+ return ResNode;
+}
+
//===----------------------------------------------------------------------===//
// Calling Convention Implementation
//
@@ -346,13 +374,11 @@
// location is used on function prologue to save GP and also after all
// emited CALL's to restore GP.
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
-
// Function can have an arbitrary number of calls, so
// hold the LastStackLoc with the biggest offset.
int FI;
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
if (LastStackLoc >= MipsFI->getGPStackOffset()) {
-
LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4);
// Create the frame index only once. SPOffset here can be anything
// (this will be fixed on processFunctionBeforeFrameFinalized)
@@ -363,7 +389,6 @@
MipsFI->setGPStackOffset(LastStackLoc);
}
-
// Reload GP value.
FI = MipsFI->getGPFI();
SDOperand FIN = DAG.getFrameIndex(FI,getPointerTy());
@@ -455,6 +480,10 @@
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
+ // GP holds the GOT address on PIC calls.
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+ AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
+
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);