This patch moves <font size="2"><span style="font-size: 10pt;">transformation of JmpLink and related nodes done during instruction selection to Legalize.<br><br>Index: lib/Target/Mips/MipsISelDAGToDAG.cpp<br>===================================================================<br>
--- lib/Target/Mips/MipsISelDAGToDAG.cpp (revision 128742)<br>+++ lib/Target/Mips/MipsISelDAGToDAG.cpp (working copy)<br>@@ -122,7 +122,8 @@<br> if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||<br> (Addr.getOpcode() == ISD::TargetConstantPool) ||<br>
(Addr.getOpcode() == ISD::TargetJumpTable) ||<br>- (Addr.getOpcode() == ISD::TargetBlockAddress)) {<br>+ (Addr.getOpcode() == ISD::TargetBlockAddress) ||<br>+ (Addr.getOpcode() == ISD::TargetExternalSymbol)) {<br>
Base = CurDAG->getRegister(Mips::GP, MVT::i32);<br> Offset = Addr;<br> return true;<br>@@ -444,61 +445,6 @@<br> return ResNode;<br> // Other cases are autogenerated.<br> break;<br>
-<br>- /// Handle direct and indirect calls when using PIC. On PIC, when<br>- /// GOT is smaller than about 64k (small code) the GA target is<br>- /// loaded with only one instruction. Otherwise GA's target must<br>
- /// be loaded with 3 instructions.<br>- case MipsISD::JmpLink: {<br>- if (TM.getRelocationModel() == Reloc::PIC_) {<br>- unsigned LastOpNum = Node->getNumOperands()-1;<br>-<br>- SDValue Chain = Node->getOperand(0);<br>
- SDValue Callee = Node->getOperand(1);<br>- SDValue InFlag;<br>-<br>- // Skip the incomming flag if present<br>- if (Node->getOperand(LastOpNum).getValueType() == MVT::Glue)<br>- LastOpNum--;<br>
-<br>- if ( (isa<GlobalAddressSDNode>(Callee)) ||<br>- (isa<ExternalSymbolSDNode>(Callee)) )<br>- {<br>- /// Direct call for global addresses and external symbols<br>- SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);<br>
-<br>- // Use load to get GOT target<br>- SDValue Ops[] = { Callee, GPReg, Chain };<br>- SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32,<br>- MVT::Other, Ops, 3), 0);<br>
- Chain = Load.getValue(1);<br>-<br>- // Call target must be on T9<br>- Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag);<br>- } else<br>- /// Indirect call<br>
- Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag);<br>-<br>- // Map the JmpLink operands to JALR<br>- SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue);<br>- SmallVector<SDValue, 8> Ops;<br>
- Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32));<br>-<br>- for (unsigned i = 2, e = LastOpNum+1; i != e; ++i)<br>- Ops.push_back(Node->getOperand(i));<br>- Ops.push_back(Chain);<br>
- Ops.push_back(Chain.getValue(1));<br>-<br>- // Emit Jump and Link Register<br>- SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys,<br>- &Ops[0], Ops.size());<br>
-<br>- // Replace Chain and InFlag<br>- ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));<br>- ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1));<br>- return ResNode;<br>- }<br>- }<br>
}<br><br> // Select the default instruction<br>Index: lib/Target/Mips/MipsISelLowering.cpp<br>===================================================================<br>--- lib/Target/Mips/MipsISelLowering.cpp (revision 128741)<br>
+++ lib/Target/Mips/MipsISelLowering.cpp (working copy)<br>@@ -1201,13 +1201,35 @@<br> // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol<br> // node so that legalize doesn't hack it.<br> unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG;<br>
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))<br>+ bool LoadSymAddr = false;<br>+<br>+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {<br> Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,<br>
- getPointerTy(), 0, OpFlag);<br>- else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))<br>+ getPointerTy(), 0, OpFlag);<br>
+ LoadSymAddr = true;<br>+ }<br>+ else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {<br> Callee = DAG.getTargetExternalSymbol(S->getSymbol(),<br> getPointerTy(), OpFlag);<br>
+ LoadSymAddr = true;<br>+ }<br><br>+ // Create nodes that load address of callee and copy it to T9<br>+ if (IsPIC) {<br>+ if (LoadSymAddr) {<br>+ // load callee address<br>+ Callee = DAG.getLoad(MVT::i32, dl, Chain, Callee,<br>
+ MachinePointerInfo::getGOT(),<br>+ false, false, 0);<br>+ Chain = Callee.getValue(1);<br>+ }<br>+<br>+ // copy to T9<br>+ Chain = DAG.getCopyToReg(Chain, dl, Mips::T9, Callee, SDValue(0, 0));<br>
+ InFlag = Chain.getValue(1);<br>+ Callee = DAG.getRegister(Mips::T9, MVT::i32);<br>+ }<br>+<br> // MipsJmpLink = #chain, #target_address, #opt_in_flags...<br> // = Chain, Callee, Reg#1, Reg#2, ...<br>
//<br> <br></span></font>