]>
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 | ||
33 | #ifdef __powerpc64__ | |
8a42356f | 34 | FFI_HIDDEN (ffi_closure_LINUX64) |
7054d980 | 35 | .globl ffi_closure_LINUX64 |
16070e45 AT |
36 | .section ".opd","aw" |
37 | .align 3 | |
e9b84181 | 38 | ffi_closure_LINUX64: |
7054d980 AM |
39 | #ifdef _CALL_LINUX |
40 | .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 | |
41 | .type ffi_closure_LINUX64,@function | |
42 | .text | |
43 | .L.ffi_closure_LINUX64: | |
44 | #else | |
45 | FFI_HIDDEN (.ffi_closure_LINUX64) | |
46 | .globl .ffi_closure_LINUX64 | |
16070e45 AT |
47 | .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 |
48 | .size ffi_closure_LINUX64,24 | |
49 | .type .ffi_closure_LINUX64,@function | |
50 | .text | |
e9b84181 | 51 | .ffi_closure_LINUX64: |
7054d980 | 52 | #endif |
e9b84181 JJ |
53 | .LFB1: |
54 | # save general regs into parm save area | |
55 | std %r3, 48(%r1) | |
56 | std %r4, 56(%r1) | |
57 | std %r5, 64(%r1) | |
58 | std %r6, 72(%r1) | |
59 | mflr %r0 | |
60 | ||
61 | std %r7, 80(%r1) | |
62 | std %r8, 88(%r1) | |
63 | std %r9, 96(%r1) | |
64 | std %r10, 104(%r1) | |
65 | std %r0, 16(%r1) | |
66 | ||
67 | # mandatory 48 bytes special reg save area + 64 bytes parm save area | |
bf310028 AM |
68 | # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 |
69 | stdu %r1, -240(%r1) | |
e9b84181 JJ |
70 | .LCFI0: |
71 | ||
72 | # next save fpr 1 to fpr 13 | |
bf310028 AM |
73 | stfd %f1, 128+(0*8)(%r1) |
74 | stfd %f2, 128+(1*8)(%r1) | |
75 | stfd %f3, 128+(2*8)(%r1) | |
76 | stfd %f4, 128+(3*8)(%r1) | |
77 | stfd %f5, 128+(4*8)(%r1) | |
78 | stfd %f6, 128+(5*8)(%r1) | |
79 | stfd %f7, 128+(6*8)(%r1) | |
80 | stfd %f8, 128+(7*8)(%r1) | |
81 | stfd %f9, 128+(8*8)(%r1) | |
82 | stfd %f10, 128+(9*8)(%r1) | |
83 | stfd %f11, 128+(10*8)(%r1) | |
84 | stfd %f12, 128+(11*8)(%r1) | |
85 | stfd %f13, 128+(12*8)(%r1) | |
e9b84181 JJ |
86 | |
87 | # set up registers for the routine that actually does the work | |
88 | # get the context pointer from the trampoline | |
89 | mr %r3, %r11 | |
90 | ||
91 | # now load up the pointer to the result storage | |
92 | addi %r4, %r1, 112 | |
93 | ||
94 | # now load up the pointer to the parameter save area | |
95 | # in the previous frame | |
bf310028 | 96 | addi %r5, %r1, 240 + 48 |
e9b84181 JJ |
97 | |
98 | # now load up the pointer to the saved fpr registers */ | |
bf310028 | 99 | addi %r6, %r1, 128 |
e9b84181 JJ |
100 | |
101 | # make the call | |
7054d980 AM |
102 | #ifdef _CALL_LINUX |
103 | bl ffi_closure_helper_LINUX64 | |
104 | #else | |
e9b84181 | 105 | bl .ffi_closure_helper_LINUX64 |
7054d980 | 106 | #endif |
b00badcd | 107 | .Lret: |
e9b84181 JJ |
108 | |
109 | # now r3 contains the return type | |
110 | # so use it to look up in a table | |
111 | # so we know how to deal with each type | |
112 | ||
16070e45 | 113 | # look up the proper starting point in table |
e9b84181 | 114 | # by using return type as offset |
b00badcd | 115 | mflr %r4 # move address of .Lret to r4 |
e9b84181 | 116 | sldi %r3, %r3, 4 # now multiply return type by 16 |
b00badcd | 117 | addi %r4, %r4, .Lret_type0 - .Lret |
bf310028 | 118 | ld %r0, 240+16(%r1) |
e9b84181 JJ |
119 | add %r3, %r3, %r4 # add contents of table to table address |
120 | mtctr %r3 | |
121 | bctr # jump to it | |
122 | ||
123 | # Each of the ret_typeX code fragments has to be exactly 16 bytes long | |
124 | # (4 instructions). For cache effectiveness we align to a 16 byte boundary | |
125 | # first. | |
126 | .align 4 | |
127 | ||
e9b84181 JJ |
128 | .Lret_type0: |
129 | # case FFI_TYPE_VOID | |
b00badcd | 130 | mtlr %r0 |
bf310028 | 131 | addi %r1, %r1, 240 |
b00badcd | 132 | blr |
e9b84181 JJ |
133 | nop |
134 | # case FFI_TYPE_INT | |
40b45a6d AM |
135 | #ifdef __LITTLE_ENDIAN__ |
136 | lwa %r3, 112+0(%r1) | |
137 | #else | |
b00badcd | 138 | lwa %r3, 112+4(%r1) |
40b45a6d | 139 | #endif |
b00badcd | 140 | mtlr %r0 |
bf310028 | 141 | addi %r1, %r1, 240 |
b00badcd | 142 | blr |
e9b84181 | 143 | # case FFI_TYPE_FLOAT |
6350c02c | 144 | lfs %f1, 112+0(%r1) |
b00badcd | 145 | mtlr %r0 |
bf310028 | 146 | addi %r1, %r1, 240 |
b00badcd | 147 | blr |
e9b84181 | 148 | # case FFI_TYPE_DOUBLE |
b00badcd AM |
149 | lfd %f1, 112+0(%r1) |
150 | mtlr %r0 | |
bf310028 | 151 | addi %r1, %r1, 240 |
b00badcd | 152 | blr |
e9b84181 | 153 | # case FFI_TYPE_LONGDOUBLE |
b00badcd AM |
154 | lfd %f1, 112+0(%r1) |
155 | mtlr %r0 | |
bf310028 AM |
156 | lfd %f2, 112+8(%r1) |
157 | b .Lfinish | |
e9b84181 | 158 | # case FFI_TYPE_UINT8 |
40b45a6d AM |
159 | #ifdef __LITTLE_ENDIAN__ |
160 | lbz %r3, 112+0(%r1) | |
161 | #else | |
b00badcd | 162 | lbz %r3, 112+7(%r1) |
40b45a6d | 163 | #endif |
b00badcd | 164 | mtlr %r0 |
bf310028 | 165 | addi %r1, %r1, 240 |
b00badcd | 166 | blr |
e9b84181 | 167 | # case FFI_TYPE_SINT8 |
40b45a6d AM |
168 | #ifdef __LITTLE_ENDIAN__ |
169 | lbz %r3, 112+0(%r1) | |
170 | #else | |
b00badcd | 171 | lbz %r3, 112+7(%r1) |
40b45a6d | 172 | #endif |
e9b84181 | 173 | extsb %r3,%r3 |
b00badcd | 174 | mtlr %r0 |
e9b84181 | 175 | b .Lfinish |
e9b84181 | 176 | # case FFI_TYPE_UINT16 |
40b45a6d AM |
177 | #ifdef __LITTLE_ENDIAN__ |
178 | lhz %r3, 112+0(%r1) | |
179 | #else | |
b00badcd | 180 | lhz %r3, 112+6(%r1) |
40b45a6d | 181 | #endif |
b00badcd AM |
182 | mtlr %r0 |
183 | .Lfinish: | |
bf310028 | 184 | addi %r1, %r1, 240 |
b00badcd | 185 | blr |
e9b84181 | 186 | # case FFI_TYPE_SINT16 |
40b45a6d AM |
187 | #ifdef __LITTLE_ENDIAN__ |
188 | lha %r3, 112+0(%r1) | |
189 | #else | |
b00badcd | 190 | lha %r3, 112+6(%r1) |
40b45a6d | 191 | #endif |
b00badcd | 192 | mtlr %r0 |
bf310028 | 193 | addi %r1, %r1, 240 |
b00badcd | 194 | blr |
e9b84181 | 195 | # case FFI_TYPE_UINT32 |
40b45a6d AM |
196 | #ifdef __LITTLE_ENDIAN__ |
197 | lwz %r3, 112+0(%r1) | |
198 | #else | |
b00badcd | 199 | lwz %r3, 112+4(%r1) |
40b45a6d | 200 | #endif |
b00badcd | 201 | mtlr %r0 |
bf310028 | 202 | addi %r1, %r1, 240 |
b00badcd | 203 | blr |
e9b84181 | 204 | # case FFI_TYPE_SINT32 |
40b45a6d AM |
205 | #ifdef __LITTLE_ENDIAN__ |
206 | lwa %r3, 112+0(%r1) | |
207 | #else | |
b00badcd | 208 | lwa %r3, 112+4(%r1) |
40b45a6d | 209 | #endif |
b00badcd | 210 | mtlr %r0 |
bf310028 | 211 | addi %r1, %r1, 240 |
b00badcd | 212 | blr |
e9b84181 | 213 | # case FFI_TYPE_UINT64 |
b00badcd AM |
214 | ld %r3, 112+0(%r1) |
215 | mtlr %r0 | |
bf310028 | 216 | addi %r1, %r1, 240 |
b00badcd | 217 | blr |
e9b84181 | 218 | # case FFI_TYPE_SINT64 |
b00badcd AM |
219 | ld %r3, 112+0(%r1) |
220 | mtlr %r0 | |
bf310028 | 221 | addi %r1, %r1, 240 |
b00badcd | 222 | blr |
e9b84181 | 223 | # case FFI_TYPE_STRUCT |
b00badcd | 224 | mtlr %r0 |
bf310028 | 225 | addi %r1, %r1, 240 |
b00badcd | 226 | blr |
e9b84181 JJ |
227 | nop |
228 | # case FFI_TYPE_POINTER | |
b00badcd | 229 | ld %r3, 112+0(%r1) |
e9b84181 | 230 | mtlr %r0 |
bf310028 | 231 | addi %r1, %r1, 240 |
e9b84181 | 232 | blr |
b00badcd | 233 | # esac |
e9b84181 JJ |
234 | .LFE1: |
235 | .long 0 | |
236 | .byte 0,12,0,1,128,0,0,0 | |
7054d980 AM |
237 | #ifdef _CALL_LINUX |
238 | .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 | |
239 | #else | |
e9b84181 | 240 | .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 |
7054d980 | 241 | #endif |
e9b84181 | 242 | |
a733b15e | 243 | .section .eh_frame,EH_FRAME_FLAGS,@progbits |
e9b84181 JJ |
244 | .Lframe1: |
245 | .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry | |
246 | .LSCIE1: | |
247 | .4byte 0x0 # CIE Identifier Tag | |
248 | .byte 0x1 # CIE Version | |
249 | .ascii "zR\0" # CIE Augmentation | |
250 | .uleb128 0x1 # CIE Code Alignment Factor | |
251 | .sleb128 -8 # CIE Data Alignment Factor | |
252 | .byte 0x41 # CIE RA Column | |
253 | .uleb128 0x1 # Augmentation size | |
254 | .byte 0x14 # FDE Encoding (pcrel udata8) | |
255 | .byte 0xc # DW_CFA_def_cfa | |
256 | .uleb128 0x1 | |
257 | .uleb128 0x0 | |
258 | .align 3 | |
259 | .LECIE1: | |
260 | .LSFDE1: | |
261 | .4byte .LEFDE1-.LASFDE1 # FDE Length | |
262 | .LASFDE1: | |
263 | .4byte .LASFDE1-.Lframe1 # FDE CIE offset | |
264 | .8byte .LFB1-. # FDE initial location | |
265 | .8byte .LFE1-.LFB1 # FDE address range | |
266 | .uleb128 0x0 # Augmentation size | |
267 | .byte 0x2 # DW_CFA_advance_loc1 | |
268 | .byte .LCFI0-.LFB1 | |
269 | .byte 0xe # DW_CFA_def_cfa_offset | |
bf310028 | 270 | .uleb128 240 |
e9b84181 JJ |
271 | .byte 0x11 # DW_CFA_offset_extended_sf |
272 | .uleb128 0x41 | |
273 | .sleb128 -2 | |
274 | .align 3 | |
275 | .LEFDE1: | |
276 | #endif | |
7446546a AH |
277 | |
278 | #if defined __ELF__ && defined __linux__ | |
279 | .section .note.GNU-stack,"",@progbits | |
280 | #endif |