diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-01-12 03:18:21 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-01-12 03:18:21 +0000 |
commit | 7d29ffbe5b091fae03afd264d8c8b0090c7a45f4 (patch) | |
tree | d4e4f25b4f37226a2084330da98e01ab4977a64d /lib/Target/Sparc | |
parent | d2e905027b3774bbc29562a5e3f64ad46bf6b0b8 (diff) |
Fix SPARC backend call instruction so that arguments passed through registers
are correctly marked as used instead of passing all possible argument registers
as used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123301 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.cpp | 22 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 13 |
2 files changed, 24 insertions, 11 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 27e78f07da..ec8c7b4809 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -1,3 +1,4 @@ + //===-- SparcISelLowering.cpp - Sparc DAG Lowering Implementation ---------===// // // The LLVM Compiler Infrastructure @@ -514,11 +515,22 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee, else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); - std::vector<EVT> NodeTys; - NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use. - SDValue Ops[] = { Chain, Callee, InFlag }; - Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, Ops, InFlag.getNode() ? 3 : 2); + // Returns a chain & a flag for retval copy to use + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); + SmallVector<SDValue, 8> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + unsigned Reg = RegsToPass[i].first; + if (Reg >= SP::I0 && Reg <= SP::I7) + Reg = Reg-SP::I0+SP::O0; + + Ops.push_back(DAG.getRegister(Reg, RegsToPass[i].second.getValueType())); + } + if (InFlag.getNode()) + Ops.push_back(InFlag); + + Chain = DAG.getNode(SPISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true), diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 4877af8c8f..94e1f7adb1 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -119,9 +119,10 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; -def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; def call : SDNode<"SPISD::CALL", SDT_SPCall, - [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, + SDNPVariadic]>; def retflag : SDNode<"SPISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNPOptInGlue]>; @@ -517,11 +518,11 @@ let Uses = [FCC] in // Section B.24 - Call and Link Instruction, p. 125 // This is the only Format 1 instruction -let Uses = [O0, O1, O2, O3, O4, O5], +let Uses = [O6], hasDelaySlot = 1, isCall = 1, Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { - def CALL : InstSP<(outs), (ins calltarget:$dst), + def CALL : InstSP<(outs), (ins calltarget:$dst, variable_ops), "call $dst", []> { bits<30> disp; let op = 1; @@ -530,11 +531,11 @@ let Uses = [O0, O1, O2, O3, O4, O5], // indirect calls def JMPLrr : F3_1<2, 0b111000, - (outs), (ins MEMrr:$ptr), + (outs), (ins MEMrr:$ptr, variable_ops), "call $ptr", [(call ADDRrr:$ptr)]>; def JMPLri : F3_2<2, 0b111000, - (outs), (ins MEMri:$ptr), + (outs), (ins MEMri:$ptr, variable_ops), "call $ptr", [(call ADDRri:$ptr)]>; } |