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

     1  /* -----------------------------------------------------------------------
     2     v8.S - Copyright (c) 2013  The Written Word, Inc.
     3  	  Copyright (c) 1996, 1997, 2003, 2004, 2008  Red Hat, Inc.
     4  
     5     SPARC 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  #include <ffi_cfi.h>
    32  #include "internal.h"
    33  
    34  #ifndef SPARC64
    35  
    36  #define C2(X, Y)  X ## Y
    37  #define C1(X, Y)  C2(X, Y)
    38  
    39  #ifdef __USER_LABEL_PREFIX__
    40  # define C(Y)	C1(__USER_LABEL_PREFIX__, Y)
    41  #else
    42  # define C(Y)	Y
    43  #endif
    44  #define L(Y)	C1(.L, Y)
    45  
    46  	.text
    47  
    48  #ifndef __GNUC__
    49          .align 8
    50  	.globl	C(ffi_flush_icache)
    51  	.type	C(ffi_flush_icache),@function
    52  	FFI_HIDDEN(C(ffi_flush_icache))
    53  
    54  C(ffi_flush_icache):
    55  	cfi_startproc
    56  1:	iflush %o0
    57  	iflush %o+8
    58  	nop
    59  	nop
    60  	nop
    61  	nop
    62  	nop
    63  	retl
    64  	 nop
    65  	cfi_endproc
    66  	.size	C(ffi_flush_icache), . - C(ffi_flush_icache)
    67  #endif
    68  
    69  .macro E index
    70  	.align	16
    71  	.org	2b + \index * 16
    72  .endm
    73  
    74          .align 8
    75  	.globl	C(ffi_call_v8)
    76  	.type	C(ffi_call_v8),@function
    77  	FFI_HIDDEN(C(ffi_call_v8))
    78  
    79  C(ffi_call_v8):
    80  	cfi_startproc
    81  	! Allocate a stack frame sized by ffi_call.
    82  	save	%sp, %o4, %sp
    83  	cfi_def_cfa_register(%fp)
    84  	cfi_window_save
    85  
    86  	mov	%i0, %o0		! copy cif
    87  	add	%sp, 64+32, %o1		! load args area
    88  	mov	%i2, %o2		! copy rvalue
    89  	call	C(ffi_prep_args_v8)
    90  	 mov	%i3, %o3		! copy avalue
    91  
    92  	add	%sp, 32, %sp		! deallocate prep frame
    93  	and	%o0, SPARC_FLAG_RET_MASK, %l0	! save return type
    94  	srl	%o0, SPARC_SIZEMASK_SHIFT, %l1	! save return size
    95  	ld	[%sp+64+4], %o0		! load all argument registers
    96  	ld	[%sp+64+8], %o1
    97  	ld	[%sp+64+12], %o2
    98  	ld	[%sp+64+16], %o3
    99  	cmp	%l0, SPARC_RET_STRUCT	! struct return needs an unimp 4
   100  	ld	[%sp+64+20], %o4
   101  	be	8f
   102  	 ld	[%sp+64+24], %o5
   103  
   104  	! Call foreign function
   105  	call	%i1
   106  	 mov	%i5, %g2		! load static chain
   107  
   108  0:	call	1f		! load pc in %o7
   109  	 sll	%l0, 4, %l0
   110  1:	add	%o7, %l0, %o7	! o7 = 0b + ret_type*16
   111  	jmp	%o7+(2f-0b)
   112  	 nop
   113  
   114  	! Note that each entry is 4 insns, enforced by the E macro.
   115  	.align	16
   116  2:
   117  E SPARC_RET_VOID
   118  	ret
   119  	 restore
   120  E SPARC_RET_STRUCT
   121  	unimp
   122  E SPARC_RET_UINT8
   123  	and	%o0, 0xff, %o0
   124  	st	%o0, [%i2]
   125  	ret
   126  	 restore
   127  E SPARC_RET_SINT8
   128  	sll	%o0, 24, %o0
   129  	b	7f
   130  	 sra	%o0, 24, %o0
   131  E SPARC_RET_UINT16
   132  	sll	%o0, 16, %o0
   133  	b	7f
   134  	 srl	%o0, 16, %o0
   135  E SPARC_RET_SINT16
   136  	sll	%o0, 16, %o0
   137  	b	7f
   138  	 sra	%o0, 16, %o0
   139  E SPARC_RET_UINT32
   140  7:	st	%o0, [%i2]
   141  	ret
   142  	 restore
   143  E SP_V8_RET_CPLX16
   144  	sth	%o0, [%i2+2]
   145  	b	9f
   146  	 srl	%o0, 16, %o0
   147  E SPARC_RET_INT64
   148  	st	%o0, [%i2]
   149  	st	%o1, [%i2+4]
   150  	ret
   151  	 restore
   152  E SPARC_RET_INT128
   153  	std	%o0, [%i2]
   154  	std	%o2, [%i2+8]
   155  	ret
   156  	 restore
   157  E SPARC_RET_F_8
   158  	st	%f7, [%i2+7*4]
   159  	nop
   160  	st	%f6, [%i2+6*4]
   161  	nop
   162  E SPARC_RET_F_6
   163  	st	%f5, [%i2+5*4]
   164  	nop
   165  	st	%f4, [%i2+4*4]
   166  	nop
   167  E SPARC_RET_F_4
   168  	st	%f3, [%i2+3*4]
   169  	nop
   170  	st	%f2, [%i2+2*4]
   171  	nop
   172  E SPARC_RET_F_2
   173  	st	%f1, [%i2+4]
   174  	st	%f0, [%i2]
   175  	ret
   176  	 restore
   177  E SP_V8_RET_CPLX8
   178  	stb	%o0, [%i2+1]
   179  	b	10f
   180  	 srl	%o0, 8, %o0
   181  E SPARC_RET_F_1
   182  	st	%f0, [%i2]
   183  	ret
   184  	 restore
   185  
   186  	.align	8
   187  9:	sth	%o0, [%i2]
   188  	ret
   189  	 restore
   190  	.align	8
   191  10:	stb	%o0, [%i2]
   192  	ret
   193  	 restore
   194  
   195  	! Struct returning functions expect and skip the unimp here.
   196  	! To make it worse, conforming callees examine the unimp and
   197  	! make sure the low 12 bits of the unimp match the size of
   198  	! the struct being returned.
   199  	.align	8
   200  8:	call	1f				! load pc in %o7
   201  	 sll	%l1, 2, %l0			! size * 4
   202  1:	sll	%l1, 4, %l1			! size * 16
   203  	add	%l0, %l1, %l0			! size * 20
   204  	add	%o7, %l0, %o7			! o7 = 0b + size*20
   205  	jmp	%o7+(2f-8b)
   206  	 mov	%i5, %g2			! load static chain
   207  2:
   208  .rept	0x1000
   209  	call	%i1
   210  	 nop
   211  	unimp	(. - 2b) / 20
   212  	ret
   213  	 restore
   214  .endr
   215  
   216  	cfi_endproc
   217  	.size	C(ffi_call_v8),. - C(ffi_call_v8)
   218  
   219  
   220  /* 16*4 register window + 1*4 struct return + 6*4 args backing store
   221     + 8*4 return storage + 1*4 alignment.  */
   222  #define	STACKFRAME	(16*4 + 4 + 6*4 + 8*4 + 4)
   223  
   224  /* ffi_closure_v8(...)
   225  
   226     Receives the closure argument in %g2.   */
   227  
   228  #ifdef HAVE_AS_REGISTER_PSEUDO_OP
   229  	.register	%g2, #scratch
   230  #endif
   231  
   232  	.align 8
   233  	.globl	C(ffi_go_closure_v8)
   234  	.type	C(ffi_go_closure_v8),@function
   235  	FFI_HIDDEN(C(ffi_go_closure_v8))
   236  
   237  C(ffi_go_closure_v8):
   238  	cfi_startproc
   239  	save	%sp, -STACKFRAME, %sp
   240  	cfi_def_cfa_register(%fp)
   241  	cfi_window_save
   242  
   243  	ld	[%g2+4], %o0			! load cif
   244  	ld	[%g2+8], %o1			! load fun
   245  	b	0f
   246  	 mov	%g2, %o2			! load user_data
   247  	cfi_endproc
   248  	.size	C(ffi_go_closure_v8), . - C(ffi_go_closure_v8)
   249  
   250  	.align 8
   251  	.globl	C(ffi_closure_v8)
   252  	.type	C(ffi_closure_v8),@function
   253  	FFI_HIDDEN(C(ffi_closure_v8))
   254  
   255  C(ffi_closure_v8):
   256  	cfi_startproc
   257  	save	%sp, -STACKFRAME, %sp
   258  	cfi_def_cfa_register(%fp)
   259  	cfi_window_save
   260  
   261  	ld	[%g2+FFI_TRAMPOLINE_SIZE], %o0		! load cif
   262  	ld	[%g2+FFI_TRAMPOLINE_SIZE+4], %o1	! load fun
   263  	ld	[%g2+FFI_TRAMPOLINE_SIZE+8], %o2	! load user_data
   264  0:
   265  	! Store all of the potential argument registers in va_list format.
   266  	st	%i0, [%fp+68+0]
   267  	st	%i1, [%fp+68+4]
   268  	st	%i2, [%fp+68+8]
   269  	st	%i3, [%fp+68+12]
   270  	st	%i4, [%fp+68+16]
   271  	st	%i5, [%fp+68+20]
   272  
   273  	! Call ffi_closure_sparc_inner to do the bulk of the work.
   274  	add	%fp, -8*4, %o3
   275  	call	ffi_closure_sparc_inner_v8
   276  	 add	%fp,  64, %o4
   277  
   278  0:	call	1f
   279  	 and	%o0, SPARC_FLAG_RET_MASK, %o0
   280  1:	sll	%o0, 4, %o0	! o0 = o0 * 16
   281  	add	%o7, %o0, %o7	! o7 = 0b + o0*16
   282  	jmp	%o7+(2f-0b)
   283  	 add	%fp, -8*4, %i2
   284  	 
   285  	! Note that each entry is 4 insns, enforced by the E macro.
   286  	.align	16
   287  2:
   288  E SPARC_RET_VOID
   289  	ret
   290  	 restore
   291  E SPARC_RET_STRUCT
   292  	ld	[%i2], %i0
   293  	jmp	%i7+12
   294  	 restore
   295  E SPARC_RET_UINT8
   296  	ldub	[%i2+3], %i0
   297  	ret
   298  	 restore
   299  E SPARC_RET_SINT8
   300  	ldsb	[%i2+3], %i0
   301  	ret
   302  	 restore
   303  E SPARC_RET_UINT16
   304  	lduh	[%i2+2], %i0
   305  	ret
   306  	 restore
   307  E SPARC_RET_SINT16
   308  	ldsh	[%i2+2], %i0
   309  	ret
   310  	 restore
   311  E SPARC_RET_UINT32
   312  	ld	[%i2], %i0
   313  	ret
   314  	 restore
   315  E SP_V8_RET_CPLX16
   316  	ld	[%i2], %i0
   317  	ret
   318  	 restore
   319  E SPARC_RET_INT64
   320  	ldd	[%i2], %i0
   321  	ret
   322  	 restore
   323  E SPARC_RET_INT128
   324  	ldd	[%i2], %i0
   325  	ldd	[%i2+8], %i2
   326  	ret
   327  	 restore
   328  E SPARC_RET_F_8
   329  	ld	[%i2+7*4], %f7
   330  	nop
   331  	ld	[%i2+6*4], %f6
   332  	nop
   333  E SPARC_RET_F_6
   334  	ld	[%i2+5*4], %f5
   335  	nop
   336  	ld	[%i2+4*4], %f4
   337  	nop
   338  E SPARC_RET_F_4
   339  	ld	[%i2+3*4], %f3
   340  	nop
   341  	ld	[%i2+2*4], %f2
   342  	nop
   343  E SPARC_RET_F_2
   344  	ldd	[%i2], %f0
   345  	ret
   346  	 restore
   347  E SP_V8_RET_CPLX8
   348  	lduh	[%i2], %i0
   349  	ret
   350  	 restore
   351  E SPARC_RET_F_1
   352  	ld	[%i2], %f0
   353  	ret
   354  	 restore
   355  
   356  	cfi_endproc
   357  	.size	C(ffi_closure_v8), . - C(ffi_closure_v8)
   358  #endif /* !SPARC64 */
   359  #if defined __ELF__ && defined __linux__
   360  	.section	.note.GNU-stack,"",@progbits
   361  #endif