diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-05-09 22:32:13 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-05-09 22:32:13 +0000 |
commit | 805a83c0419aa453b78b2a062f46dc7f72137f79 (patch) | |
tree | 1c220d4b875a82dd2da92df79e139d57f13afc86 /lib/Target/Mips/MipsISelLowering.cpp | |
parent | b3275b9fca1f805fbd93dc6c473e85f533f9b217 (diff) | |
download | llvm-805a83c0419aa453b78b2a062f46dc7f72137f79.tar.gz llvm-805a83c0419aa453b78b2a062f46dc7f72137f79.tar.bz2 llvm-805a83c0419aa453b78b2a062f46dc7f72137f79.tar.xz |
Allow sret on the second parameter as well as the first
MSVC always places the implicit sret parameter after the implicit this
parameter of instance methods. We used to handle this for
x86_thiscallcc by allocating the sret parameter on the stack and leaving
the this pointer in ecx, but that doesn't handle alternative calling
conventions like cdecl, stdcall, fastcall, or the win64 convention.
Instead, change the verifier to allow sret on the second parameter.
This also requires changing the Mips and X86 backends to return the
argument with the sret parameter, instead of assuming that the sret
parameter comes first.
The Sparc backend also returns sret parameters in a register, but I
wasn't able to update it to handle secondary sret parameters. It
currently calls report_fatal_error if you feed it an sret in the second
parameter.
Reviewers: rafael.espindola, majnemer
Differential Revision: http://reviews.llvm.org/D3617
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsISelLowering.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index d152e6781a..ddcbb60ba9 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2659,20 +2659,21 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, InVals.push_back(Load); OutChains.push_back(Load.getValue(1)); } - } - // The mips ABIs for returning structs by value requires that we copy - // the sret argument into $v0 for the return. Save the argument into - // a virtual register so that we can access it from the return points. - if (DAG.getMachineFunction().getFunction()->hasStructRetAttr()) { - unsigned Reg = MipsFI->getSRetReturnReg(); - if (!Reg) { - Reg = MF.getRegInfo().createVirtualRegister( - getRegClassFor(isN64() ? MVT::i64 : MVT::i32)); - MipsFI->setSRetReturnReg(Reg); + // The mips ABIs for returning structs by value requires that we copy + // the sret argument into $v0 for the return. Save the argument into + // a virtual register so that we can access it from the return points. + if (Flags.isSRet()) { + unsigned Reg = MipsFI->getSRetReturnReg(); + if (!Reg) { + Reg = MF.getRegInfo().createVirtualRegister( + getRegClassFor(isN64() ? MVT::i64 : MVT::i32)); + MipsFI->setSRetReturnReg(Reg); + } + SDValue Copy = + DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals.back()); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain); } - SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]); - Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain); } if (IsVarArg) |