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

     1  /* -----------------------------------------------------------------------
     2     v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
     3     
     4     SPARC 64-bit 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,
    18     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    19     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    20     NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    21     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    22     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    23     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    24     DEALINGS IN THE SOFTWARE.
    25     ----------------------------------------------------------------------- */
    26  
    27  #define LIBFFI_ASM	
    28  #include <fficonfig.h>
    29  #include <ffi.h>
    30  #include <ffi_cfi.h>
    31  #include "internal.h"
    32  
    33  #ifdef SPARC64
    34  
    35  #define C2(X, Y)  X ## Y
    36  #define C1(X, Y)  C2(X, Y)
    37  
    38  #ifdef __USER_LABEL_PREFIX__
    39  # define C(Y)	C1(__USER_LABEL_PREFIX__, Y)
    40  #else
    41  # define C(Y)	Y
    42  #endif
    43  #define L(Y)	C1(.L, Y)
    44  
    45  .macro E index
    46  	.align	16
    47  	.org	2b + \index * 16
    48  .endm
    49  
    50  #define STACK_BIAS 2047
    51  
    52  	.text
    53          .align 8
    54  	.globl	C(ffi_call_v9)
    55  	.type	C(ffi_call_v9),@function
    56  	FFI_HIDDEN(C(ffi_call_v9))
    57  
    58  C(ffi_call_v9):
    59  	cfi_startproc
    60  	save	%sp, %o4, %sp
    61  	cfi_def_cfa_register(%fp)
    62  	cfi_window_save
    63  	
    64  	mov	%i0, %o0			! copy cif
    65  	add	%sp, STACK_BIAS+128+48, %o1	! load args area
    66  	mov	%i2, %o2			! copy rvalue
    67  	call	C(ffi_prep_args_v9)
    68  	 mov	%i3, %o3			! copy avalue
    69  
    70  	andcc	%o0, SPARC_FLAG_FP_ARGS, %g0	! need fp regs?
    71  	add	%sp, 48, %sp			! deallocate prep frame
    72  	be,pt	%xcc, 1f
    73  	 mov	%o0, %l0			! save flags
    74  
    75  	ldd	[%sp+STACK_BIAS+128], %f0	! load all fp arg regs
    76  	ldd	[%sp+STACK_BIAS+128+8], %f2
    77  	ldd	[%sp+STACK_BIAS+128+16], %f4
    78  	ldd	[%sp+STACK_BIAS+128+24], %f6
    79  	ldd	[%sp+STACK_BIAS+128+32], %f8
    80  	ldd	[%sp+STACK_BIAS+128+40], %f10
    81  	ldd	[%sp+STACK_BIAS+128+48], %f12
    82  	ldd	[%sp+STACK_BIAS+128+56], %f14
    83  	ldd	[%sp+STACK_BIAS+128+64], %f16
    84  	ldd	[%sp+STACK_BIAS+128+72], %f18
    85  	ldd	[%sp+STACK_BIAS+128+80], %f20
    86  	ldd	[%sp+STACK_BIAS+128+88], %f22
    87  	ldd	[%sp+STACK_BIAS+128+96], %f24
    88  	ldd	[%sp+STACK_BIAS+128+104], %f26
    89  	ldd	[%sp+STACK_BIAS+128+112], %f28
    90  	ldd	[%sp+STACK_BIAS+128+120], %f30
    91  
    92  1:	ldx	[%sp+STACK_BIAS+128], %o0	! load all int arg regs
    93  	ldx	[%sp+STACK_BIAS+128+8], %o1
    94  	ldx	[%sp+STACK_BIAS+128+16], %o2
    95  	ldx	[%sp+STACK_BIAS+128+24], %o3
    96  	ldx	[%sp+STACK_BIAS+128+32], %o4
    97  	ldx	[%sp+STACK_BIAS+128+40], %o5
    98  	call	%i1
    99  	 mov	%i5, %g5			! load static chain
   100  
   101  0:	call	1f		! load pc in %o7
   102  	 and	%l0, SPARC_FLAG_RET_MASK, %l1
   103  1:	sll	%l1, 4, %l1
   104  	add	%o7, %l1, %o7	! o7 = 0b + ret_type*16
   105  	jmp	%o7+(2f-0b)
   106  	 nop
   107  
   108  	.align	16
   109  2:
   110  E SPARC_RET_VOID
   111  	return	%i7+8
   112  	 nop
   113  E SPARC_RET_STRUCT
   114  	add	%sp, STACK_BIAS-64+128+48, %l2
   115  	sub	%sp, 64, %sp
   116  	b	8f
   117  	 stx	%o0, [%l2]
   118  E SPARC_RET_UINT8
   119  	and	%o0, 0xff, %i0
   120  	return	%i7+8
   121  	  stx	%o0, [%o2]
   122  E SPARC_RET_SINT8
   123  	sll	%o0, 24, %o0
   124  	sra	%o0, 24, %i0
   125  	return	%i7+8
   126  	 stx	%o0, [%o2]
   127  E SPARC_RET_UINT16
   128  	sll	%o0, 16, %o0
   129  	srl	%o0, 16, %i0
   130  	return	%i7+8
   131  	 stx	%o0, [%o2]
   132  E SPARC_RET_SINT16
   133  	sll	%o0, 16, %o0
   134  	sra	%o0, 16, %i0
   135  	return	%i7+8
   136  	 stx	%o0, [%o2]
   137  E SPARC_RET_UINT32
   138  	srl	%o0, 0, %i0
   139  	return	%i7+8
   140  	 stx	%o0, [%o2]
   141  E SP_V9_RET_SINT32
   142  	sra	%o0, 0, %i0
   143  	return	%i7+8
   144  	 stx	%o0, [%o2]
   145  E SPARC_RET_INT64
   146  	stx	%o0, [%i2]
   147  	return	%i7+8
   148  	 nop
   149  E SPARC_RET_INT128
   150  	stx	%o0, [%i2]
   151  	stx	%o1, [%i2+8]
   152  	return	%i7+8
   153  	 nop
   154  E SPARC_RET_F_8
   155  	st	%f7, [%i2+7*4]
   156  	nop
   157  	st	%f6, [%i2+6*4]
   158  	nop
   159  E SPARC_RET_F_6
   160  	st	%f5, [%i2+5*4]
   161  	nop
   162  	st	%f4, [%i2+4*4]
   163  	nop
   164  E SPARC_RET_F_4
   165  	std	%f2, [%i2+2*4]
   166  	return	%i7+8
   167  	 std	%f0, [%o2]
   168  E SPARC_RET_F_2
   169  	return	%i7+8
   170  	 std	%f0, [%o2]
   171  E SP_V9_RET_F_3
   172  	st	%f2, [%i2+2*4]
   173  	nop
   174  	st	%f1, [%i2+1*4]
   175  	nop
   176  E SPARC_RET_F_1
   177  	return	%i7+8
   178  	 st	%f0, [%o2]
   179  
   180  	! Finish the SPARC_RET_STRUCT sequence.
   181  	.align	8
   182  8:	stx	%o1, [%l2+8]
   183  	stx	%o2, [%l2+16]
   184  	stx	%o3, [%l2+24]
   185  	std	%f0, [%l2+32]
   186  	std	%f2, [%l2+40]
   187  	std	%f4, [%l2+48]
   188  	std	%f6, [%l2+56]
   189  
   190  	! Copy the structure into place.
   191  	srl	%l0, SPARC_SIZEMASK_SHIFT, %o0	! load size_mask
   192  	mov	%i2, %o1			! load dst
   193  	mov	%l2, %o2			! load src_gp
   194  	call	C(ffi_struct_float_copy)
   195  	 add	%l2, 32, %o3			! load src_fp
   196  
   197  	return	%i7+8
   198  	 nop
   199  
   200  	cfi_endproc
   201  	.size	C(ffi_call_v9), . - C(ffi_call_v9)
   202  
   203  
   204  #undef STACKFRAME
   205  #define	STACKFRAME	 336	/* 16*8 register window +
   206  				   6*8 args backing store +
   207  				   20*8 locals */
   208  #define	FP		%fp+STACK_BIAS
   209  
   210  /* ffi_closure_v9(...)
   211  
   212     Receives the closure argument in %g1.   */
   213  
   214  	.align 8
   215  	.globl	C(ffi_go_closure_v9)
   216  	.type	C(ffi_go_closure_v9),@function
   217  	FFI_HIDDEN(C(ffi_go_closure_v9))
   218  
   219  C(ffi_go_closure_v9):
   220  	cfi_startproc
   221  	save	%sp, -STACKFRAME, %sp
   222  	cfi_def_cfa_register(%fp)
   223  	cfi_window_save
   224  
   225  	ldx	[%g5+8], %o0
   226  	ldx	[%g5+16], %o1
   227  	b	0f
   228  	 mov	%g5, %o2
   229  
   230  	cfi_endproc
   231  	.size	C(ffi_go_closure_v9), . - C(ffi_go_closure_v9)
   232  
   233  	.align 8
   234  	.globl	C(ffi_closure_v9)
   235  	.type	C(ffi_closure_v9),@function
   236  	FFI_HIDDEN(C(ffi_closure_v9))
   237  
   238  C(ffi_closure_v9):
   239  	cfi_startproc
   240  	save	%sp, -STACKFRAME, %sp
   241  	cfi_def_cfa_register(%fp)
   242  	cfi_window_save
   243  
   244  	ldx	[%g1+FFI_TRAMPOLINE_SIZE], %o0
   245  	ldx	[%g1+FFI_TRAMPOLINE_SIZE+8], %o1
   246  	ldx	[%g1+FFI_TRAMPOLINE_SIZE+16], %o2
   247  0:
   248  	! Store all of the potential argument registers in va_list format.
   249  	stx	%i0, [FP+128+0]
   250  	stx	%i1, [FP+128+8]
   251  	stx	%i2, [FP+128+16]
   252  	stx	%i3, [FP+128+24]
   253  	stx	%i4, [FP+128+32]
   254  	stx	%i5, [FP+128+40]
   255  
   256  	! Store possible floating point argument registers too.
   257  	std	%f0,  [FP-128]
   258  	std	%f2,  [FP-120]
   259  	std	%f4,  [FP-112]
   260  	std	%f6,  [FP-104]
   261  	std	%f8,  [FP-96]
   262  	std	%f10, [FP-88]
   263  	std     %f12, [FP-80]
   264  	std     %f14, [FP-72]
   265  	std     %f16, [FP-64]
   266  	std     %f18, [FP-56]
   267  	std     %f20, [FP-48]
   268  	std     %f22, [FP-40]
   269  	std     %f24, [FP-32]
   270  	std     %f26, [FP-24]
   271  	std     %f28, [FP-16]
   272  	std     %f30, [FP-8]
   273  
   274  	! Call ffi_closure_sparc_inner to do the bulk of the work.
   275  	add	%fp, STACK_BIAS-160, %o3
   276  	add	%fp, STACK_BIAS+128, %o4
   277  	call	C(ffi_closure_sparc_inner_v9)
   278  	 add	%fp, STACK_BIAS-128, %o5
   279  
   280  0:	call	1f		! load pc in %o7
   281  	 and	%o0, SPARC_FLAG_RET_MASK, %o0
   282  1:	sll	%o0, 4, %o0	! o2 = i2 * 16
   283  	add	%o7, %o0, %o7	! o7 = 0b + i2*16
   284  	jmp	%o7+(2f-0b)
   285  	 nop
   286  
   287  	! Note that we cannot load the data in the delay slot of
   288  	! the return insn because the data is in the stack frame
   289  	! that is deallocated by the return.
   290  	.align	16
   291  2:
   292  E SPARC_RET_VOID
   293  	return	%i7+8
   294  	 nop
   295  E SPARC_RET_STRUCT
   296  	ldx	[FP-160], %i0
   297  	ldd	[FP-160], %f0
   298  	b	8f
   299  	 ldx	[FP-152], %i1
   300  E SPARC_RET_UINT8
   301  	ldub	[FP-160+7], %i0
   302  	return	%i7+8
   303  	 nop
   304  E SPARC_RET_SINT8
   305  	ldsb	[FP-160+7], %i0
   306  	return	%i7+8
   307  	 nop
   308  E SPARC_RET_UINT16
   309  	lduh	[FP-160+6], %i0
   310  	return	%i7+8
   311  	 nop
   312  E SPARC_RET_SINT16
   313  	ldsh	[FP-160+6], %i0
   314  	return	%i7+8
   315  	 nop
   316  E SPARC_RET_UINT32
   317  	lduw	[FP-160+4], %i0
   318  	return	%i7+8
   319  	 nop
   320  E SP_V9_RET_SINT32
   321  	ldsw	[FP-160+4], %i0
   322  	return	%i7+8
   323  	 nop
   324  E SPARC_RET_INT64
   325  	ldx	[FP-160], %i0
   326  	return	%i7+8
   327  	 nop
   328  E SPARC_RET_INT128
   329  	ldx	[FP-160], %i0
   330  	ldx	[FP-160+8], %i1
   331  	return	%i7+8
   332  	 nop
   333  E SPARC_RET_F_8
   334  	ld	[FP-160+7*4], %f7
   335  	nop
   336  	ld	[FP-160+6*4], %f6
   337  	nop
   338  E SPARC_RET_F_6
   339  	ld	[FP-160+5*4], %f5
   340  	nop
   341  	ld	[FP-160+4*4], %f4
   342  	nop
   343  E SPARC_RET_F_4
   344  	ldd	[FP-160], %f0
   345  	ldd	[FP-160+8], %f2
   346  	return	%i7+8
   347  	 nop
   348  E SPARC_RET_F_2
   349  	ldd	[FP-160], %f0
   350  	return	%i7+8
   351  	 nop
   352  E SP_V9_RET_F_3
   353  	ld	[FP-160+2*4], %f2
   354  	nop
   355  	ld	[FP-160+1*4], %f1
   356  	nop
   357  E SPARC_RET_F_1
   358  	ld	[FP-160], %f0
   359  	return	%i7+8
   360  	 nop
   361  
   362  	! Finish the SPARC_RET_STRUCT sequence.
   363  	.align	8
   364  8:	ldd	[FP-152], %f2
   365  	ldx	[FP-144], %i2
   366  	ldd	[FP-144], %f4
   367  	ldx	[FP-136], %i3
   368  	ldd	[FP-136], %f6
   369  	return	%i7+8
   370  	 nop
   371  
   372  	cfi_endproc
   373  	.size	C(ffi_closure_v9), . - C(ffi_closure_v9)
   374  #endif /* SPARC64 */
   375  #ifdef __linux__
   376  	.section	.note.GNU-stack,"",@progbits
   377  #endif