Mercurial > pub > dyncall > dyncall
comparison dyncall/dyncall_call_arm64.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | 450c4f06cb14 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3e629dc19168 |
---|---|
1 /* | |
2 | |
3 Package: dyncall | |
4 Library: dyncall | |
5 File: dyncall/dyncall_call_arm64.S | |
6 Description: Call Kernel for ARM 64-bit Architecture (aka ARM64, AArch64) | |
7 License: | |
8 | |
9 Copyright (c) 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 #include "../portasm/portasm-arm.S" | |
29 | |
30 /* ============================================================================ | |
31 DynCall Call Kernel for ARM 64-bit ARM Architecture | |
32 ---------------------------------------------------------------------------- | |
33 C Interface: | |
34 dcCall_arm64 (DCpointer target, DCpointer data, DCsize size, DCfloat* regdata); | |
35 | |
36 This Call Kernel was tested on Debian/qemu-debootstrap arm64 jessie. | |
37 */ | |
38 | |
39 .text | |
40 | |
41 // | |
42 // DynCall Back-End arm64 | |
43 // | |
44 // Supported ABIs: | |
45 // - 'ARM 64-bit AArch64 PCS' (@dadler: work in progress) | |
46 // | |
47 // Useful Links: | |
48 // - http://lxr.free-electrons.com/source/arch/arm64/kernel/stacktrace.c | |
49 | |
50 GLOBAL_C(dcCall_arm64) | |
51 ENTRY_C(dcCall_arm64) | |
52 | |
53 // input: | |
54 // x0: target (address of target) | |
55 // x1: data (address of stack copy data) | |
56 // x2: size (number of 'pair' 16-byte units) | |
57 // x3: regdata (address of register data) | |
58 | |
59 // prolog: | |
60 | |
61 stp x29, x30, [sp, #-16]! // allocate frame | |
62 mov x29, sp | |
63 | |
64 // load 64-bit floating-point registers | |
65 | |
66 ldr d0, [x3,#0 ] | |
67 ldr d1, [x3,#8 ] | |
68 ldr d2, [x3,#16] | |
69 ldr d3, [x3,#24] | |
70 ldr d4, [x3,#32] | |
71 ldr d5, [x3,#40] | |
72 ldr d6, [x3,#48] | |
73 ldr d7, [x3,#56] | |
74 | |
75 // copy to stack | |
76 | |
77 sub sp, sp, x2 // create call-frame | |
78 | |
79 eor x4, x4, x4 // x4: cnt = 0 | |
80 | |
81 mov x5, x1 // x5: read pointer = data | |
82 mov x6, sp // x6: write pointer = sp | |
83 | |
84 .next: | |
85 cmp x4, x2 | |
86 b.ge .done | |
87 | |
88 ldp x7, x9, [x5], #16 // get pair from data | |
89 stp x7, x9, [x6], #16 // put to stack | |
90 add x4, x4, 16 // advance 16 bytes | |
91 | |
92 b .next | |
93 | |
94 .done: | |
95 | |
96 // rescue temp int registers | |
97 | |
98 mov x9 , x0 // x9: target | |
99 add x10, x3, 64 // x3: integer reg buffer | |
100 | |
101 // load 64-bit integer registers ( 8 x 64-bit ) | |
102 | |
103 // load register set | |
104 | |
105 ldr x0, [x10, #0] | |
106 ldr x1, [x10, #8] | |
107 ldr x2, [x10, #16] | |
108 ldr x3, [x10, #24] | |
109 ldr x4, [x10, #32] | |
110 ldr x5, [x10, #40] | |
111 ldr x6, [x10, #48] | |
112 ldr x7, [x10, #56] | |
113 | |
114 // call target: | |
115 | |
116 blr x9 | |
117 | |
118 // epilog: | |
119 | |
120 mov sp, x29 | |
121 ldp x29, x30, [sp], 16 | |
122 | |
123 ret | |
124 | |
125 #if 0 | |
126 | |
127 | |
128 | |
129 // epilog: | |
130 | |
131 add sp, x28, 0 // remove call record | |
132 | |
133 ret | |
134 | |
135 // -- OLD: | |
136 | |
137 str x27, [sp, 16] // use 1 local var (size) | |
138 | |
139 | |
140 ldr q0, [x3,#0 ] | |
141 ldr q1, [x3,#8 ] | |
142 ldr q2, [x3,#16] | |
143 ldr q3, [x3,#24] | |
144 ldr q4, [x3,#32] | |
145 ldr q5, [x3,#40] | |
146 ldr q6, [x3,#48] | |
147 ldr q7, [x3,#56] | |
148 | |
149 ldr d8, [x3,#32] | |
150 ldr d9, [x3,#36] | |
151 ldr d10, [x3,#40] | |
152 ldr d11, [x3,#44] | |
153 ldr d12, [x3,#48] | |
154 ldr d13, [x3,#52] | |
155 ldr d14, [x3,#56] | |
156 ldr d15, [x3,#60] | |
157 | |
158 | |
159 // load float ( 16 x 32-bit ) | |
160 | |
161 ldr s0, [x3,#0 ] | |
162 ldr s1, [x3,#4 ] | |
163 ldr s2, [x3,#8 ] | |
164 ldr s3, [x3,#12] | |
165 ldr s4, [x3,#16] | |
166 ldr s5, [x3,#20] | |
167 ldr s6, [x3,#24] | |
168 ldr s7, [x3,#28] | |
169 ldr s8, [x3,#32] | |
170 ldr s9, [x3,#36] | |
171 ldr s10, [x3,#40] | |
172 ldr s11, [x3,#44] | |
173 ldr s12, [x3,#48] | |
174 ldr s13, [x3,#52] | |
175 ldr s14, [x3,#56] | |
176 ldr s15, [x3,#60] | |
177 | |
178 // call | |
179 | |
180 blr x0 | |
181 | |
182 // epilog | |
183 | |
184 ldp x29, x30, [sp], 32 | |
185 ret | |
186 | |
187 // stack copy | |
188 | |
189 sub sp, sp, x2 // decrement stack by size (x2) | |
190 eor x3, x3, x3 // x3 = counter, set to zero | |
191 | |
192 // .next: | |
193 ldr x4, [x1, x3] // x4 = 64-bit stack data | |
194 str x4, [sp, x3] // store to stack | |
195 add x3, x3, #8 | |
196 cmp x3, x2 | |
197 blt .next | |
198 | |
199 | |
200 // rescue int registers | |
201 | |
202 mov x9 , x0 // x9 = code ptr | |
203 mov x10, x2 | |
204 | |
205 // load int ( 8 x 64-bit ) | |
206 | |
207 ldr x0, [sp, #0] | |
208 ldr x1, [sp, #8] | |
209 ldr x2, [sp, #16] | |
210 ldr x3, [sp, #24] | |
211 ldr x4, [sp, #32] | |
212 ldr x5, [sp, #40] | |
213 ldr x6, [sp, #48] | |
214 ldr x7, [sp, #56] | |
215 | |
216 // call | |
217 | |
218 blr x9 | |
219 | |
220 // epilog | |
221 | |
222 ldp x29, x30, [sp], 32 | |
223 ret | |
224 #endif | |
225 | |
226 |