diff options
author | Lubomir Litchev <llitchev@live.com> | 2015-02-19 11:42:30 -0800 |
---|---|---|
committer | Lubomir Litchev <lubol@microsoft.com> | 2015-10-20 14:20:36 -0700 |
commit | 378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5 (patch) | |
tree | b83aec8f77caeb9ca94c6d7505a548b93cdb7259 /src/vm/amd64/calldescrworkeramd64.S | |
parent | 3015ff7afb4936a1c5c5856daa4e3482e6b390a9 (diff) | |
download | coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.tar.gz coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.tar.bz2 coreclr-378e304f9e22b3c4d03c3b1b62c47b0aa58ceaf5.zip |
Implementation of System V ABI struct passing.
This PR adds support for System V x86_64 ABI classification and calling
convention to the VM and the Jit, including, but not limited to Ubuntu
Linux and Mac OS X.
The general rules outlined in the System V x86_64 ABI (described at
http://www.x86-64.org/documentation/abi.pdf) are followed with a few
little exceptions, described below:
1. The hidden argument for by-value passed structs is always after
the ÎéÎíthisÎéÎí parameter (if there is one.). This is a difference with
the Sysetem V ABI and affects only the internal jit calling conventions.
For PInvoke calls the hidden argument is always the first parameter since
there is no ÎéÎíthisÎéÎí parameter in this case.
2. Managed structs that have no fields are always passed by-value on
the stack.
3. The jit proactively generates frame register frames (with RBP as a
frame register) in order to aid the native OS tooling for stack unwinding
and the like.
Diffstat (limited to 'src/vm/amd64/calldescrworkeramd64.S')
-rw-r--r-- | src/vm/amd64/calldescrworkeramd64.S | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/vm/amd64/calldescrworkeramd64.S b/src/vm/amd64/calldescrworkeramd64.S index efee6f325a..ca4fd703c6 100644 --- a/src/vm/amd64/calldescrworkeramd64.S +++ b/src/vm/amd64/calldescrworkeramd64.S @@ -108,11 +108,43 @@ LOCAL_LABEL(NoFloatArguments): je LOCAL_LABEL(ReturnsFloat) cmp ecx, 8 je LOCAL_LABEL(ReturnsDouble) - // unexpected + +#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) + // Struct with two integer eightbytes + cmp ecx, 16 + jne LOCAL_LABEL(NotTwoIntegerEightbytes) + mov qword ptr [rbx+CallDescrData__returnValue], rax + mov qword ptr [rbx+CallDescrData__returnValue + 8], rdx + jmp LOCAL_LABEL(Epilog) + +LOCAL_LABEL(NotTwoIntegerEightbytes): + // Struct with the first eightbyte SSE and the second one integer + cmp ecx, 16 + 1 + jne LOCAL_LABEL(NotFirstSSESecondIntegerEightbyte) + movsd real8 ptr [rbx+CallDescrData__returnValue], xmm0 + mov qword ptr [rbx+CallDescrData__returnValue + 8], rax + jmp LOCAL_LABEL(Epilog) + +LOCAL_LABEL(NotFirstSSESecondIntegerEightbyte): + // Struct with the first eightbyte integer and the second one SSE + cmp ecx, 16 + 2 + jne LOCAL_LABEL(NotFirstIntegerSecondSSEEightbyte) + mov qword ptr [rbx+CallDescrData__returnValue], rax + movsd real8 ptr [rbx+CallDescrData__returnValue + 8], xmm0 + jmp LOCAL_LABEL(Epilog) + +LOCAL_LABEL(NotFirstIntegerSecondSSEEightbyte): + // Struct with two SSE eightbytes + cmp ecx, 16 + 3 + jne LOCAL_LABEL(Epilog) // unexpected + movsd real8 ptr [rbx+CallDescrData__returnValue], xmm0 + movsd real8 ptr [rbx+CallDescrData__returnValue + 8], xmm1 +#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING + jmp LOCAL_LABEL(Epilog) LOCAL_LABEL(ReturnsInt): - mov [rbx+CallDescrData__returnValue], rax + mov qword ptr [rbx+CallDescrData__returnValue], rax LOCAL_LABEL(Epilog): lea rsp, [rbp - 8] // deallocate arguments |