]>
Commit | Line | Data |
---|---|---|
7446546a AH |
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 | ----------------------------------------------------------------------- */ | |
a733b15e | 27 | #define LIBFFI_ASM |
1450eb7a | 28 | #include <fficonfig.h> |
a733b15e JJ |
29 | #include <ffi.h> |
30 | ||
e9b84181 JJ |
31 | .file "linux64_closure.S" |
32 | ||
90205f67 SB |
33 | .machine altivec |
34 | ||
e73d2479 | 35 | #ifdef POWERPC64 |
8a42356f | 36 | FFI_HIDDEN (ffi_closure_LINUX64) |
7054d980 | 37 | .globl ffi_closure_LINUX64 |
3521ba8b | 38 | .text |
b1760f7f RH |
39 | .cfi_startproc |
40 | # if _CALL_ELF == 2 | |
3521ba8b | 41 | ffi_closure_LINUX64: |
08cd8d59 | 42 | # ifndef __PCREL__ |
3521ba8b AM |
43 | addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha |
44 | addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l | |
08cd8d59 | 45 | # endif |
3521ba8b AM |
46 | .localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64 |
47 | # else | |
16070e45 AT |
48 | .section ".opd","aw" |
49 | .align 3 | |
e9b84181 | 50 | ffi_closure_LINUX64: |
3521ba8b | 51 | # ifdef _CALL_LINUX |
7054d980 AM |
52 | .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 |
53 | .type ffi_closure_LINUX64,@function | |
54 | .text | |
55 | .L.ffi_closure_LINUX64: | |
3521ba8b | 56 | # else |
7054d980 AM |
57 | FFI_HIDDEN (.ffi_closure_LINUX64) |
58 | .globl .ffi_closure_LINUX64 | |
16070e45 AT |
59 | .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 |
60 | .size ffi_closure_LINUX64,24 | |
61 | .type .ffi_closure_LINUX64,@function | |
62 | .text | |
e9b84181 | 63 | .ffi_closure_LINUX64: |
3521ba8b AM |
64 | # endif |
65 | # endif | |
66 | ||
67 | # if _CALL_ELF == 2 | |
92456a4e L |
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 | |
3521ba8b | 77 | # define PARMSAVE 32 |
e73d2479 | 78 | # define RETVAL PARMSAVE+64 |
3521ba8b AM |
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 | ||
3521ba8b AM |
87 | # if _CALL_ELF == 2 |
88 | ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif | |
e9b84181 | 89 | mflr %r0 |
3521ba8b AM |
90 | lwz %r12, 28(%r12) # cif->flags |
91 | mtcrf 0x40, %r12 | |
92 | addi %r12, %r1, PARMSAVE | |
b1760f7f | 93 | bt 7, 0f |
3521ba8b AM |
94 | # Our caller has not allocated a parameter save area. |
95 | # We need to allocate one here and use it to pass gprs to | |
e73d2479 AM |
96 | # ffi_closure_helper_LINUX64. |
97 | addi %r12, %r1, -STACKFRAME+PARMSAVE | |
b1760f7f | 98 | 0: |
3521ba8b AM |
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 | |
b1760f7f | 110 | mr %r7, %r12 |
3521ba8b | 111 | # else |
b1760f7f RH |
112 | # copy r2 to r11 and load TOC into r2 |
113 | mr %r11, %r2 | |
114 | ld %r2, 16(%r2) | |
115 | ||
3521ba8b AM |
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) | |
e9b84181 | 127 | |
3521ba8b | 128 | # load up the pointer to the parm save area |
b1760f7f | 129 | addi %r7, %r1, PARMSAVE |
3521ba8b | 130 | # endif |
b1760f7f | 131 | std %r0, 16(%r1) |
e9b84181 | 132 | |
b1760f7f RH |
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: | |
e9b84181 | 141 | # next save fpr 1 to fpr 13 |
3521ba8b AM |
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) | |
e9b84181 | 155 | |
08cd8d59 | 156 | # load up the pointer to the saved fpr registers |
b1760f7f | 157 | addi %r8, %r1, -104 |
e9b84181 | 158 | |
92456a4e L |
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 | ||
3521ba8b | 188 | # load up the pointer to the result storage |
b1760f7f | 189 | addi %r6, %r1, -STACKFRAME+RETVAL |
e9b84181 | 190 | |
3521ba8b | 191 | stdu %r1, -STACKFRAME(%r1) |
b1760f7f RH |
192 | .cfi_def_cfa_offset STACKFRAME |
193 | .cfi_offset 65, 16 | |
e9b84181 JJ |
194 | |
195 | # make the call | |
3521ba8b | 196 | # if defined _CALL_LINUX || _CALL_ELF == 2 |
08cd8d59 AM |
197 | # ifdef __PCREL__ |
198 | bl ffi_closure_helper_LINUX64@notoc | |
fff56af6 | 199 | .Lret: |
08cd8d59 | 200 | # else |
7054d980 | 201 | bl ffi_closure_helper_LINUX64 |
fff56af6 | 202 | .Lret: |
08cd8d59 AM |
203 | nop |
204 | # endif | |
3521ba8b | 205 | # else |
e9b84181 | 206 | bl .ffi_closure_helper_LINUX64 |
fff56af6 | 207 | .Lret: |
08cd8d59 | 208 | nop |
3521ba8b | 209 | # endif |
e9b84181 JJ |
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 | ||
16070e45 | 215 | # look up the proper starting point in table |
e9b84181 | 216 | # by using return type as offset |
3521ba8b AM |
217 | ld %r0, STACKFRAME+16(%r1) |
218 | cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT | |
219 | bge .Lsmall | |
b00badcd | 220 | mflr %r4 # move address of .Lret to r4 |
e9b84181 | 221 | sldi %r3, %r3, 4 # now multiply return type by 16 |
b00badcd | 222 | addi %r4, %r4, .Lret_type0 - .Lret |
e9b84181 JJ |
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 | ||
e9b84181 JJ |
232 | .Lret_type0: |
233 | # case FFI_TYPE_VOID | |
b00badcd | 234 | mtlr %r0 |
3521ba8b | 235 | addi %r1, %r1, STACKFRAME |
b1760f7f | 236 | .cfi_def_cfa_offset 0 |
b00badcd | 237 | blr |
b1760f7f | 238 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 JJ |
239 | nop |
240 | # case FFI_TYPE_INT | |
3521ba8b AM |
241 | # ifdef __LITTLE_ENDIAN__ |
242 | lwa %r3, RETVAL+0(%r1) | |
243 | # else | |
244 | lwa %r3, RETVAL+4(%r1) | |
245 | # endif | |
b00badcd | 246 | mtlr %r0 |
3521ba8b | 247 | addi %r1, %r1, STACKFRAME |
b1760f7f | 248 | .cfi_def_cfa_offset 0 |
b00badcd | 249 | blr |
b1760f7f | 250 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 251 | # case FFI_TYPE_FLOAT |
3521ba8b | 252 | lfs %f1, RETVAL+0(%r1) |
b00badcd | 253 | mtlr %r0 |
3521ba8b | 254 | addi %r1, %r1, STACKFRAME |
b1760f7f | 255 | .cfi_def_cfa_offset 0 |
b00badcd | 256 | blr |
b1760f7f | 257 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 258 | # case FFI_TYPE_DOUBLE |
3521ba8b | 259 | lfd %f1, RETVAL+0(%r1) |
b00badcd | 260 | mtlr %r0 |
3521ba8b | 261 | addi %r1, %r1, STACKFRAME |
b1760f7f | 262 | .cfi_def_cfa_offset 0 |
b00badcd | 263 | blr |
b1760f7f | 264 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 265 | # case FFI_TYPE_LONGDOUBLE |
3521ba8b | 266 | lfd %f1, RETVAL+0(%r1) |
b00badcd | 267 | mtlr %r0 |
3521ba8b | 268 | lfd %f2, RETVAL+8(%r1) |
bf310028 | 269 | b .Lfinish |
e9b84181 | 270 | # case FFI_TYPE_UINT8 |
3521ba8b AM |
271 | # ifdef __LITTLE_ENDIAN__ |
272 | lbz %r3, RETVAL+0(%r1) | |
273 | # else | |
274 | lbz %r3, RETVAL+7(%r1) | |
275 | # endif | |
b00badcd | 276 | mtlr %r0 |
3521ba8b | 277 | addi %r1, %r1, STACKFRAME |
b1760f7f | 278 | .cfi_def_cfa_offset 0 |
b00badcd | 279 | blr |
b1760f7f | 280 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 281 | # case FFI_TYPE_SINT8 |
3521ba8b AM |
282 | # ifdef __LITTLE_ENDIAN__ |
283 | lbz %r3, RETVAL+0(%r1) | |
284 | # else | |
285 | lbz %r3, RETVAL+7(%r1) | |
286 | # endif | |
e9b84181 | 287 | extsb %r3,%r3 |
b00badcd | 288 | mtlr %r0 |
e9b84181 | 289 | b .Lfinish |
e9b84181 | 290 | # case FFI_TYPE_UINT16 |
3521ba8b AM |
291 | # ifdef __LITTLE_ENDIAN__ |
292 | lhz %r3, RETVAL+0(%r1) | |
293 | # else | |
294 | lhz %r3, RETVAL+6(%r1) | |
295 | # endif | |
b00badcd AM |
296 | mtlr %r0 |
297 | .Lfinish: | |
3521ba8b | 298 | addi %r1, %r1, STACKFRAME |
b1760f7f | 299 | .cfi_def_cfa_offset 0 |
b00badcd | 300 | blr |
b1760f7f | 301 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 302 | # case FFI_TYPE_SINT16 |
3521ba8b AM |
303 | # ifdef __LITTLE_ENDIAN__ |
304 | lha %r3, RETVAL+0(%r1) | |
305 | # else | |
306 | lha %r3, RETVAL+6(%r1) | |
307 | # endif | |
b00badcd | 308 | mtlr %r0 |
3521ba8b | 309 | addi %r1, %r1, STACKFRAME |
b1760f7f | 310 | .cfi_def_cfa_offset 0 |
b00badcd | 311 | blr |
b1760f7f | 312 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 313 | # case FFI_TYPE_UINT32 |
3521ba8b AM |
314 | # ifdef __LITTLE_ENDIAN__ |
315 | lwz %r3, RETVAL+0(%r1) | |
316 | # else | |
317 | lwz %r3, RETVAL+4(%r1) | |
318 | # endif | |
b00badcd | 319 | mtlr %r0 |
3521ba8b | 320 | addi %r1, %r1, STACKFRAME |
b1760f7f | 321 | .cfi_def_cfa_offset 0 |
b00badcd | 322 | blr |
b1760f7f | 323 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 324 | # case FFI_TYPE_SINT32 |
3521ba8b AM |
325 | # ifdef __LITTLE_ENDIAN__ |
326 | lwa %r3, RETVAL+0(%r1) | |
327 | # else | |
328 | lwa %r3, RETVAL+4(%r1) | |
329 | # endif | |
b00badcd | 330 | mtlr %r0 |
3521ba8b | 331 | addi %r1, %r1, STACKFRAME |
b1760f7f | 332 | .cfi_def_cfa_offset 0 |
b00badcd | 333 | blr |
b1760f7f | 334 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 335 | # case FFI_TYPE_UINT64 |
3521ba8b | 336 | ld %r3, RETVAL+0(%r1) |
b00badcd | 337 | mtlr %r0 |
3521ba8b | 338 | addi %r1, %r1, STACKFRAME |
b1760f7f | 339 | .cfi_def_cfa_offset 0 |
b00badcd | 340 | blr |
b1760f7f | 341 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 342 | # case FFI_TYPE_SINT64 |
3521ba8b | 343 | ld %r3, RETVAL+0(%r1) |
b00badcd | 344 | mtlr %r0 |
3521ba8b | 345 | addi %r1, %r1, STACKFRAME |
b1760f7f | 346 | .cfi_def_cfa_offset 0 |
b00badcd | 347 | blr |
b1760f7f | 348 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 | 349 | # case FFI_TYPE_STRUCT |
b00badcd | 350 | mtlr %r0 |
3521ba8b | 351 | addi %r1, %r1, STACKFRAME |
b1760f7f | 352 | .cfi_def_cfa_offset 0 |
b00badcd | 353 | blr |
b1760f7f | 354 | .cfi_def_cfa_offset STACKFRAME |
e9b84181 JJ |
355 | nop |
356 | # case FFI_TYPE_POINTER | |
3521ba8b AM |
357 | ld %r3, RETVAL+0(%r1) |
358 | mtlr %r0 | |
359 | addi %r1, %r1, STACKFRAME | |
b1760f7f | 360 | .cfi_def_cfa_offset 0 |
3521ba8b | 361 | blr |
b1760f7f | 362 | .cfi_def_cfa_offset STACKFRAME |
92456a4e L |
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 | |
3521ba8b AM |
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 | |
b1760f7f | 389 | .cfi_def_cfa_offset 0 |
3521ba8b | 390 | blr |
b1760f7f | 391 | .cfi_def_cfa_offset STACKFRAME |
92456a4e L |
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 | |
3521ba8b AM |
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 | |
b1760f7f | 419 | .cfi_def_cfa_offset 0 |
3521ba8b | 420 | blr |
b1760f7f | 421 | .cfi_def_cfa_offset STACKFRAME |
3521ba8b AM |
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 | |
b1760f7f | 428 | .cfi_def_cfa_offset 0 |
3521ba8b AM |
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 | |
b1760f7f | 442 | .cfi_def_cfa_offset 0 |
3521ba8b | 443 | blr |
b1760f7f | 444 | .cfi_def_cfa_offset STACKFRAME |
3521ba8b AM |
445 | .Lsmalldown: |
446 | addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 | |
e9b84181 | 447 | mtlr %r0 |
3521ba8b AM |
448 | sldi %r5, %r5, 3 |
449 | addi %r1, %r1, STACKFRAME | |
b1760f7f | 450 | .cfi_def_cfa_offset 0 |
3521ba8b | 451 | srd %r3, %r3, %r5 |
e9b84181 | 452 | blr |
3521ba8b AM |
453 | # endif |
454 | ||
b1760f7f | 455 | .cfi_endproc |
3521ba8b AM |
456 | # if _CALL_ELF == 2 |
457 | .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 | |
458 | # else | |
459 | # ifdef _CALL_LINUX | |
7054d980 | 460 | .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 |
3521ba8b | 461 | # else |
b1760f7f RH |
462 | .long 0 |
463 | .byte 0,12,0,1,128,0,0,0 | |
e9b84181 | 464 | .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 |
3521ba8b AM |
465 | # endif |
466 | # endif | |
e9b84181 | 467 | |
7446546a | 468 | |
b1760f7f RH |
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: | |
08cd8d59 | 475 | # ifndef __PCREL__ |
b1760f7f RH |
476 | addis %r2, %r12, .TOC.-ffi_go_closure_linux64@ha |
477 | addi %r2, %r2, .TOC.-ffi_go_closure_linux64@l | |
08cd8d59 | 478 | # endif |
b1760f7f RH |
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 | |
1138382b JJ |
562 | #endif |
563 | ||
564 | #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 | |
7446546a AH |
565 | .section .note.GNU-stack,"",@progbits |
566 | #endif |