Mercurial > pub > dyncall > dyncall
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 |