Fix type in last change.
[official-gcc.git] / libffi / src / s390 / sysv.S
blobc4b5006aed07454aba41870f4bc2bb1bac65a88e
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    ----------------------------------------------------------------------- */
28 #define LIBFFI_ASM
29 #include <fficonfig.h>
30 #include <ffi.h>
32         .text
34 #ifndef __s390x__
36         # r2:   frame
37         # r3:   ret_type
38         # r4:   ret_addr
39         # r5:   fun
40         # r6:   closure
42         # This assumes we are using gas.
43         .balign 8
44         .globl  ffi_call_SYSV
45         FFI_HIDDEN(ffi_call_SYSV)
46         .type   ffi_call_SYSV,%function
47 ffi_call_SYSV:
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
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
72         lm      %r2,%r6,8(%r13)                 # Load arguments
73         ld      %f0,64(%r13)
74         ld      %f2,72(%r13)
75         br      %r1                             # ... and call function
77         .balign 8
78 .Ltable:
79 # FFI390_RET_DOUBLE
80         std     %f0,0(%r12)
81         j       .Ldone
83         .balign 8
84 # FFI390_RET_FLOAT
85         ste     %f0,0(%r12)
86         j       .Ldone
88         .balign 8
89 # FFI390_RET_INT64
90         st      %r3,4(%r12)
91         nop
92         # fallthru
94         .balign 8
95 # FFI390_RET_INT32
96         st      %r2,0(%r12)
97         nop
98         # fallthru
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
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
130         .balign 8
131         .globl  ffi_closure_SYSV
132         FFI_HIDDEN(ffi_closure_SYSV)
133         .type   ffi_closure_SYSV,%function
134 ffi_closure_SYSV:
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:
142         stm     %r12,%r15,48(%r15)              # Save registers
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
151         basr    %r13,0                          # Set up base register
152 .Lcbase:
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
158         std     %f0,64(%r12)                    # Save fp arguments
159         std     %f2,72(%r12)
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
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
180 #ifndef HAVE_AS_S390_ZARCH
181         .align 4
182 .Lchelper:
183         .long   ffi_closure_helper_SYSV-.Lcbase
184 #endif
186         .size    ffi_closure_SYSV,.-ffi_closure_SYSV
188 #else
190         # r2:   frame
191         # r3:   ret_type
192         # r4:   ret_addr
193         # r5:   fun
194         # r6:   closure
196         # This assumes we are using gas.
197         .balign 8
198         .globl  ffi_call_SYSV
199         FFI_HIDDEN(ffi_call_SYSV)
200         .type   ffi_call_SYSV,%function
201 ffi_call_SYSV:
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
225         .balign 8
226 .Ltable:
227 # FFI390_RET_DOUBLE
228         std     %f0,0(%r12)
229         j       .Ldone
231         .balign 8
232 # FFI390_RET_DOUBLE
233         ste     %f0,0(%r12)
234         j       .Ldone
236         .balign 8
237 # FFI390_RET_INT64
238         stg     %r2,0(%r12)
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
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
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
280         .balign 8
281         .globl  ffi_closure_SYSV
282         FFI_HIDDEN(ffi_closure_SYSV)
283         .type   ffi_closure_SYSV,%function
284 ffi_closure_SYSV:
285         .cfi_startproc
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
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
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
310         brasl   %r14,ffi_closure_helper_SYSV    # Call helper
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)
318         br      %r14
319         .cfi_endproc
320         .size    ffi_closure_SYSV,.-ffi_closure_SYSV
321 #endif /* !s390x */
323 #if defined __ELF__ && defined __linux__
324         .section        .note.GNU-stack,"",@progbits
325 #endif