1 | /* -----------------------------------------------------------------------
|
---|
2 | sysv.S - Copyright (c) 2000 Software AG
|
---|
3 |
|
---|
4 | S390 Foreign Function Interface
|
---|
5 |
|
---|
6 | Permission is hereby granted, free of charge, to any person obtaining
|
---|
7 | a copy of this software and associated documentation files (the
|
---|
8 | ``Software''), to deal in the Software without restriction, including
|
---|
9 | without limitation the rights to use, copy, modify, merge, publish,
|
---|
10 | distribute, sublicense, and/or sell copies of the Software, and to
|
---|
11 | permit persons to whom the Software is furnished to do so, subject to
|
---|
12 | the following conditions:
|
---|
13 |
|
---|
14 | The above copyright notice and this permission notice shall be included
|
---|
15 | in all copies or substantial portions of the Software.
|
---|
16 |
|
---|
17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
---|
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
---|
20 | IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
---|
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
---|
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
23 | OTHER DEALINGS IN THE SOFTWARE.
|
---|
24 | ----------------------------------------------------------------------- */
|
---|
25 |
|
---|
26 | #ifndef __s390x__
|
---|
27 |
|
---|
28 | .text
|
---|
29 |
|
---|
30 | # r2: cif->bytes
|
---|
31 | # r3: &ecif
|
---|
32 | # r4: ffi_prep_args
|
---|
33 | # r5: ret_type
|
---|
34 | # r6: ecif.rvalue
|
---|
35 | # ov: fn
|
---|
36 |
|
---|
37 | # This assumes we are using gas.
|
---|
38 | .globl ffi_call_SYSV
|
---|
39 | .type ffi_call_SYSV,%function
|
---|
40 | ffi_call_SYSV:
|
---|
41 | .LFB1:
|
---|
42 | stm %r6,%r15,24(%r15) # Save registers
|
---|
43 | .LCFI0:
|
---|
44 | basr %r13,0 # Set up base register
|
---|
45 | .Lbase:
|
---|
46 | lr %r11,%r15 # Set up frame pointer
|
---|
47 | .LCFI1:
|
---|
48 | sr %r15,%r2
|
---|
49 | ahi %r15,-96-48 # Allocate stack
|
---|
50 | lr %r8,%r6 # Save ecif.rvalue
|
---|
51 | sr %r9,%r9
|
---|
52 | ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
|
---|
53 | l %r7,96(%r11) # Load function address
|
---|
54 | st %r11,0(%r15) # Set up back chain
|
---|
55 | ahi %r11,-48 # Register save area
|
---|
56 | .LCFI2:
|
---|
57 |
|
---|
58 | la %r2,96(%r15) # Save area
|
---|
59 | # r3 already holds &ecif
|
---|
60 | basr %r14,%r4 # Call ffi_prep_args
|
---|
61 |
|
---|
62 | lm %r2,%r6,0(%r11) # Load arguments
|
---|
63 | ld %f0,32(%r11)
|
---|
64 | ld %f2,40(%r11)
|
---|
65 | la %r14,0(%r13,%r9) # Set return address
|
---|
66 | br %r7 # ... and call function
|
---|
67 |
|
---|
68 | .LretNone: # Return void
|
---|
69 | l %r4,48+56(%r11)
|
---|
70 | lm %r6,%r15,48+24(%r11)
|
---|
71 | br %r4
|
---|
72 |
|
---|
73 | .LretFloat:
|
---|
74 | l %r4,48+56(%r11)
|
---|
75 | ste %f0,0(%r8) # Return float
|
---|
76 | lm %r6,%r15,48+24(%r11)
|
---|
77 | br %r4
|
---|
78 |
|
---|
79 | .LretDouble:
|
---|
80 | l %r4,48+56(%r11)
|
---|
81 | std %f0,0(%r8) # Return double
|
---|
82 | lm %r6,%r15,48+24(%r11)
|
---|
83 | br %r4
|
---|
84 |
|
---|
85 | .LretInt32:
|
---|
86 | l %r4,48+56(%r11)
|
---|
87 | st %r2,0(%r8) # Return int
|
---|
88 | lm %r6,%r15,48+24(%r11)
|
---|
89 | br %r4
|
---|
90 |
|
---|
91 | .LretInt64:
|
---|
92 | l %r4,48+56(%r11)
|
---|
93 | stm %r2,%r3,0(%r8) # Return long long
|
---|
94 | lm %r6,%r15,48+24(%r11)
|
---|
95 | br %r4
|
---|
96 |
|
---|
97 | .Ltable:
|
---|
98 | .byte .LretNone-.Lbase # FFI390_RET_VOID
|
---|
99 | .byte .LretNone-.Lbase # FFI390_RET_STRUCT
|
---|
100 | .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
|
---|
101 | .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
|
---|
102 | .byte .LretInt32-.Lbase # FFI390_RET_INT32
|
---|
103 | .byte .LretInt64-.Lbase # FFI390_RET_INT64
|
---|
104 |
|
---|
105 | .LFE1:
|
---|
106 | .ffi_call_SYSV_end:
|
---|
107 | .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
---|
108 |
|
---|
109 |
|
---|
110 | .globl ffi_closure_SYSV
|
---|
111 | .type ffi_closure_SYSV,%function
|
---|
112 | ffi_closure_SYSV:
|
---|
113 | .LFB2:
|
---|
114 | stm %r12,%r15,48(%r15) # Save registers
|
---|
115 | .LCFI10:
|
---|
116 | basr %r13,0 # Set up base register
|
---|
117 | .Lcbase:
|
---|
118 | stm %r2,%r6,8(%r15) # Save arguments
|
---|
119 | std %f0,64(%r15)
|
---|
120 | std %f2,72(%r15)
|
---|
121 | lr %r1,%r15 # Set up stack frame
|
---|
122 | ahi %r15,-96
|
---|
123 | .LCFI11:
|
---|
124 | l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
|
---|
125 | lr %r2,%r0 # Closure
|
---|
126 | la %r3,8(%r1) # GPRs
|
---|
127 | la %r4,64(%r1) # FPRs
|
---|
128 | la %r5,96(%r1) # Overflow
|
---|
129 | st %r1,0(%r15) # Set up back chain
|
---|
130 |
|
---|
131 | bas %r14,0(%r12,%r13) # Call helper
|
---|
132 |
|
---|
133 | l %r4,96+56(%r15)
|
---|
134 | ld %f0,96+64(%r15) # Load return registers
|
---|
135 | lm %r2,%r3,96+8(%r15)
|
---|
136 | lm %r12,%r15,96+48(%r15)
|
---|
137 | br %r4
|
---|
138 |
|
---|
139 | .align 4
|
---|
140 | .Lchelper:
|
---|
141 | .long ffi_closure_helper_SYSV-.Lcbase
|
---|
142 |
|
---|
143 | .LFE2:
|
---|
144 |
|
---|
145 | .ffi_closure_SYSV_end:
|
---|
146 | .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
---|
147 |
|
---|
148 |
|
---|
149 | .section .eh_frame,"a",@progbits
|
---|
150 | .Lframe1:
|
---|
151 | .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
|
---|
152 | .LSCIE1:
|
---|
153 | .4byte 0x0 # CIE Identifier Tag
|
---|
154 | .byte 0x1 # CIE Version
|
---|
155 | .ascii "zR\0" # CIE Augmentation
|
---|
156 | .uleb128 0x1 # CIE Code Alignment Factor
|
---|
157 | .sleb128 -4 # CIE Data Alignment Factor
|
---|
158 | .byte 0xe # CIE RA Column
|
---|
159 | .uleb128 0x1 # Augmentation size
|
---|
160 | .byte 0x1b # FDE Encoding (pcrel sdata4)
|
---|
161 | .byte 0xc # DW_CFA_def_cfa
|
---|
162 | .uleb128 0xf
|
---|
163 | .uleb128 0x60
|
---|
164 | .align 4
|
---|
165 | .LECIE1:
|
---|
166 | .LSFDE1:
|
---|
167 | .4byte .LEFDE1-.LASFDE1 # FDE Length
|
---|
168 | .LASFDE1:
|
---|
169 | .4byte .LASFDE1-.Lframe1 # FDE CIE offset
|
---|
170 | .4byte .LFB1-. # FDE initial location
|
---|
171 | .4byte .LFE1-.LFB1 # FDE address range
|
---|
172 | .uleb128 0x0 # Augmentation size
|
---|
173 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
174 | .4byte .LCFI0-.LFB1
|
---|
175 | .byte 0x8f # DW_CFA_offset, column 0xf
|
---|
176 | .uleb128 0x9
|
---|
177 | .byte 0x8e # DW_CFA_offset, column 0xe
|
---|
178 | .uleb128 0xa
|
---|
179 | .byte 0x8d # DW_CFA_offset, column 0xd
|
---|
180 | .uleb128 0xb
|
---|
181 | .byte 0x8c # DW_CFA_offset, column 0xc
|
---|
182 | .uleb128 0xc
|
---|
183 | .byte 0x8b # DW_CFA_offset, column 0xb
|
---|
184 | .uleb128 0xd
|
---|
185 | .byte 0x8a # DW_CFA_offset, column 0xa
|
---|
186 | .uleb128 0xe
|
---|
187 | .byte 0x89 # DW_CFA_offset, column 0x9
|
---|
188 | .uleb128 0xf
|
---|
189 | .byte 0x88 # DW_CFA_offset, column 0x8
|
---|
190 | .uleb128 0x10
|
---|
191 | .byte 0x87 # DW_CFA_offset, column 0x7
|
---|
192 | .uleb128 0x11
|
---|
193 | .byte 0x86 # DW_CFA_offset, column 0x6
|
---|
194 | .uleb128 0x12
|
---|
195 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
196 | .4byte .LCFI1-.LCFI0
|
---|
197 | .byte 0xd # DW_CFA_def_cfa_register
|
---|
198 | .uleb128 0xb
|
---|
199 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
200 | .4byte .LCFI2-.LCFI1
|
---|
201 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
202 | .uleb128 0x90
|
---|
203 | .align 4
|
---|
204 | .LEFDE1:
|
---|
205 | .LSFDE2:
|
---|
206 | .4byte .LEFDE2-.LASFDE2 # FDE Length
|
---|
207 | .LASFDE2:
|
---|
208 | .4byte .LASFDE2-.Lframe1 # FDE CIE offset
|
---|
209 | .4byte .LFB2-. # FDE initial location
|
---|
210 | .4byte .LFE2-.LFB2 # FDE address range
|
---|
211 | .uleb128 0x0 # Augmentation size
|
---|
212 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
213 | .4byte .LCFI10-.LFB2
|
---|
214 | .byte 0x8f # DW_CFA_offset, column 0xf
|
---|
215 | .uleb128 0x9
|
---|
216 | .byte 0x8e # DW_CFA_offset, column 0xe
|
---|
217 | .uleb128 0xa
|
---|
218 | .byte 0x8d # DW_CFA_offset, column 0xd
|
---|
219 | .uleb128 0xb
|
---|
220 | .byte 0x8c # DW_CFA_offset, column 0xc
|
---|
221 | .uleb128 0xc
|
---|
222 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
223 | .4byte .LCFI11-.LCFI10
|
---|
224 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
225 | .uleb128 0xc0
|
---|
226 | .align 4
|
---|
227 | .LEFDE2:
|
---|
228 |
|
---|
229 | #else
|
---|
230 |
|
---|
231 | .text
|
---|
232 |
|
---|
233 | # r2: cif->bytes
|
---|
234 | # r3: &ecif
|
---|
235 | # r4: ffi_prep_args
|
---|
236 | # r5: ret_type
|
---|
237 | # r6: ecif.rvalue
|
---|
238 | # ov: fn
|
---|
239 |
|
---|
240 | # This assumes we are using gas.
|
---|
241 | .globl ffi_call_SYSV
|
---|
242 | .type ffi_call_SYSV,%function
|
---|
243 | ffi_call_SYSV:
|
---|
244 | .LFB1:
|
---|
245 | stmg %r6,%r15,48(%r15) # Save registers
|
---|
246 | .LCFI0:
|
---|
247 | larl %r13,.Lbase # Set up base register
|
---|
248 | lgr %r11,%r15 # Set up frame pointer
|
---|
249 | .LCFI1:
|
---|
250 | sgr %r15,%r2
|
---|
251 | aghi %r15,-160-80 # Allocate stack
|
---|
252 | lgr %r8,%r6 # Save ecif.rvalue
|
---|
253 | llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
|
---|
254 | lg %r7,160(%r11) # Load function address
|
---|
255 | stg %r11,0(%r15) # Set up back chain
|
---|
256 | aghi %r11,-80 # Register save area
|
---|
257 | .LCFI2:
|
---|
258 |
|
---|
259 | la %r2,160(%r15) # Save area
|
---|
260 | # r3 already holds &ecif
|
---|
261 | basr %r14,%r4 # Call ffi_prep_args
|
---|
262 |
|
---|
263 | lmg %r2,%r6,0(%r11) # Load arguments
|
---|
264 | ld %f0,48(%r11)
|
---|
265 | ld %f2,56(%r11)
|
---|
266 | ld %f4,64(%r11)
|
---|
267 | ld %f6,72(%r11)
|
---|
268 | la %r14,0(%r13,%r9) # Set return address
|
---|
269 | br %r7 # ... and call function
|
---|
270 |
|
---|
271 | .Lbase:
|
---|
272 | .LretNone: # Return void
|
---|
273 | lg %r4,80+112(%r11)
|
---|
274 | lmg %r6,%r15,80+48(%r11)
|
---|
275 | br %r4
|
---|
276 |
|
---|
277 | .LretFloat:
|
---|
278 | lg %r4,80+112(%r11)
|
---|
279 | ste %f0,0(%r8) # Return float
|
---|
280 | lmg %r6,%r15,80+48(%r11)
|
---|
281 | br %r4
|
---|
282 |
|
---|
283 | .LretDouble:
|
---|
284 | lg %r4,80+112(%r11)
|
---|
285 | std %f0,0(%r8) # Return double
|
---|
286 | lmg %r6,%r15,80+48(%r11)
|
---|
287 | br %r4
|
---|
288 |
|
---|
289 | .LretInt32:
|
---|
290 | lg %r4,80+112(%r11)
|
---|
291 | st %r2,0(%r8) # Return int
|
---|
292 | lmg %r6,%r15,80+48(%r11)
|
---|
293 | br %r4
|
---|
294 |
|
---|
295 | .LretInt64:
|
---|
296 | lg %r4,80+112(%r11)
|
---|
297 | stg %r2,0(%r8) # Return long
|
---|
298 | lmg %r6,%r15,80+48(%r11)
|
---|
299 | br %r4
|
---|
300 |
|
---|
301 | .Ltable:
|
---|
302 | .byte .LretNone-.Lbase # FFI390_RET_VOID
|
---|
303 | .byte .LretNone-.Lbase # FFI390_RET_STRUCT
|
---|
304 | .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
|
---|
305 | .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
|
---|
306 | .byte .LretInt32-.Lbase # FFI390_RET_INT32
|
---|
307 | .byte .LretInt64-.Lbase # FFI390_RET_INT64
|
---|
308 |
|
---|
309 | .LFE1:
|
---|
310 | .ffi_call_SYSV_end:
|
---|
311 | .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
---|
312 |
|
---|
313 |
|
---|
314 | .globl ffi_closure_SYSV
|
---|
315 | .type ffi_closure_SYSV,%function
|
---|
316 | ffi_closure_SYSV:
|
---|
317 | .LFB2:
|
---|
318 | stmg %r14,%r15,112(%r15) # Save registers
|
---|
319 | .LCFI10:
|
---|
320 | stmg %r2,%r6,16(%r15) # Save arguments
|
---|
321 | std %f0,128(%r15)
|
---|
322 | std %f2,136(%r15)
|
---|
323 | std %f4,144(%r15)
|
---|
324 | std %f6,152(%r15)
|
---|
325 | lgr %r1,%r15 # Set up stack frame
|
---|
326 | aghi %r15,-160
|
---|
327 | .LCFI11:
|
---|
328 | lgr %r2,%r0 # Closure
|
---|
329 | la %r3,16(%r1) # GPRs
|
---|
330 | la %r4,128(%r1) # FPRs
|
---|
331 | la %r5,160(%r1) # Overflow
|
---|
332 | stg %r1,0(%r15) # Set up back chain
|
---|
333 |
|
---|
334 | brasl %r14,ffi_closure_helper_SYSV # Call helper
|
---|
335 |
|
---|
336 | lg %r14,160+112(%r15)
|
---|
337 | ld %f0,160+128(%r15) # Load return registers
|
---|
338 | lg %r2,160+16(%r15)
|
---|
339 | la %r15,160(%r15)
|
---|
340 | br %r14
|
---|
341 | .LFE2:
|
---|
342 |
|
---|
343 | .ffi_closure_SYSV_end:
|
---|
344 | .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
---|
345 |
|
---|
346 |
|
---|
347 |
|
---|
348 | .section .eh_frame,"a",@progbits
|
---|
349 | .Lframe1:
|
---|
350 | .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
|
---|
351 | .LSCIE1:
|
---|
352 | .4byte 0x0 # CIE Identifier Tag
|
---|
353 | .byte 0x1 # CIE Version
|
---|
354 | .ascii "zR\0" # CIE Augmentation
|
---|
355 | .uleb128 0x1 # CIE Code Alignment Factor
|
---|
356 | .sleb128 -8 # CIE Data Alignment Factor
|
---|
357 | .byte 0xe # CIE RA Column
|
---|
358 | .uleb128 0x1 # Augmentation size
|
---|
359 | .byte 0x1b # FDE Encoding (pcrel sdata4)
|
---|
360 | .byte 0xc # DW_CFA_def_cfa
|
---|
361 | .uleb128 0xf
|
---|
362 | .uleb128 0xa0
|
---|
363 | .align 8
|
---|
364 | .LECIE1:
|
---|
365 | .LSFDE1:
|
---|
366 | .4byte .LEFDE1-.LASFDE1 # FDE Length
|
---|
367 | .LASFDE1:
|
---|
368 | .4byte .LASFDE1-.Lframe1 # FDE CIE offset
|
---|
369 | .4byte .LFB1-. # FDE initial location
|
---|
370 | .4byte .LFE1-.LFB1 # FDE address range
|
---|
371 | .uleb128 0x0 # Augmentation size
|
---|
372 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
373 | .4byte .LCFI0-.LFB1
|
---|
374 | .byte 0x8f # DW_CFA_offset, column 0xf
|
---|
375 | .uleb128 0x5
|
---|
376 | .byte 0x8e # DW_CFA_offset, column 0xe
|
---|
377 | .uleb128 0x6
|
---|
378 | .byte 0x8d # DW_CFA_offset, column 0xd
|
---|
379 | .uleb128 0x7
|
---|
380 | .byte 0x8c # DW_CFA_offset, column 0xc
|
---|
381 | .uleb128 0x8
|
---|
382 | .byte 0x8b # DW_CFA_offset, column 0xb
|
---|
383 | .uleb128 0x9
|
---|
384 | .byte 0x8a # DW_CFA_offset, column 0xa
|
---|
385 | .uleb128 0xa
|
---|
386 | .byte 0x89 # DW_CFA_offset, column 0x9
|
---|
387 | .uleb128 0xb
|
---|
388 | .byte 0x88 # DW_CFA_offset, column 0x8
|
---|
389 | .uleb128 0xc
|
---|
390 | .byte 0x87 # DW_CFA_offset, column 0x7
|
---|
391 | .uleb128 0xd
|
---|
392 | .byte 0x86 # DW_CFA_offset, column 0x6
|
---|
393 | .uleb128 0xe
|
---|
394 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
395 | .4byte .LCFI1-.LCFI0
|
---|
396 | .byte 0xd # DW_CFA_def_cfa_register
|
---|
397 | .uleb128 0xb
|
---|
398 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
399 | .4byte .LCFI2-.LCFI1
|
---|
400 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
401 | .uleb128 0xf0
|
---|
402 | .align 8
|
---|
403 | .LEFDE1:
|
---|
404 | .LSFDE2:
|
---|
405 | .4byte .LEFDE2-.LASFDE2 # FDE Length
|
---|
406 | .LASFDE2:
|
---|
407 | .4byte .LASFDE2-.Lframe1 # FDE CIE offset
|
---|
408 | .4byte .LFB2-. # FDE initial location
|
---|
409 | .4byte .LFE2-.LFB2 # FDE address range
|
---|
410 | .uleb128 0x0 # Augmentation size
|
---|
411 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
412 | .4byte .LCFI10-.LFB2
|
---|
413 | .byte 0x8f # DW_CFA_offset, column 0xf
|
---|
414 | .uleb128 0x5
|
---|
415 | .byte 0x8e # DW_CFA_offset, column 0xe
|
---|
416 | .uleb128 0x6
|
---|
417 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
418 | .4byte .LCFI11-.LCFI10
|
---|
419 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
420 | .uleb128 0x140
|
---|
421 | .align 8
|
---|
422 | .LEFDE2:
|
---|
423 |
|
---|
424 | #endif
|
---|
425 |
|
---|