comparison test/gen-masm/call_x64.S @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children f5577f6bf97a
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: test
5 File: test/gen-masm/call_x64.S
6 Description:
7 License:
8
9 Copyright (c) 2011-2015 Daniel Adler <dadler@uni-goettingen.de>,
10 Tassilo Philipp <tphilipp@potion-studios.com>
11
12 Permission to use, copy, modify, and distribute this software for any
13 purpose with or without fee is hereby granted, provided that the above
14 copyright notice and this permission notice appear in all copies.
15
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24 */
25
26
27
28 #if defined(GEN_MASM)
29 .CODE
30 # define BEGIN_ASM
31 # define END_ASM END
32 # define GLOBAL(X) X PROC
33 # define BEGIN_PROC(X) OPTION PROLOGUE:NONE, EPILOGUE:NONE
34 # define END_PROC(X) X ENDP
35 #else
36 .intel_syntax
37 .text
38 # define BEGIN_ASM
39 # define END_ASM
40 # define GLOBAL(X) .globl X
41 # define BEGIN_PROC(X) X:
42 # define END_PROC(X)
43 #endif
44
45 BEGIN_ASM
46
47 // ---------------------------------------------------------------------------
48 // Call Kernel for x64 System V
49
50 GLOBAL(dcCall_x64_sysv)
51 BEGIN_PROC(dcCall_x64_sysv)
52 // rdi : size of arguments to be passed via stack
53 // rsi : pointer to arguments to be passed via the stack
54 // rdx : pointer to arguments of integral/pointer type to be passed via registers
55 // rcx : pointer to arguments of floating point type to be passed via registers
56 // r8 : target function pointer
57
58 push rbp // Pseudo-prolog - preserve rbp.
59 push rbx // Preserve rbx and store pointer to function in it.
60
61 mov rbp, rsp // Store stack pointer in rbp.
62
63 mov rbx, r8
64
65 movsd xmm0, qword ptr[rcx ] // Copy first 8 floats to xmm0-xmm7 (this makes rcx free to use).
66 movsd xmm1, qword ptr[rcx+ 8]
67 movsd xmm2, qword ptr[rcx+16]
68 movsd xmm3, qword ptr[rcx+24]
69 movsd xmm4, qword ptr[rcx+32]
70 movsd xmm5, qword ptr[rcx+40]
71 movsd xmm6, qword ptr[rcx+48]
72 movsd xmm7, qword ptr[rcx+56]
73
74 sub rsp, rdi // Setup stack frame by subtracting the size of the arguments.
75
76 mov rax, rdi // Align stack.
77 add rax, 8
78 and rax, 15
79 sub rsp, rax
80
81 mov rcx, rdi // Store number of bytes to copy to stack in rcx (for rep movsb).
82 mov rdi, rsp // Store pointer to beginning of stack arguments in rdi (for rep movsb).
83
84 rep movsb // @@@ should be optimized (e.g. movq)
85
86 mov rdi, qword ptr[rdx ] // Copy first six int/pointer arguments to rdi, rsi, rdx, rcx, r8, r9.
87 mov rsi, qword ptr[rdx+ 8]
88 mov rcx, qword ptr[rdx+24]
89 mov r8, qword ptr[rdx+32]
90 mov r9, qword ptr[rdx+40]
91 mov rdx, qword ptr[rdx+16] /* Set rdx last to not overwrite it to soon. */
92
93 mov al, 8 /* Put upper bound of number of used xmm registers in al. */
94 call rbx /* Invoke function. */
95
96 mov rsp, rbp /* Restore stack pointer (such that we can pop the preserved values). */
97
98 pop rbx /* Restore rbx. */
99 pop rbp /* Pseudo-epilog. */
100
101 ret
102 END_PROC(dcCall_x64_sysv)
103
104 // ---------------------------------------------------------------------------
105 // Call Kernel for x64 Win64
106
107 GLOBAL(dcCall_x64_win64)
108 BEGIN_PROC(dcCall_x64_win64)
109 push rbp // Pseudo-prolog - preserve rbp.
110 push rsi // Preserve rsi and rdi.
111 push rdi
112
113 mov rbp, rsp // Store stack pointer in rbp.
114
115 sub rsp, rcx // Setup stack frame by subtracting the size of the arguments.
116
117 mov rax, rcx // Align stack.
118 add rax, 8
119 and rax, 15
120 sub rsp, rax
121
122 mov rsi, rdx // Let rsi point to the arguments.
123 mov rdi, rsp // Store pointer to beginning of stack arguments in rdi (for rep movsb).
124 mov rax, r9 // Put function address in rax.
125
126 rep movsb // @@@ should be optimized (e.g. movq)
127
128 mov rcx, qword ptr[r8 ] // Copy first four arguments to rcx, rdx, r8, r9 and xmm0-xmm3.
129 mov rdx, qword ptr[r8+ 8]
130 mov r9, qword ptr[r8+24] // Set r9 first to not overwrite r8 too soon.
131 mov r8, qword ptr[r8+16]
132 movd xmm0, rcx
133 movd xmm1, rdx
134 movd xmm2, r8
135 movd xmm3, r9
136
137 push r9 // Push first four arguments onto the stack preserve area.
138 push r8
139 push rdx
140 push rcx
141
142 call rax // Invoke function.
143
144 mov rsp, rbp // Restore stack pointer (such that we can pop the preserved values).
145
146 pop rdi // Restore rsi and rdi.
147 pop rsi
148 pop rbp // Pseudo-epilog.
149
150 ret
151 END_PROC(dcCall_x64_win64)
152
153 END_ASM
154