/// 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 T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
- SDValue InFlag(0, 0);
+ SDValue InFlag;
+
+ // Skip the incomming flag if present
+ if (Node->getOperand(LastOpNum).getValueType() == MVT::Flag)
+ LastOpNum--;
if ( (isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)) )
Chain = Load.getValue(1);
// Call target must be on T9
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag);
} else
/// Indirect call
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag);
+
+ // Map the JmpLink operands to JALR
+ SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Flag);
+ 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, MVT::Other,
- MVT::Flag, T9Reg, Chain);
- Chain = SDValue(ResNode, 0);
- InFlag = SDValue(ResNode, 1);
- ReplaceUses(SDValue(Node, 0), Chain);
- ReplaceUses(SDValue(Node, 1), InFlag);
+ 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;
}
}
def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
// Call
-def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
- SDNPOutFlag]>;
+def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
+ [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
// Hi and Lo nodes are used to handle global addresses. Used on
// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
class JumpLink<bits<6> op, string instr_asm>:
FJ< op,
(outs),
- (ins calltarget:$target),
+ (ins calltarget:$target, variable_ops),
!strconcat(instr_asm, "\t$target"),
[(MipsJmpLink imm:$target)], IIBranch>;
FR< op,
func,
(outs),
- (ins CPURegs:$rs),
+ (ins CPURegs:$rs, variable_ops),
!strconcat(instr_asm, "\t$rs"),
[(MipsJmpLink CPURegs:$rs)], IIBranch>;
class BranchLink<string instr_asm>:
FI< 0x1,
(outs),
- (ins CPURegs:$rs, brtarget:$target),
+ (ins CPURegs:$rs, brtarget:$target, variable_ops),
!strconcat(instr_asm, "\t$rs, $target"),
[], IIBranch>;
}