github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/s390/sysv.S (about)

     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  	.text
    33  
    34  #ifndef __s390x__
    35  
    36  	# r2:	frame
    37  	# r3:	ret_type
    38  	# r4:	ret_addr
    39  	# r5:	fun
    40  	# r6:	closure
    41  
    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
    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
    69  0:	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
    78  .Ltable:
    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
   115  
   116  
   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
   129  
   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
   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
   170  
   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
   181  	.align 4
   182  .Lchelper:
   183  	.long	ffi_closure_helper_SYSV-.Lcbase
   184  #endif
   185  
   186  	.size	 ffi_closure_SYSV,.-ffi_closure_SYSV
   187  
   188  #else
   189  
   190  	# r2:	frame
   191  	# r3:	ret_type
   192  	# r4:	ret_addr
   193  	# r5:	fun
   194  	# r6:	closure
   195  
   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
   224  
   225  	.balign	8
   226  .Ltable:
   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
   263  
   264  
   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
   278  
   279  
   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
   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
   310  	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
   311  
   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 */
   322  
   323  #if defined __ELF__ && defined __linux__
   324  	.section	.note.GNU-stack,"",@progbits
   325  #endif