Home | History | Annotate | Download | only in s390
      1 /* -----------------------------------------------------------------------
      2    sysv.S - Copyright (c) 2000 Software AG
      3             Copyright (c) 2008 Red Hat, Inc.
      4 
      5    S390 Foreign Function Interface
      6 
      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:
     14 
     15    The above copyright notice and this permission notice shall be included
     16    in all copies or substantial portions of the Software.
     17 
     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    ----------------------------------------------------------------------- */
     27 
     28 #define LIBFFI_ASM
     29 #include <fficonfig.h>
     30 #include <ffi.h>
     31 
     32 #ifndef __s390x__
     33 
     34 .text
     35 
     36 	# r2:	cif->bytes
     37 	# r3:	&ecif
     38 	# r4:	ffi_prep_args
     39 	# r5:	ret_type
     40 	# r6:	ecif.rvalue
     41 	# ov:	fn
     42 
     43 	# This assumes we are using gas.
     44 	.globl	ffi_call_SYSV
     45 	.type	ffi_call_SYSV,%function
     46 ffi_call_SYSV:
     47 .LFB1:
     48 	stm	%r6,%r15,24(%r15)		# Save registers
     49 .LCFI0:
     50 	basr	%r13,0				# Set up base register
     51 .Lbase:
     52 	lr	%r11,%r15			# Set up frame pointer
     53 .LCFI1:
     54 	sr	%r15,%r2
     55 	ahi	%r15,-96-48			# Allocate stack
     56 	lr	%r8,%r6				# Save ecif.rvalue
     57 	sr	%r9,%r9
     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
     62 .LCFI2:
     63 
     64 	la	%r2,96(%r15)			# Save area
     65 						# r3 already holds &ecif
     66 	basr	%r14,%r4			# Call ffi_prep_args
     67 
     68 	lm	%r2,%r6,0(%r11)			# Load arguments
     69 	ld	%f0,32(%r11)
     70 	ld	%f2,40(%r11)
     71 	la	%r14,0(%r13,%r9)		# Set return address
     72 	br	%r7				# ... and call function
     73 
     74 .LretNone:					# Return void
     75 	l	%r4,48+56(%r11)
     76 	lm	%r6,%r15,48+24(%r11)
     77 	br	%r4
     78 
     79 .LretFloat:
     80 	l	%r4,48+56(%r11)
     81 	ste	%f0,0(%r8)			# Return float
     82 	lm	%r6,%r15,48+24(%r11)
     83 	br	%r4
     84 
     85 .LretDouble:
     86 	l	%r4,48+56(%r11)
     87 	std	%f0,0(%r8)			# Return double
     88 	lm	%r6,%r15,48+24(%r11)
     89 	br	%r4
     90 
     91 .LretInt32:
     92 	l	%r4,48+56(%r11)
     93 	st	%r2,0(%r8)			# Return int
     94 	lm	%r6,%r15,48+24(%r11)
     95 	br	%r4
     96 
     97 .LretInt64:
     98 	l	%r4,48+56(%r11)
     99 	stm	%r2,%r3,0(%r8)			# Return long long
    100 	lm	%r6,%r15,48+24(%r11)
    101 	br	%r4
    102 
    103 .Ltable:
    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
    110 
    111 .LFE1:
    112 .ffi_call_SYSV_end:
    113 	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
    114 
    115 
    116 	.globl	ffi_closure_SYSV
    117 	.type	ffi_closure_SYSV,%function
    118 ffi_closure_SYSV:
    119 .LFB2:
    120 	stm	%r12,%r15,48(%r15)		# Save registers
    121 .LCFI10:
    122 	basr	%r13,0				# Set up base register
    123 .Lcbase:
    124 	stm	%r2,%r6,8(%r15)			# Save arguments
    125 	std	%f0,64(%r15)
    126 	std	%f2,72(%r15)
    127 	lr	%r1,%r15			# Set up stack frame
    128 	ahi	%r15,-96
    129 .LCFI11:
    130 	l	%r12,.Lchelper-.Lcbase(%r13)	# Get helper function
    131 	lr	%r2,%r0				# Closure
    132 	la	%r3,8(%r1)			# GPRs
    133 	la	%r4,64(%r1)			# FPRs
    134 	la	%r5,96(%r1)			# Overflow
    135 	st	%r1,0(%r15)			# Set up back chain
    136 
    137 	bas	%r14,0(%r12,%r13)		# Call helper
    138 
    139 	l	%r4,96+56(%r15)
    140 	ld	%f0,96+64(%r15)			# Load return registers
    141 	lm	%r2,%r3,96+8(%r15)
    142 	lm	%r12,%r15,96+48(%r15)
    143 	br	%r4
    144 
    145 	.align 4
    146 .Lchelper:
    147 	.long	ffi_closure_helper_SYSV-.Lcbase
    148 
    149 .LFE2:
    150 
    151 .ffi_closure_SYSV_end:
    152 	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
    153 
    154 
    155 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
    156 .Lframe1:
    157 	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
    158 .LSCIE1:
    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
    168 	.uleb128 0xf
    169 	.uleb128 0x60
    170 	.align	4
    171 .LECIE1:
    172 .LSFDE1:
    173 	.4byte	.LEFDE1-.LASFDE1	# FDE Length
    174 .LASFDE1:
    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
    180 	.4byte	.LCFI0-.LFB1
    181 	.byte	0x8f	# DW_CFA_offset, column 0xf
    182 	.uleb128 0x9
    183 	.byte	0x8e	# DW_CFA_offset, column 0xe
    184 	.uleb128 0xa
    185 	.byte	0x8d	# DW_CFA_offset, column 0xd
    186 	.uleb128 0xb
    187 	.byte	0x8c	# DW_CFA_offset, column 0xc
    188 	.uleb128 0xc
    189 	.byte	0x8b	# DW_CFA_offset, column 0xb
    190 	.uleb128 0xd
    191 	.byte	0x8a	# DW_CFA_offset, column 0xa
    192 	.uleb128 0xe
    193 	.byte	0x89	# DW_CFA_offset, column 0x9
    194 	.uleb128 0xf
    195 	.byte	0x88	# DW_CFA_offset, column 0x8
    196 	.uleb128 0x10
    197 	.byte	0x87	# DW_CFA_offset, column 0x7
    198 	.uleb128 0x11
    199 	.byte	0x86	# DW_CFA_offset, column 0x6
    200 	.uleb128 0x12
    201 	.byte	0x4	# DW_CFA_advance_loc4
    202 	.4byte	.LCFI1-.LCFI0
    203 	.byte	0xd	# DW_CFA_def_cfa_register
    204 	.uleb128 0xb
    205 	.byte	0x4	# DW_CFA_advance_loc4
    206 	.4byte	.LCFI2-.LCFI1
    207 	.byte	0xe	# DW_CFA_def_cfa_offset
    208 	.uleb128 0x90
    209 	.align	4
    210 .LEFDE1:
    211 .LSFDE2:
    212 	.4byte	.LEFDE2-.LASFDE2	# FDE Length
    213 .LASFDE2:
    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
    219 	.4byte	.LCFI10-.LFB2
    220 	.byte	0x8f	# DW_CFA_offset, column 0xf
    221 	.uleb128 0x9
    222 	.byte	0x8e	# DW_CFA_offset, column 0xe
    223 	.uleb128 0xa
    224 	.byte	0x8d	# DW_CFA_offset, column 0xd
    225 	.uleb128 0xb
    226 	.byte	0x8c	# DW_CFA_offset, column 0xc
    227 	.uleb128 0xc
    228 	.byte	0x4	# DW_CFA_advance_loc4
    229 	.4byte	.LCFI11-.LCFI10
    230 	.byte	0xe	# DW_CFA_def_cfa_offset
    231 	.uleb128 0xc0
    232 	.align	4
    233 .LEFDE2:
    234 
    235 #else
    236 
    237 .text
    238 
    239 	# r2:	cif->bytes
    240 	# r3:	&ecif
    241 	# r4:	ffi_prep_args
    242 	# r5:	ret_type
    243 	# r6:	ecif.rvalue
    244 	# ov:	fn
    245 
    246 	# This assumes we are using gas.
    247 	.globl	ffi_call_SYSV
    248 	.type	ffi_call_SYSV,%function
    249 ffi_call_SYSV:
    250 .LFB1:
    251 	stmg	%r6,%r15,48(%r15)		# Save registers
    252 .LCFI0:
    253 	larl	%r13,.Lbase			# Set up base register
    254 	lgr	%r11,%r15			# Set up frame pointer
    255 .LCFI1:
    256 	sgr	%r15,%r2
    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
    263 .LCFI2:
    264 
    265 	la	%r2,160(%r15)			# Save area
    266 						# r3 already holds &ecif
    267 	basr	%r14,%r4			# Call ffi_prep_args
    268 
    269 	lmg	%r2,%r6,0(%r11)			# Load arguments
    270 	ld	%f0,48(%r11)
    271 	ld	%f2,56(%r11)
    272 	ld	%f4,64(%r11)
    273 	ld	%f6,72(%r11)
    274 	la	%r14,0(%r13,%r9)		# Set return address
    275 	br	%r7				# ... and call function
    276 
    277 .Lbase:
    278 .LretNone:					# Return void
    279 	lg	%r4,80+112(%r11)
    280 	lmg	%r6,%r15,80+48(%r11)
    281 	br	%r4
    282 
    283 .LretFloat:
    284 	lg	%r4,80+112(%r11)
    285 	ste	%f0,0(%r8)			# Return float
    286 	lmg	%r6,%r15,80+48(%r11)
    287 	br	%r4
    288 
    289 .LretDouble:
    290 	lg	%r4,80+112(%r11)
    291 	std	%f0,0(%r8)			# Return double
    292 	lmg	%r6,%r15,80+48(%r11)
    293 	br	%r4
    294 
    295 .LretInt32:
    296 	lg	%r4,80+112(%r11)
    297 	st	%r2,0(%r8)			# Return int
    298 	lmg	%r6,%r15,80+48(%r11)
    299 	br	%r4
    300 
    301 .LretInt64:
    302 	lg	%r4,80+112(%r11)
    303 	stg	%r2,0(%r8)			# Return long
    304 	lmg	%r6,%r15,80+48(%r11)
    305 	br	%r4
    306 
    307 .Ltable:
    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
    314 
    315 .LFE1:
    316 .ffi_call_SYSV_end:
    317 	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
    318 
    319 
    320 	.globl	ffi_closure_SYSV
    321 	.type	ffi_closure_SYSV,%function
    322 ffi_closure_SYSV:
    323 .LFB2:
    324 	stmg	%r14,%r15,112(%r15)		# Save registers
    325 .LCFI10:
    326 	stmg	%r2,%r6,16(%r15)		# Save arguments
    327 	std	%f0,128(%r15)
    328 	std	%f2,136(%r15)
    329 	std	%f4,144(%r15)
    330 	std	%f6,152(%r15)
    331 	lgr	%r1,%r15			# Set up stack frame
    332 	aghi	%r15,-160
    333 .LCFI11:
    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
    339 
    340 	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
    341 
    342 	lg	%r14,160+112(%r15)
    343 	ld	%f0,160+128(%r15)		# Load return registers
    344 	lg	%r2,160+16(%r15)
    345 	la	%r15,160(%r15)
    346 	br	%r14
    347 .LFE2:
    348 
    349 .ffi_closure_SYSV_end:
    350 	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
    351 
    352 
    353 
    354 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
    355 .Lframe1:
    356 	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
    357 .LSCIE1:
    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
    367 	.uleb128 0xf
    368 	.uleb128 0xa0
    369 	.align	8
    370 .LECIE1:
    371 .LSFDE1:
    372 	.4byte	.LEFDE1-.LASFDE1	# FDE Length
    373 .LASFDE1:
    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
    379 	.4byte	.LCFI0-.LFB1
    380 	.byte	0x8f	# DW_CFA_offset, column 0xf
    381 	.uleb128 0x5
    382 	.byte	0x8e	# DW_CFA_offset, column 0xe
    383 	.uleb128 0x6
    384 	.byte	0x8d	# DW_CFA_offset, column 0xd
    385 	.uleb128 0x7
    386 	.byte	0x8c	# DW_CFA_offset, column 0xc
    387 	.uleb128 0x8
    388 	.byte	0x8b	# DW_CFA_offset, column 0xb
    389 	.uleb128 0x9
    390 	.byte	0x8a	# DW_CFA_offset, column 0xa
    391 	.uleb128 0xa
    392 	.byte	0x89	# DW_CFA_offset, column 0x9
    393 	.uleb128 0xb
    394 	.byte	0x88	# DW_CFA_offset, column 0x8
    395 	.uleb128 0xc
    396 	.byte	0x87	# DW_CFA_offset, column 0x7
    397 	.uleb128 0xd
    398 	.byte	0x86	# DW_CFA_offset, column 0x6
    399 	.uleb128 0xe
    400 	.byte	0x4	# DW_CFA_advance_loc4
    401 	.4byte	.LCFI1-.LCFI0
    402 	.byte	0xd	# DW_CFA_def_cfa_register
    403 	.uleb128 0xb
    404 	.byte	0x4	# DW_CFA_advance_loc4
    405 	.4byte	.LCFI2-.LCFI1
    406 	.byte	0xe	# DW_CFA_def_cfa_offset
    407 	.uleb128 0xf0
    408 	.align	8
    409 .LEFDE1:
    410 .LSFDE2:
    411 	.4byte	.LEFDE2-.LASFDE2	# FDE Length
    412 .LASFDE2:
    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
    418 	.4byte	.LCFI10-.LFB2
    419 	.byte	0x8f	# DW_CFA_offset, column 0xf
    420 	.uleb128 0x5
    421 	.byte	0x8e	# DW_CFA_offset, column 0xe
    422 	.uleb128 0x6
    423 	.byte	0x4	# DW_CFA_advance_loc4
    424 	.4byte	.LCFI11-.LCFI10
    425 	.byte	0xe	# DW_CFA_def_cfa_offset
    426 	.uleb128 0x140
    427 	.align	8
    428 .LEFDE2:
    429 
    430 #endif
    431 
    432 #if defined __ELF__ && defined __linux__
    433 	.section	.note.GNU-stack,"",@progbits
    434 #endif
    435