]>
Commit | Line | Data |
---|---|---|
22bcf65c GT |
1 | /* ----------------------------------------------------------------------- |
2 | sysv.S - Copyright (c) 2000 Software AG | |
7446546a | 3 | Copyright (c) 2008 Red Hat, Inc. |
b1760f7f | 4 | |
22bcf65c | 5 | S390 Foreign Function Interface |
b1760f7f | 6 | |
22bcf65c GT |
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: | |
b1760f7f | 14 | |
22bcf65c GT |
15 | The above copyright notice and this permission notice shall be included |
16 | in all copies or substantial portions of the Software. | |
b1760f7f | 17 | |
5f933ef0 AH |
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. | |
22bcf65c | 26 | ----------------------------------------------------------------------- */ |
c4f17c6f | 27 | |
a733b15e | 28 | #define LIBFFI_ASM |
1450eb7a | 29 | #include <fficonfig.h> |
a733b15e JJ |
30 | #include <ffi.h> |
31 | ||
b1760f7f RH |
32 | .text |
33 | ||
c4f17c6f | 34 | #ifndef __s390x__ |
b1760f7f RH |
35 | |
36 | # r2: frame | |
37 | # r3: ret_type | |
38 | # r4: ret_addr | |
39 | # r5: fun | |
40 | # r6: closure | |
41 | ||
22bcf65c | 42 | # This assumes we are using gas. |
b1760f7f | 43 | .balign 8 |
22bcf65c | 44 | .globl ffi_call_SYSV |
b1760f7f | 45 | FFI_HIDDEN(ffi_call_SYSV) |
22bcf65c GT |
46 | .type ffi_call_SYSV,%function |
47 | ffi_call_SYSV: | |
b1760f7f RH |
48 | .cfi_startproc |
49 | st %r6,44(%r2) # Save registers | |
50 | stm %r12,%r14,48(%r2) | |
51 | lr %r13,%r2 # Install frame pointer | |
52 | .cfi_rel_offset r6, 44 | |
53 | .cfi_rel_offset r12, 48 | |
54 | .cfi_rel_offset r13, 52 | |
55 | .cfi_rel_offset r14, 56 | |
56 | .cfi_def_cfa_register r13 | |
57 | st %r2,0(%r15) # Set up back chain | |
58 | sla %r3,3 # ret_type *= 8 | |
59 | lr %r12,%r4 # Save ret_addr | |
60 | lr %r1,%r5 # Save fun | |
61 | lr %r0,%r6 # Install static chain | |
62 | ||
63 | # Set return address, so that there is only one indirect jump. | |
64 | #ifdef HAVE_AS_S390_ZARCH | |
65 | larl %r14,.Ltable | |
66 | ar %r14,%r3 | |
67 | #else | |
68 | basr %r14,0 | |
69 | 0: la %r14,.Ltable-0b(%r14,%r3) | |
70 | #endif | |
71 | ||
72 | lm %r2,%r6,8(%r13) # Load arguments | |
73 | ld %f0,64(%r13) | |
74 | ld %f2,72(%r13) | |
75 | br %r1 # ... and call function | |
76 | ||
77 | .balign 8 | |
c4f17c6f | 78 | .Ltable: |
b1760f7f RH |
79 | # FFI390_RET_DOUBLE |
80 | std %f0,0(%r12) | |
81 | j .Ldone | |
82 | ||
83 | .balign 8 | |
84 | # FFI390_RET_FLOAT | |
85 | ste %f0,0(%r12) | |
86 | j .Ldone | |
87 | ||
88 | .balign 8 | |
89 | # FFI390_RET_INT64 | |
90 | st %r3,4(%r12) | |
91 | nop | |
92 | # fallthru | |
93 | ||
94 | .balign 8 | |
95 | # FFI390_RET_INT32 | |
96 | st %r2,0(%r12) | |
97 | nop | |
98 | # fallthru | |
99 | ||
100 | .balign 8 | |
101 | # FFI390_RET_VOID | |
102 | .Ldone: | |
103 | l %r14,56(%r13) | |
104 | l %r12,48(%r13) | |
105 | l %r6,44(%r13) | |
106 | l %r13,52(%r13) | |
107 | .cfi_restore 14 | |
108 | .cfi_restore 13 | |
109 | .cfi_restore 12 | |
110 | .cfi_restore 6 | |
111 | .cfi_def_cfa r15, 96 | |
112 | br %r14 | |
113 | .cfi_endproc | |
114 | .size ffi_call_SYSV,.-ffi_call_SYSV | |
ad5e163c | 115 | |
ad5e163c | 116 | |
b1760f7f RH |
117 | .balign 8 |
118 | .globl ffi_go_closure_SYSV | |
119 | FFI_HIDDEN(ffi_go_closure_SYSV) | |
120 | .type ffi_go_closure_SYSV,%function | |
121 | ffi_go_closure_SYSV: | |
122 | .cfi_startproc | |
123 | stm %r2,%r6,8(%r15) # Save arguments | |
124 | lr %r4,%r0 # Load closure -> user_data | |
125 | l %r2,4(%r4) # ->cif | |
126 | l %r3,8(%r4) # ->fun | |
127 | j .Ldoclosure | |
128 | .cfi_endproc | |
ad5e163c | 129 | |
b1760f7f | 130 | .balign 8 |
c4f17c6f | 131 | .globl ffi_closure_SYSV |
b1760f7f | 132 | FFI_HIDDEN(ffi_closure_SYSV) |
c4f17c6f UW |
133 | .type ffi_closure_SYSV,%function |
134 | ffi_closure_SYSV: | |
b1760f7f RH |
135 | .cfi_startproc |
136 | stm %r2,%r6,8(%r15) # Save arguments | |
137 | lr %r4,%r0 # Closure | |
138 | l %r2,16(%r4) # ->cif | |
139 | l %r3,20(%r4) # ->fun | |
140 | l %r4,24(%r4) # ->user_data | |
141 | .Ldoclosure: | |
c4f17c6f | 142 | stm %r12,%r15,48(%r15) # Save registers |
b1760f7f RH |
143 | lr %r12,%r15 |
144 | .cfi_def_cfa_register r12 | |
145 | .cfi_rel_offset r6, 24 | |
146 | .cfi_rel_offset r12, 48 | |
147 | .cfi_rel_offset r13, 52 | |
148 | .cfi_rel_offset r14, 56 | |
149 | .cfi_rel_offset r15, 60 | |
150 | #ifndef HAVE_AS_S390_ZARCH | |
c4f17c6f UW |
151 | basr %r13,0 # Set up base register |
152 | .Lcbase: | |
b1760f7f RH |
153 | l %r1,.Lchelper-.Lcbase(%r13) # Get helper function |
154 | #endif | |
155 | ahi %r15,-96-8 # Set up stack frame | |
156 | st %r12,0(%r15) # Set up back chain | |
157 | ||
158 | std %f0,64(%r12) # Save fp arguments | |
159 | std %f2,72(%r12) | |
160 | ||
161 | la %r5,96(%r12) # Overflow | |
162 | st %r5,96(%r15) | |
163 | la %r6,64(%r12) # FPRs | |
164 | la %r5,8(%r12) # GPRs | |
165 | #ifdef HAVE_AS_S390_ZARCH | |
166 | brasl %r14,ffi_closure_helper_SYSV | |
167 | #else | |
168 | bas %r14,0(%r1,%r13) # Call helper | |
169 | #endif | |
c4f17c6f | 170 | |
b1760f7f RH |
171 | lr %r15,%r12 |
172 | .cfi_def_cfa_register r15 | |
173 | lm %r12,%r14,48(%r12) # Restore saved registers | |
174 | l %r6,24(%r15) | |
175 | ld %f0,64(%r15) # Load return registers | |
176 | lm %r2,%r3,8(%r15) | |
177 | br %r14 | |
178 | .cfi_endproc | |
179 | ||
180 | #ifndef HAVE_AS_S390_ZARCH | |
c4f17c6f UW |
181 | .align 4 |
182 | .Lchelper: | |
183 | .long ffi_closure_helper_SYSV-.Lcbase | |
b1760f7f | 184 | #endif |
c4f17c6f | 185 | |
b1760f7f | 186 | .size ffi_closure_SYSV,.-ffi_closure_SYSV |
c4f17c6f UW |
187 | |
188 | #else | |
b1760f7f RH |
189 | |
190 | # r2: frame | |
191 | # r3: ret_type | |
192 | # r4: ret_addr | |
193 | # r5: fun | |
194 | # r6: closure | |
195 | ||
c4f17c6f | 196 | # This assumes we are using gas. |
b1760f7f | 197 | .balign 8 |
c4f17c6f | 198 | .globl ffi_call_SYSV |
b1760f7f | 199 | FFI_HIDDEN(ffi_call_SYSV) |
c4f17c6f UW |
200 | .type ffi_call_SYSV,%function |
201 | ffi_call_SYSV: | |
b1760f7f RH |
202 | .cfi_startproc |
203 | stg %r6,88(%r2) # Save registers | |
204 | stmg %r12,%r14,96(%r2) | |
205 | lgr %r13,%r2 # Install frame pointer | |
206 | .cfi_rel_offset r6, 88 | |
207 | .cfi_rel_offset r12, 96 | |
208 | .cfi_rel_offset r13, 104 | |
209 | .cfi_rel_offset r14, 112 | |
210 | .cfi_def_cfa_register r13 | |
211 | stg %r2,0(%r15) # Set up back chain | |
212 | larl %r14,.Ltable # Set up return address | |
213 | slag %r3,%r3,3 # ret_type *= 8 | |
214 | lgr %r12,%r4 # Save ret_addr | |
215 | lgr %r1,%r5 # Save fun | |
216 | lgr %r0,%r6 # Install static chain | |
217 | agr %r14,%r3 | |
218 | lmg %r2,%r6,16(%r13) # Load arguments | |
219 | ld %f0,128(%r13) | |
220 | ld %f2,136(%r13) | |
221 | ld %f4,144(%r13) | |
222 | ld %f6,152(%r13) | |
223 | br %r1 # ... and call function | |
224 | ||
225 | .balign 8 | |
c4f17c6f | 226 | .Ltable: |
b1760f7f RH |
227 | # FFI390_RET_DOUBLE |
228 | std %f0,0(%r12) | |
229 | j .Ldone | |
230 | ||
231 | .balign 8 | |
232 | # FFI390_RET_DOUBLE | |
233 | ste %f0,0(%r12) | |
234 | j .Ldone | |
235 | ||
236 | .balign 8 | |
237 | # FFI390_RET_INT64 | |
238 | stg %r2,0(%r12) | |
239 | ||
240 | .balign 8 | |
241 | # FFI390_RET_INT32 | |
242 | # Never used, as we always store type ffi_arg. | |
243 | # But the stg above is 6 bytes and we cannot | |
244 | # jump around this case, so fall through. | |
245 | nop | |
246 | nop | |
247 | ||
248 | .balign 8 | |
249 | # FFI390_RET_VOID | |
250 | .Ldone: | |
251 | lg %r14,112(%r13) | |
252 | lg %r12,96(%r13) | |
253 | lg %r6,88(%r13) | |
254 | lg %r13,104(%r13) | |
255 | .cfi_restore r14 | |
256 | .cfi_restore r13 | |
257 | .cfi_restore r12 | |
258 | .cfi_restore r6 | |
259 | .cfi_def_cfa r15, 160 | |
260 | br %r14 | |
261 | .cfi_endproc | |
262 | .size ffi_call_SYSV,.-ffi_call_SYSV | |
c4f17c6f | 263 | |
b1760f7f RH |
264 | |
265 | .balign 8 | |
266 | .globl ffi_go_closure_SYSV | |
267 | FFI_HIDDEN(ffi_go_closure_SYSV) | |
268 | .type ffi_go_closure_SYSV,%function | |
269 | ffi_go_closure_SYSV: | |
270 | .cfi_startproc | |
271 | stmg %r2,%r6,16(%r15) # Save arguments | |
272 | lgr %r4,%r0 # Load closure -> user_data | |
273 | lg %r2,8(%r4) # ->cif | |
274 | lg %r3,16(%r4) # ->fun | |
275 | j .Ldoclosure | |
276 | .cfi_endproc | |
277 | .size ffi_go_closure_SYSV,.-ffi_go_closure_SYSV | |
c4f17c6f UW |
278 | |
279 | ||
b1760f7f | 280 | .balign 8 |
c4f17c6f | 281 | .globl ffi_closure_SYSV |
b1760f7f | 282 | FFI_HIDDEN(ffi_closure_SYSV) |
c4f17c6f UW |
283 | .type ffi_closure_SYSV,%function |
284 | ffi_closure_SYSV: | |
b1760f7f | 285 | .cfi_startproc |
c4f17c6f | 286 | stmg %r2,%r6,16(%r15) # Save arguments |
b1760f7f RH |
287 | lgr %r4,%r0 # Load closure |
288 | lg %r2,32(%r4) # ->cif | |
289 | lg %r3,40(%r4) # ->fun | |
290 | lg %r4,48(%r4) # ->user_data | |
291 | .Ldoclosure: | |
292 | stmg %r13,%r15,104(%r15) # Save registers | |
293 | lgr %r13,%r15 | |
294 | .cfi_def_cfa_register r13 | |
295 | .cfi_rel_offset r6, 48 | |
296 | .cfi_rel_offset r13, 104 | |
297 | .cfi_rel_offset r14, 112 | |
298 | .cfi_rel_offset r15, 120 | |
299 | aghi %r15,-160-16 # Set up stack frame | |
300 | stg %r13,0(%r15) # Set up back chain | |
301 | ||
302 | std %f0,128(%r13) # Save fp arguments | |
303 | std %f2,136(%r13) | |
304 | std %f4,144(%r13) | |
305 | std %f6,152(%r13) | |
306 | la %r5,160(%r13) # Overflow | |
307 | stg %r5,160(%r15) | |
308 | la %r6,128(%r13) # FPRs | |
309 | la %r5,16(%r13) # GPRs | |
c4f17c6f UW |
310 | brasl %r14,ffi_closure_helper_SYSV # Call helper |
311 | ||
b1760f7f RH |
312 | lgr %r15,%r13 |
313 | .cfi_def_cfa_register r15 | |
314 | lmg %r13,%r14,104(%r13) # Restore saved registers | |
315 | lg %r6,48(%r15) | |
316 | ld %f0,128(%r15) # Load return registers | |
317 | lg %r2,16(%r15) | |
c4f17c6f | 318 | br %r14 |
b1760f7f RH |
319 | .cfi_endproc |
320 | .size ffi_closure_SYSV,.-ffi_closure_SYSV | |
321 | #endif /* !s390x */ | |
ad5e163c | 322 | |
feb51530 MK |
323 | #if defined __ELF__ && defined __linux__ |
324 | .section .note.GNU-stack,"",@progbits | |
325 | #endif |