]>
Commit | Line | Data |
---|---|---|
1 | /* ----------------------------------------------------------------------- | |
2 | sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com> | |
3 | Copyright (c) 2008 Red Hat, Inc. | |
4 | ||
5 | PowerPC64 Assembly glue. | |
6 | ||
7 | Permission is hereby granted, free of charge, to any person obtaining | |
8 | a copy of this software and associated documentation files (the | |
9 | ``Software''), to deal in the Software without restriction, including | |
10 | without limitation the rights to use, copy, modify, merge, publish, | |
11 | distribute, sublicense, and/or sell copies of the Software, and to | |
12 | permit persons to whom the Software is furnished to do so, subject to | |
13 | the following conditions: | |
14 | ||
15 | The above copyright notice and this permission notice shall be included | |
16 | in all copies or substantial portions of the Software. | |
17 | ||
18 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, | |
19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
25 | DEALINGS IN THE SOFTWARE. | |
26 | ----------------------------------------------------------------------- */ | |
27 | #define LIBFFI_ASM | |
28 | #include <fficonfig.h> | |
29 | #include <ffi.h> | |
30 | ||
31 | .file "linux64_closure.S" | |
32 | ||
33 | .machine altivec | |
34 | ||
35 | #ifdef POWERPC64 | |
36 | FFI_HIDDEN (ffi_closure_LINUX64) | |
37 | .globl ffi_closure_LINUX64 | |
38 | .text | |
39 | .cfi_startproc | |
40 | # if _CALL_ELF == 2 | |
41 | ffi_closure_LINUX64: | |
42 | # ifndef __PCREL__ | |
43 | addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha | |
44 | addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l | |
45 | # endif | |
46 | .localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64 | |
47 | # else | |
48 | .section ".opd","aw" | |
49 | .align 3 | |
50 | ffi_closure_LINUX64: | |
51 | # ifdef _CALL_LINUX | |
52 | .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 | |
53 | .type ffi_closure_LINUX64,@function | |
54 | .text | |
55 | .L.ffi_closure_LINUX64: | |
56 | # else | |
57 | FFI_HIDDEN (.ffi_closure_LINUX64) | |
58 | .globl .ffi_closure_LINUX64 | |
59 | .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 | |
60 | .size ffi_closure_LINUX64,24 | |
61 | .type .ffi_closure_LINUX64,@function | |
62 | .text | |
63 | .ffi_closure_LINUX64: | |
64 | # endif | |
65 | # endif | |
66 | ||
67 | # if _CALL_ELF == 2 | |
68 | # ifdef __VEC__ | |
69 | # 32 byte special reg save area + 64 byte parm save area | |
70 | # + 128 byte retval area + 13*8 fpr save area + 12*16 vec save area + round to 16 | |
71 | # define STACKFRAME 528 | |
72 | # else | |
73 | # 32 byte special reg save area + 64 byte parm save area | |
74 | # + 64 byte retval area + 13*8 fpr save area + round to 16 | |
75 | # define STACKFRAME 272 | |
76 | # endif | |
77 | # define PARMSAVE 32 | |
78 | # define RETVAL PARMSAVE+64 | |
79 | # else | |
80 | # 48 bytes special reg save area + 64 bytes parm save area | |
81 | # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 | |
82 | # define STACKFRAME 240 | |
83 | # define PARMSAVE 48 | |
84 | # define RETVAL PARMSAVE+64 | |
85 | # endif | |
86 | ||
87 | # if _CALL_ELF == 2 | |
88 | ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif | |
89 | mflr %r0 | |
90 | lwz %r12, 28(%r12) # cif->flags | |
91 | mtcrf 0x40, %r12 | |
92 | addi %r12, %r1, PARMSAVE | |
93 | bt 7, 0f | |
94 | # Our caller has not allocated a parameter save area. | |
95 | # We need to allocate one here and use it to pass gprs to | |
96 | # ffi_closure_helper_LINUX64. | |
97 | addi %r12, %r1, -STACKFRAME+PARMSAVE | |
98 | 0: | |
99 | # Save general regs into parm save area | |
100 | std %r3, 0(%r12) | |
101 | std %r4, 8(%r12) | |
102 | std %r5, 16(%r12) | |
103 | std %r6, 24(%r12) | |
104 | std %r7, 32(%r12) | |
105 | std %r8, 40(%r12) | |
106 | std %r9, 48(%r12) | |
107 | std %r10, 56(%r12) | |
108 | ||
109 | # load up the pointer to the parm save area | |
110 | mr %r7, %r12 | |
111 | # else | |
112 | # copy r2 to r11 and load TOC into r2 | |
113 | mr %r11, %r2 | |
114 | ld %r2, 16(%r2) | |
115 | ||
116 | mflr %r0 | |
117 | # Save general regs into parm save area | |
118 | # This is the parameter save area set up by our caller. | |
119 | std %r3, PARMSAVE+0(%r1) | |
120 | std %r4, PARMSAVE+8(%r1) | |
121 | std %r5, PARMSAVE+16(%r1) | |
122 | std %r6, PARMSAVE+24(%r1) | |
123 | std %r7, PARMSAVE+32(%r1) | |
124 | std %r8, PARMSAVE+40(%r1) | |
125 | std %r9, PARMSAVE+48(%r1) | |
126 | std %r10, PARMSAVE+56(%r1) | |
127 | ||
128 | # load up the pointer to the parm save area | |
129 | addi %r7, %r1, PARMSAVE | |
130 | # endif | |
131 | std %r0, 16(%r1) | |
132 | ||
133 | # closure->cif | |
134 | ld %r3, FFI_TRAMPOLINE_SIZE(%r11) | |
135 | # closure->fun | |
136 | ld %r4, FFI_TRAMPOLINE_SIZE+8(%r11) | |
137 | # closure->user_data | |
138 | ld %r5, FFI_TRAMPOLINE_SIZE+16(%r11) | |
139 | ||
140 | .Ldoclosure: | |
141 | # next save fpr 1 to fpr 13 | |
142 | stfd %f1, -104+(0*8)(%r1) | |
143 | stfd %f2, -104+(1*8)(%r1) | |
144 | stfd %f3, -104+(2*8)(%r1) | |
145 | stfd %f4, -104+(3*8)(%r1) | |
146 | stfd %f5, -104+(4*8)(%r1) | |
147 | stfd %f6, -104+(5*8)(%r1) | |
148 | stfd %f7, -104+(6*8)(%r1) | |
149 | stfd %f8, -104+(7*8)(%r1) | |
150 | stfd %f9, -104+(8*8)(%r1) | |
151 | stfd %f10, -104+(9*8)(%r1) | |
152 | stfd %f11, -104+(10*8)(%r1) | |
153 | stfd %f12, -104+(11*8)(%r1) | |
154 | stfd %f13, -104+(12*8)(%r1) | |
155 | ||
156 | # load up the pointer to the saved fpr registers | |
157 | addi %r8, %r1, -104 | |
158 | ||
159 | # ifdef __VEC__ | |
160 | # load up the pointer to the saved vector registers | |
161 | # 8 bytes padding for 16-byte alignment at -112(%r1) | |
162 | addi %r9, %r8, -24 | |
163 | stvx %v13, 0, %r9 | |
164 | addi %r9, %r9, -16 | |
165 | stvx %v12, 0, %r9 | |
166 | addi %r9, %r9, -16 | |
167 | stvx %v11, 0, %r9 | |
168 | addi %r9, %r9, -16 | |
169 | stvx %v10, 0, %r9 | |
170 | addi %r9, %r9, -16 | |
171 | stvx %v9, 0, %r9 | |
172 | addi %r9, %r9, -16 | |
173 | stvx %v8, 0, %r9 | |
174 | addi %r9, %r9, -16 | |
175 | stvx %v7, 0, %r9 | |
176 | addi %r9, %r9, -16 | |
177 | stvx %v6, 0, %r9 | |
178 | addi %r9, %r9, -16 | |
179 | stvx %v5, 0, %r9 | |
180 | addi %r9, %r9, -16 | |
181 | stvx %v4, 0, %r9 | |
182 | addi %r9, %r9, -16 | |
183 | stvx %v3, 0, %r9 | |
184 | addi %r9, %r9, -16 | |
185 | stvx %v2, 0, %r9 | |
186 | # endif | |
187 | ||
188 | # load up the pointer to the result storage | |
189 | addi %r6, %r1, -STACKFRAME+RETVAL | |
190 | ||
191 | stdu %r1, -STACKFRAME(%r1) | |
192 | .cfi_def_cfa_offset STACKFRAME | |
193 | .cfi_offset 65, 16 | |
194 | ||
195 | # make the call | |
196 | # if defined _CALL_LINUX || _CALL_ELF == 2 | |
197 | # ifdef __PCREL__ | |
198 | bl ffi_closure_helper_LINUX64@notoc | |
199 | .Lret: | |
200 | # else | |
201 | bl ffi_closure_helper_LINUX64 | |
202 | .Lret: | |
203 | nop | |
204 | # endif | |
205 | # else | |
206 | bl .ffi_closure_helper_LINUX64 | |
207 | .Lret: | |
208 | nop | |
209 | # endif | |
210 | ||
211 | # now r3 contains the return type | |
212 | # so use it to look up in a table | |
213 | # so we know how to deal with each type | |
214 | ||
215 | # look up the proper starting point in table | |
216 | # by using return type as offset | |
217 | ld %r0, STACKFRAME+16(%r1) | |
218 | cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT | |
219 | bge .Lsmall | |
220 | mflr %r4 # move address of .Lret to r4 | |
221 | sldi %r3, %r3, 4 # now multiply return type by 16 | |
222 | addi %r4, %r4, .Lret_type0 - .Lret | |
223 | add %r3, %r3, %r4 # add contents of table to table address | |
224 | mtctr %r3 | |
225 | bctr # jump to it | |
226 | ||
227 | # Each of the ret_typeX code fragments has to be exactly 16 bytes long | |
228 | # (4 instructions). For cache effectiveness we align to a 16 byte boundary | |
229 | # first. | |
230 | .align 4 | |
231 | ||
232 | .Lret_type0: | |
233 | # case FFI_TYPE_VOID | |
234 | mtlr %r0 | |
235 | addi %r1, %r1, STACKFRAME | |
236 | .cfi_def_cfa_offset 0 | |
237 | blr | |
238 | .cfi_def_cfa_offset STACKFRAME | |
239 | nop | |
240 | # case FFI_TYPE_INT | |
241 | # ifdef __LITTLE_ENDIAN__ | |
242 | lwa %r3, RETVAL+0(%r1) | |
243 | # else | |
244 | lwa %r3, RETVAL+4(%r1) | |
245 | # endif | |
246 | mtlr %r0 | |
247 | addi %r1, %r1, STACKFRAME | |
248 | .cfi_def_cfa_offset 0 | |
249 | blr | |
250 | .cfi_def_cfa_offset STACKFRAME | |
251 | # case FFI_TYPE_FLOAT | |
252 | lfs %f1, RETVAL+0(%r1) | |
253 | mtlr %r0 | |
254 | addi %r1, %r1, STACKFRAME | |
255 | .cfi_def_cfa_offset 0 | |
256 | blr | |
257 | .cfi_def_cfa_offset STACKFRAME | |
258 | # case FFI_TYPE_DOUBLE | |
259 | lfd %f1, RETVAL+0(%r1) | |
260 | mtlr %r0 | |
261 | addi %r1, %r1, STACKFRAME | |
262 | .cfi_def_cfa_offset 0 | |
263 | blr | |
264 | .cfi_def_cfa_offset STACKFRAME | |
265 | # case FFI_TYPE_LONGDOUBLE | |
266 | lfd %f1, RETVAL+0(%r1) | |
267 | mtlr %r0 | |
268 | lfd %f2, RETVAL+8(%r1) | |
269 | b .Lfinish | |
270 | # case FFI_TYPE_UINT8 | |
271 | # ifdef __LITTLE_ENDIAN__ | |
272 | lbz %r3, RETVAL+0(%r1) | |
273 | # else | |
274 | lbz %r3, RETVAL+7(%r1) | |
275 | # endif | |
276 | mtlr %r0 | |
277 | addi %r1, %r1, STACKFRAME | |
278 | .cfi_def_cfa_offset 0 | |
279 | blr | |
280 | .cfi_def_cfa_offset STACKFRAME | |
281 | # case FFI_TYPE_SINT8 | |
282 | # ifdef __LITTLE_ENDIAN__ | |
283 | lbz %r3, RETVAL+0(%r1) | |
284 | # else | |
285 | lbz %r3, RETVAL+7(%r1) | |
286 | # endif | |
287 | extsb %r3,%r3 | |
288 | mtlr %r0 | |
289 | b .Lfinish | |
290 | # case FFI_TYPE_UINT16 | |
291 | # ifdef __LITTLE_ENDIAN__ | |
292 | lhz %r3, RETVAL+0(%r1) | |
293 | # else | |
294 | lhz %r3, RETVAL+6(%r1) | |
295 | # endif | |
296 | mtlr %r0 | |
297 | .Lfinish: | |
298 | addi %r1, %r1, STACKFRAME | |
299 | .cfi_def_cfa_offset 0 | |
300 | blr | |
301 | .cfi_def_cfa_offset STACKFRAME | |
302 | # case FFI_TYPE_SINT16 | |
303 | # ifdef __LITTLE_ENDIAN__ | |
304 | lha %r3, RETVAL+0(%r1) | |
305 | # else | |
306 | lha %r3, RETVAL+6(%r1) | |
307 | # endif | |
308 | mtlr %r0 | |
309 | addi %r1, %r1, STACKFRAME | |
310 | .cfi_def_cfa_offset 0 | |
311 | blr | |
312 | .cfi_def_cfa_offset STACKFRAME | |
313 | # case FFI_TYPE_UINT32 | |
314 | # ifdef __LITTLE_ENDIAN__ | |
315 | lwz %r3, RETVAL+0(%r1) | |
316 | # else | |
317 | lwz %r3, RETVAL+4(%r1) | |
318 | # endif | |
319 | mtlr %r0 | |
320 | addi %r1, %r1, STACKFRAME | |
321 | .cfi_def_cfa_offset 0 | |
322 | blr | |
323 | .cfi_def_cfa_offset STACKFRAME | |
324 | # case FFI_TYPE_SINT32 | |
325 | # ifdef __LITTLE_ENDIAN__ | |
326 | lwa %r3, RETVAL+0(%r1) | |
327 | # else | |
328 | lwa %r3, RETVAL+4(%r1) | |
329 | # endif | |
330 | mtlr %r0 | |
331 | addi %r1, %r1, STACKFRAME | |
332 | .cfi_def_cfa_offset 0 | |
333 | blr | |
334 | .cfi_def_cfa_offset STACKFRAME | |
335 | # case FFI_TYPE_UINT64 | |
336 | ld %r3, RETVAL+0(%r1) | |
337 | mtlr %r0 | |
338 | addi %r1, %r1, STACKFRAME | |
339 | .cfi_def_cfa_offset 0 | |
340 | blr | |
341 | .cfi_def_cfa_offset STACKFRAME | |
342 | # case FFI_TYPE_SINT64 | |
343 | ld %r3, RETVAL+0(%r1) | |
344 | mtlr %r0 | |
345 | addi %r1, %r1, STACKFRAME | |
346 | .cfi_def_cfa_offset 0 | |
347 | blr | |
348 | .cfi_def_cfa_offset STACKFRAME | |
349 | # case FFI_TYPE_STRUCT | |
350 | mtlr %r0 | |
351 | addi %r1, %r1, STACKFRAME | |
352 | .cfi_def_cfa_offset 0 | |
353 | blr | |
354 | .cfi_def_cfa_offset STACKFRAME | |
355 | nop | |
356 | # case FFI_TYPE_POINTER | |
357 | ld %r3, RETVAL+0(%r1) | |
358 | mtlr %r0 | |
359 | addi %r1, %r1, STACKFRAME | |
360 | .cfi_def_cfa_offset 0 | |
361 | blr | |
362 | .cfi_def_cfa_offset STACKFRAME | |
363 | # case FFI_V2_TYPE_VECTOR | |
364 | addi %r3, %r1, RETVAL | |
365 | lvx %v2, 0, %r3 | |
366 | mtlr %r0 | |
367 | b .Lfinish | |
368 | # case FFI_V2_TYPE_VECTOR_HOMOG | |
369 | addi %r3, %r1, RETVAL | |
370 | lvx %v2, 0, %r3 | |
371 | addi %r3, %r3, 16 | |
372 | b .Lmorevector | |
373 | # case FFI_V2_TYPE_FLOAT_HOMOG | |
374 | lfs %f1, RETVAL+0(%r1) | |
375 | lfs %f2, RETVAL+4(%r1) | |
376 | lfs %f3, RETVAL+8(%r1) | |
377 | b .Lmorefloat | |
378 | # case FFI_V2_TYPE_DOUBLE_HOMOG | |
379 | lfd %f1, RETVAL+0(%r1) | |
380 | lfd %f2, RETVAL+8(%r1) | |
381 | lfd %f3, RETVAL+16(%r1) | |
382 | lfd %f4, RETVAL+24(%r1) | |
383 | mtlr %r0 | |
384 | lfd %f5, RETVAL+32(%r1) | |
385 | lfd %f6, RETVAL+40(%r1) | |
386 | lfd %f7, RETVAL+48(%r1) | |
387 | lfd %f8, RETVAL+56(%r1) | |
388 | addi %r1, %r1, STACKFRAME | |
389 | .cfi_def_cfa_offset 0 | |
390 | blr | |
391 | .cfi_def_cfa_offset STACKFRAME | |
392 | .Lmorevector: | |
393 | lvx %v3, 0, %r3 | |
394 | addi %r3, %r3, 16 | |
395 | lvx %v4, 0, %r3 | |
396 | addi %r3, %r3, 16 | |
397 | lvx %v5, 0, %r3 | |
398 | mtlr %r0 | |
399 | addi %r3, %r3, 16 | |
400 | lvx %v6, 0, %r3 | |
401 | addi %r3, %r3, 16 | |
402 | lvx %v7, 0, %r3 | |
403 | addi %r3, %r3, 16 | |
404 | lvx %v8, 0, %r3 | |
405 | addi %r3, %r3, 16 | |
406 | lvx %v9, 0, %r3 | |
407 | addi %r1, %r1, STACKFRAME | |
408 | .cfi_def_cfa_offset 0 | |
409 | blr | |
410 | .cfi_def_cfa_offset STACKFRAME | |
411 | .Lmorefloat: | |
412 | lfs %f4, RETVAL+12(%r1) | |
413 | mtlr %r0 | |
414 | lfs %f5, RETVAL+16(%r1) | |
415 | lfs %f6, RETVAL+20(%r1) | |
416 | lfs %f7, RETVAL+24(%r1) | |
417 | lfs %f8, RETVAL+28(%r1) | |
418 | addi %r1, %r1, STACKFRAME | |
419 | .cfi_def_cfa_offset 0 | |
420 | blr | |
421 | .cfi_def_cfa_offset STACKFRAME | |
422 | .Lsmall: | |
423 | # ifdef __LITTLE_ENDIAN__ | |
424 | ld %r3,RETVAL+0(%r1) | |
425 | mtlr %r0 | |
426 | ld %r4,RETVAL+8(%r1) | |
427 | addi %r1, %r1, STACKFRAME | |
428 | .cfi_def_cfa_offset 0 | |
429 | blr | |
430 | # else | |
431 | # A struct smaller than a dword is returned in the low bits of r3 | |
432 | # ie. right justified. Larger structs are passed left justified | |
433 | # in r3 and r4. The return value area on the stack will have | |
434 | # the structs as they are usually stored in memory. | |
435 | cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes? | |
436 | neg %r5, %r3 | |
437 | ld %r3,RETVAL+0(%r1) | |
438 | blt .Lsmalldown | |
439 | mtlr %r0 | |
440 | ld %r4,RETVAL+8(%r1) | |
441 | addi %r1, %r1, STACKFRAME | |
442 | .cfi_def_cfa_offset 0 | |
443 | blr | |
444 | .cfi_def_cfa_offset STACKFRAME | |
445 | .Lsmalldown: | |
446 | addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 | |
447 | mtlr %r0 | |
448 | sldi %r5, %r5, 3 | |
449 | addi %r1, %r1, STACKFRAME | |
450 | .cfi_def_cfa_offset 0 | |
451 | srd %r3, %r3, %r5 | |
452 | blr | |
453 | # endif | |
454 | ||
455 | .cfi_endproc | |
456 | # if _CALL_ELF == 2 | |
457 | .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 | |
458 | # else | |
459 | # ifdef _CALL_LINUX | |
460 | .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 | |
461 | # else | |
462 | .long 0 | |
463 | .byte 0,12,0,1,128,0,0,0 | |
464 | .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 | |
465 | # endif | |
466 | # endif | |
467 | ||
468 | ||
469 | FFI_HIDDEN (ffi_go_closure_linux64) | |
470 | .globl ffi_go_closure_linux64 | |
471 | .text | |
472 | .cfi_startproc | |
473 | # if _CALL_ELF == 2 | |
474 | ffi_go_closure_linux64: | |
475 | # ifndef __PCREL__ | |
476 | addis %r2, %r12, .TOC.-ffi_go_closure_linux64@ha | |
477 | addi %r2, %r2, .TOC.-ffi_go_closure_linux64@l | |
478 | # endif | |
479 | .localentry ffi_go_closure_linux64, . - ffi_go_closure_linux64 | |
480 | # else | |
481 | .section ".opd","aw" | |
482 | .align 3 | |
483 | ffi_go_closure_linux64: | |
484 | # ifdef _CALL_LINUX | |
485 | .quad .L.ffi_go_closure_linux64,.TOC.@tocbase,0 | |
486 | .type ffi_go_closure_linux64,@function | |
487 | .text | |
488 | .L.ffi_go_closure_linux64: | |
489 | # else | |
490 | FFI_HIDDEN (.ffi_go_closure_linux64) | |
491 | .globl .ffi_go_closure_linux64 | |
492 | .quad .ffi_go_closure_linux64,.TOC.@tocbase,0 | |
493 | .size ffi_go_closure_linux64,24 | |
494 | .type .ffi_go_closure_linux64,@function | |
495 | .text | |
496 | .ffi_go_closure_linux64: | |
497 | # endif | |
498 | # endif | |
499 | ||
500 | # if _CALL_ELF == 2 | |
501 | ld %r12, 8(%r11) # closure->cif | |
502 | mflr %r0 | |
503 | lwz %r12, 28(%r12) # cif->flags | |
504 | mtcrf 0x40, %r12 | |
505 | addi %r12, %r1, PARMSAVE | |
506 | bt 7, 0f | |
507 | # Our caller has not allocated a parameter save area. | |
508 | # We need to allocate one here and use it to pass gprs to | |
509 | # ffi_closure_helper_LINUX64. | |
510 | addi %r12, %r1, -STACKFRAME+PARMSAVE | |
511 | 0: | |
512 | # Save general regs into parm save area | |
513 | std %r3, 0(%r12) | |
514 | std %r4, 8(%r12) | |
515 | std %r5, 16(%r12) | |
516 | std %r6, 24(%r12) | |
517 | std %r7, 32(%r12) | |
518 | std %r8, 40(%r12) | |
519 | std %r9, 48(%r12) | |
520 | std %r10, 56(%r12) | |
521 | ||
522 | # load up the pointer to the parm save area | |
523 | mr %r7, %r12 | |
524 | # else | |
525 | mflr %r0 | |
526 | # Save general regs into parm save area | |
527 | # This is the parameter save area set up by our caller. | |
528 | std %r3, PARMSAVE+0(%r1) | |
529 | std %r4, PARMSAVE+8(%r1) | |
530 | std %r5, PARMSAVE+16(%r1) | |
531 | std %r6, PARMSAVE+24(%r1) | |
532 | std %r7, PARMSAVE+32(%r1) | |
533 | std %r8, PARMSAVE+40(%r1) | |
534 | std %r9, PARMSAVE+48(%r1) | |
535 | std %r10, PARMSAVE+56(%r1) | |
536 | ||
537 | # load up the pointer to the parm save area | |
538 | addi %r7, %r1, PARMSAVE | |
539 | # endif | |
540 | std %r0, 16(%r1) | |
541 | ||
542 | # closure->cif | |
543 | ld %r3, 8(%r11) | |
544 | # closure->fun | |
545 | ld %r4, 16(%r11) | |
546 | # user_data | |
547 | mr %r5, %r11 | |
548 | b .Ldoclosure | |
549 | ||
550 | .cfi_endproc | |
551 | # if _CALL_ELF == 2 | |
552 | .size ffi_go_closure_linux64,.-ffi_go_closure_linux64 | |
553 | # else | |
554 | # ifdef _CALL_LINUX | |
555 | .size ffi_go_closure_linux64,.-.L.ffi_go_closure_linux64 | |
556 | # else | |
557 | .long 0 | |
558 | .byte 0,12,0,1,128,0,0,0 | |
559 | .size .ffi_go_closure_linux64,.-.ffi_go_closure_linux64 | |
560 | # endif | |
561 | # endif | |
562 | #endif | |
563 | ||
564 | #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 | |
565 | .section .note.GNU-stack,"",@progbits | |
566 | #endif |