aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanak@gmail.com>2011-04-02 00:26:12 +0000
committerAkira Hatanaka <ahatanak@gmail.com>2011-04-02 00:26:12 +0000
commitad8ffad60ae33e834c18072a37b6b30fe45efdf6 (patch)
tree4d72f259fd645f864cedc1542e77e91462c9a7eb
parentdc1652fd311073492a169101b8b6e1d725dca280 (diff)
Undo changes mistakenly made in revision 128750.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128751 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp58
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp28
2 files changed, 59 insertions, 27 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 0382964fe9..3749009112 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -122,8 +122,7 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
(Addr.getOpcode() == ISD::TargetConstantPool) ||
(Addr.getOpcode() == ISD::TargetJumpTable) ||
- (Addr.getOpcode() == ISD::TargetBlockAddress) ||
- (Addr.getOpcode() == ISD::TargetExternalSymbol)) {
+ (Addr.getOpcode() == ISD::TargetBlockAddress)) {
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
Offset = Addr;
return true;
@@ -445,6 +444,61 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
return ResNode;
// Other cases are autogenerated.
break;
+
+ /// Handle direct and indirect calls when using PIC. On PIC, when
+ /// GOT is smaller than about 64k (small code) the GA target is
+ /// loaded with only one instruction. Otherwise GA's target must
+ /// be loaded with 3 instructions.
+ case MipsISD::JmpLink: {
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ unsigned LastOpNum = Node->getNumOperands()-1;
+
+ SDValue Chain = Node->getOperand(0);
+ SDValue Callee = Node->getOperand(1);
+ SDValue InFlag;
+
+ // Skip the incomming flag if present
+ if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue)
+ LastOpNum--;
+
+ if ( (isa<GlobalAddressSDNode>(Callee)) ||
+ (isa<ExternalSymbolSDNode>(Callee)) )
+ {
+ /// Direct call for global addresses and external symbols
+ SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
+
+ // Use load to get GOT target
+ SDValue Ops[] = { Callee, GPReg, Chain };
+ SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32,
+ MVT::Other, Ops, 3), 0);
+ Chain = Load.getValue(1);
+
+ // Call target must be on T9
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag);
+ } else
+ /// Indirect call
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag);
+
+ // Map the JmpLink operands to JALR
+ SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue);
+ SmallVector<SDValue, 8> Ops;
+ Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32));
+
+ for (unsigned i = 2, e = LastOpNum+1; i != e; ++i)
+ Ops.push_back(Node->getOperand(i));
+ Ops.push_back(Chain);
+ Ops.push_back(Chain.getValue(1));
+
+ // Emit Jump and Link Register
+ SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys,
+ &Ops[0], Ops.size());
+
+ // Replace Chain and InFlag
+ ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1));
+ return ResNode;
+ }
+ }
}
// Select the default instruction
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 20df9c8632..59ad81b5a7 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1201,34 +1201,12 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.
unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG;
- bool LoadSymAddr = false;
-
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,
- getPointerTy(), 0, OpFlag);
- LoadSymAddr = true;
- }
- else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ getPointerTy(), 0, OpFlag);
+ else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
getPointerTy(), OpFlag);
- LoadSymAddr = true;
- }
-
- // Create nodes that load address of callee and copy it to T9
- if (IsPIC) {
- if (LoadSymAddr) {
- // load callee address
- Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee,
- MachinePointerInfo::getGOT(),
- false, false, 0);
- Chain = Callee.getValue(1);
- }
-
- // copy to T9
- Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0));
- InFlag = Chain.getValue(1);
- Callee = DAG.getRegister(Mips::T9, MVT::i32);
- }
// MipsJmpLink = #chain, #target_address, #opt_in_flags...
// = Chain, Callee, Reg#1, Reg#2, ...