]> git.ipfire.org Git - thirdparty/gcc.git/blame - libffi/src/s390/sysv.S
Merge libffi to upstream commit c82cc159426d8d4402375fa1ae3f045b9cf82e16
[thirdparty/gcc.git] / libffi / src / s390 / sysv.S
CommitLineData
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
47ffi_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
690: 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
121ffi_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
134ffi_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
201ffi_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
269ffi_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
284ffi_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