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>
43 # This assumes we are using gas.
45 .type ffi_call_SYSV,%function
48 stm %r6,%r15,24(%r15) # Save registers
50 basr %r13,0 # Set up base register
52 lr %r11,%r15 # Set up frame pointer
55 ahi %r15,-96-48 # Allocate stack
56 lr %r8,%r6 # Save ecif.rvalue
58 ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
59 l %r7,96(%r11) # Load function address
60 st %r11,0(%r15) # Set up back chain
61 ahi %r11,-48 # Register save area
64 la %r2,96(%r15) # Save area
65 # r3 already holds &ecif
66 basr %r14,%r4 # Call ffi_prep_args
68 lm %r2,%r6,0(%r11) # Load arguments
71 la %r14,0(%r13,%r9) # Set return address
72 br %r7 # ... and call function
74 .LretNone: # Return void
76 lm %r6,%r15,48+24(%r11)
81 ste %f0,0(%r8) # Return float
82 lm %r6,%r15,48+24(%r11)
87 std %f0,0(%r8) # Return double
88 lm %r6,%r15,48+24(%r11)
93 st %r2,0(%r8) # Return int
94 lm %r6,%r15,48+24(%r11)
99 stm %r2,%r3,0(%r8) # Return long long
100 lm %r6,%r15,48+24(%r11)
104 .byte .LretNone-.Lbase # FFI390_RET_VOID
105 .byte .LretNone-.Lbase # FFI390_RET_STRUCT
106 .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
107 .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
108 .byte .LretInt32-.Lbase # FFI390_RET_INT32
109 .byte .LretInt64-.Lbase # FFI390_RET_INT64
113 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
116 .globl ffi_closure_SYSV
117 .type ffi_closure_SYSV,%function
120 stm %r12,%r15,48(%r15) # Save registers
122 basr %r13,0 # Set up base register
124 stm %r2,%r6,8(%r15) # Save arguments
127 lr %r1,%r15 # Set up stack frame
130 l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
133 la %r4,64(%r1) # FPRs
134 la %r5,96(%r1) # Overflow
135 st %r1,0(%r15) # Set up back chain
137 bas %r14,0(%r12,%r13) # Call helper
140 ld %f0,96+64(%r15) # Load return registers
141 lm %r2,%r3,96+8(%r15)
142 lm %r12,%r15,96+48(%r15)
147 .long ffi_closure_helper_SYSV-.Lcbase
151 .ffi_closure_SYSV_end:
152 .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
155 .section .eh_frame,EH_FRAME_FLAGS,@progbits
157 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
159 .4byte 0x0 # CIE Identifier Tag
160 .byte 0x1 # CIE Version
161 .ascii "zR\0" # CIE Augmentation
162 .uleb128 0x1 # CIE Code Alignment Factor
163 .sleb128 -4 # CIE Data Alignment Factor
164 .byte 0xe # CIE RA Column
165 .uleb128 0x1 # Augmentation size
166 .byte 0x1b # FDE Encoding (pcrel sdata4)
167 .byte 0xc # DW_CFA_def_cfa
173 .4byte .LEFDE1-.LASFDE1 # FDE Length
175 .4byte .LASFDE1-.Lframe1 # FDE CIE offset
176 .4byte .LFB1-. # FDE initial location
177 .4byte .LFE1-.LFB1 # FDE address range
178 .uleb128 0x0 # Augmentation size
179 .byte 0x4 # DW_CFA_advance_loc4
181 .byte 0x8f # DW_CFA_offset, column 0xf
183 .byte 0x8e # DW_CFA_offset, column 0xe
185 .byte 0x8d # DW_CFA_offset, column 0xd
187 .byte 0x8c # DW_CFA_offset, column 0xc
189 .byte 0x8b # DW_CFA_offset, column 0xb
191 .byte 0x8a # DW_CFA_offset, column 0xa
193 .byte 0x89 # DW_CFA_offset, column 0x9
195 .byte 0x88 # DW_CFA_offset, column 0x8
197 .byte 0x87 # DW_CFA_offset, column 0x7
199 .byte 0x86 # DW_CFA_offset, column 0x6
201 .byte 0x4 # DW_CFA_advance_loc4
203 .byte 0xd # DW_CFA_def_cfa_register
205 .byte 0x4 # DW_CFA_advance_loc4
207 .byte 0xe # DW_CFA_def_cfa_offset
212 .4byte .LEFDE2-.LASFDE2 # FDE Length
214 .4byte .LASFDE2-.Lframe1 # FDE CIE offset
215 .4byte .LFB2-. # FDE initial location
216 .4byte .LFE2-.LFB2 # FDE address range
217 .uleb128 0x0 # Augmentation size
218 .byte 0x4 # DW_CFA_advance_loc4
220 .byte 0x8f # DW_CFA_offset, column 0xf
222 .byte 0x8e # DW_CFA_offset, column 0xe
224 .byte 0x8d # DW_CFA_offset, column 0xd
226 .byte 0x8c # DW_CFA_offset, column 0xc
228 .byte 0x4 # DW_CFA_advance_loc4
229 .4byte .LCFI11-.LCFI10
230 .byte 0xe # DW_CFA_def_cfa_offset
246 # This assumes we are using gas.
248 .type ffi_call_SYSV,%function
251 stmg %r6,%r15,48(%r15) # Save registers
253 larl %r13,.Lbase # Set up base register
254 lgr %r11,%r15 # Set up frame pointer
257 aghi %r15,-160-80 # Allocate stack
258 lgr %r8,%r6 # Save ecif.rvalue
259 llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
260 lg %r7,160(%r11) # Load function address
261 stg %r11,0(%r15) # Set up back chain
262 aghi %r11,-80 # Register save area
265 la %r2,160(%r15) # Save area
266 # r3 already holds &ecif
267 basr %r14,%r4 # Call ffi_prep_args
269 lmg %r2,%r6,0(%r11) # Load arguments
274 la %r14,0(%r13,%r9) # Set return address
275 br %r7 # ... and call function
278 .LretNone: # Return void
280 lmg %r6,%r15,80+48(%r11)
285 ste %f0,0(%r8) # Return float
286 lmg %r6,%r15,80+48(%r11)
291 std %f0,0(%r8) # Return double
292 lmg %r6,%r15,80+48(%r11)
297 st %r2,0(%r8) # Return int
298 lmg %r6,%r15,80+48(%r11)
303 stg %r2,0(%r8) # Return long
304 lmg %r6,%r15,80+48(%r11)
308 .byte .LretNone-.Lbase # FFI390_RET_VOID
309 .byte .LretNone-.Lbase # FFI390_RET_STRUCT
310 .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
311 .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
312 .byte .LretInt32-.Lbase # FFI390_RET_INT32
313 .byte .LretInt64-.Lbase # FFI390_RET_INT64
317 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
320 .globl ffi_closure_SYSV
321 .type ffi_closure_SYSV,%function
324 stmg %r14,%r15,112(%r15) # Save registers
326 stmg %r2,%r6,16(%r15) # Save arguments
331 lgr %r1,%r15 # Set up stack frame
334 lgr %r2,%r0 # Closure
335 la %r3,16(%r1) # GPRs
336 la %r4,128(%r1) # FPRs
337 la %r5,160(%r1) # Overflow
338 stg %r1,0(%r15) # Set up back chain
340 brasl %r14,ffi_closure_helper_SYSV # Call helper
342 lg %r14,160+112(%r15)
343 ld %f0,160+128(%r15) # Load return registers
349 .ffi_closure_SYSV_end:
350 .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
354 .section .eh_frame,EH_FRAME_FLAGS,@progbits
356 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
358 .4byte 0x0 # CIE Identifier Tag
359 .byte 0x1 # CIE Version
360 .ascii "zR\0" # CIE Augmentation
361 .uleb128 0x1 # CIE Code Alignment Factor
362 .sleb128 -8 # CIE Data Alignment Factor
363 .byte 0xe # CIE RA Column
364 .uleb128 0x1 # Augmentation size
365 .byte 0x1b # FDE Encoding (pcrel sdata4)
366 .byte 0xc # DW_CFA_def_cfa
372 .4byte .LEFDE1-.LASFDE1 # FDE Length
374 .4byte .LASFDE1-.Lframe1 # FDE CIE offset
375 .4byte .LFB1-. # FDE initial location
376 .4byte .LFE1-.LFB1 # FDE address range
377 .uleb128 0x0 # Augmentation size
378 .byte 0x4 # DW_CFA_advance_loc4
380 .byte 0x8f # DW_CFA_offset, column 0xf
382 .byte 0x8e # DW_CFA_offset, column 0xe
384 .byte 0x8d # DW_CFA_offset, column 0xd
386 .byte 0x8c # DW_CFA_offset, column 0xc
388 .byte 0x8b # DW_CFA_offset, column 0xb
390 .byte 0x8a # DW_CFA_offset, column 0xa
392 .byte 0x89 # DW_CFA_offset, column 0x9
394 .byte 0x88 # DW_CFA_offset, column 0x8
396 .byte 0x87 # DW_CFA_offset, column 0x7
398 .byte 0x86 # DW_CFA_offset, column 0x6
400 .byte 0x4 # DW_CFA_advance_loc4
402 .byte 0xd # DW_CFA_def_cfa_register
404 .byte 0x4 # DW_CFA_advance_loc4
406 .byte 0xe # DW_CFA_def_cfa_offset
411 .4byte .LEFDE2-.LASFDE2 # FDE Length
413 .4byte .LASFDE2-.Lframe1 # FDE CIE offset
414 .4byte .LFB2-. # FDE initial location
415 .4byte .LFE2-.LFB2 # FDE address range
416 .uleb128 0x0 # Augmentation size
417 .byte 0x4 # DW_CFA_advance_loc4
419 .byte 0x8f # DW_CFA_offset, column 0xf
421 .byte 0x8e # DW_CFA_offset, column 0xe
423 .byte 0x4 # DW_CFA_advance_loc4
424 .4byte .LCFI11-.LCFI10
425 .byte 0xe # DW_CFA_def_cfa_offset
432 #if defined __ELF__ && defined __linux__
433 .section .note.GNU-stack,"",@progbits