1 /* -----------------------------------------------------------------------
2 sysv.S - Copyright (c) 2000 Software AG
3 Copyright (c) 2008 Red Hat, Inc.
5 S390 Foreign Function Interface
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:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
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 ----------------------------------------------------------------------- */
29 #include <fficonfig.h>
42 # This assumes we are using gas.
45 FFI_HIDDEN(ffi_call_SYSV)
46 .type ffi_call_SYSV,%function
49 st %r6,44(%r2) # Save registers
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
61 lr %r0,%r6 # Install static chain
63 # Set return address, so that there is only one indirect jump.
64 #ifdef HAVE_AS_S390_ZARCH
69 0: la %r14,.Ltable-0b(%r14,%r3)
72 lm %r2,%r6,8(%r13) # Load arguments
75 br %r1 # ... and call function
114 .size ffi_call_SYSV,.-ffi_call_SYSV
118 .globl ffi_go_closure_SYSV
119 FFI_HIDDEN(ffi_go_closure_SYSV)
120 .type ffi_go_closure_SYSV,%function
123 stm %r2,%r6,8(%r15) # Save arguments
124 lr %r4,%r0 # Load closure -> user_data
131 .globl ffi_closure_SYSV
132 FFI_HIDDEN(ffi_closure_SYSV)
133 .type ffi_closure_SYSV,%function
136 stm %r2,%r6,8(%r15) # Save arguments
138 l %r2,16(%r4) # ->cif
139 l %r3,20(%r4) # ->fun
140 l %r4,24(%r4) # ->user_data
142 stm %r12,%r15,48(%r15) # Save registers
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
151 basr %r13,0 # Set up base register
153 l %r1,.Lchelper-.Lcbase(%r13) # Get helper function
155 ahi %r15,-96-8 # Set up stack frame
156 st %r12,0(%r15) # Set up back chain
158 std %f0,64(%r12) # Save fp arguments
161 la %r5,96(%r12) # Overflow
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
168 bas %r14,0(%r1,%r13) # Call helper
172 .cfi_def_cfa_register r15
173 lm %r12,%r14,48(%r12) # Restore saved registers
175 ld %f0,64(%r15) # Load return registers
180 #ifndef HAVE_AS_S390_ZARCH
183 .long ffi_closure_helper_SYSV-.Lcbase
186 .size ffi_closure_SYSV,.-ffi_closure_SYSV
196 # This assumes we are using gas.
199 FFI_HIDDEN(ffi_call_SYSV)
200 .type ffi_call_SYSV,%function
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
218 lmg %r2,%r6,16(%r13) # Load arguments
223 br %r1 # ... and call function
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.
259 .cfi_def_cfa r15, 160
262 .size ffi_call_SYSV,.-ffi_call_SYSV
266 .globl ffi_go_closure_SYSV
267 FFI_HIDDEN(ffi_go_closure_SYSV)
268 .type ffi_go_closure_SYSV,%function
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
277 .size ffi_go_closure_SYSV,.-ffi_go_closure_SYSV
281 .globl ffi_closure_SYSV
282 FFI_HIDDEN(ffi_closure_SYSV)
283 .type ffi_closure_SYSV,%function
286 stmg %r2,%r6,16(%r15) # Save arguments
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
292 stmg %r13,%r15,104(%r15) # Save registers
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
302 std %f0,128(%r13) # Save fp arguments
306 la %r5,160(%r13) # Overflow
308 la %r6,128(%r13) # FPRs
309 la %r5,16(%r13) # GPRs
310 brasl %r14,ffi_closure_helper_SYSV # Call helper
313 .cfi_def_cfa_register r15
314 lmg %r13,%r14,104(%r13) # Restore saved registers
316 ld %f0,128(%r15) # Load return registers
320 .size ffi_closure_SYSV,.-ffi_closure_SYSV
323 #if defined __ELF__ && defined __linux__
324 .section .note.GNU-stack,"",@progbits