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

     1  /* -----------------------------------------------------------------------
     2  	
     3     sysv.S - Copyright (c) 2012 Alan Hourihane
     4  	    Copyright (c) 1998, 2012 Andreas Schwab
     5  	    Copyright (c) 2008 Red Hat, Inc.
     6  	    Copyright (c) 2012 Thorsten Glaser
     7  
     8     m68k Foreign Function Interface
     9  
    10     Permission is hereby granted, free of charge, to any person obtaining
    11     a copy of this software and associated documentation files (the
    12     ``Software''), to deal in the Software without restriction, including
    13     without limitation the rights to use, copy, modify, merge, publish,
    14     distribute, sublicense, and/or sell copies of the Software, and to
    15     permit persons to whom the Software is furnished to do so, subject to
    16     the following conditions:
    17  
    18     The above copyright notice and this permission notice shall be included
    19     in all copies or substantial portions of the Software.
    20  
    21     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    22     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    23     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    24     NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    25     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    26     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    27     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    28     DEALINGS IN THE SOFTWARE.
    29     ----------------------------------------------------------------------- */
    30  
    31  #define LIBFFI_ASM	
    32  #include <fficonfig.h>
    33  #include <ffi.h>
    34  
    35  #ifdef HAVE_AS_CFI_PSEUDO_OP
    36  #define CFI_STARTPROC()		.cfi_startproc
    37  #define CFI_OFFSET(reg,off)	.cfi_offset	reg,off
    38  #define CFI_DEF_CFA(reg,off)	.cfi_def_cfa	reg,off
    39  #define CFI_ENDPROC()		.cfi_endproc
    40  #else
    41  #define CFI_STARTPROC()
    42  #define CFI_OFFSET(reg,off)
    43  #define CFI_DEF_CFA(reg,off)
    44  #define CFI_ENDPROC()
    45  #endif
    46  
    47  #ifdef __MINT__
    48  #define CALLFUNC(funcname) _ ## funcname
    49  #else
    50  #define CALLFUNC(funcname) funcname
    51  #endif
    52  
    53  	.text
    54  
    55  	.globl	CALLFUNC(ffi_call_SYSV)
    56  	.type	CALLFUNC(ffi_call_SYSV),@function
    57  	.align	4
    58  
    59  CALLFUNC(ffi_call_SYSV):
    60  	CFI_STARTPROC()
    61  	link	%fp,#0
    62  	CFI_OFFSET(14,-8)
    63  	CFI_DEF_CFA(14,8)
    64  	move.l	%d2,-(%sp)
    65  	CFI_OFFSET(2,-12)
    66  
    67  	| Make room for all of the new args.
    68  	sub.l	12(%fp),%sp
    69  
    70  	| Call ffi_prep_args
    71  	move.l	8(%fp),-(%sp)
    72  	pea	4(%sp)
    73  #if !defined __PIC__
    74  	jsr	CALLFUNC(ffi_prep_args)
    75  #else
    76  	bsr.l	CALLFUNC(ffi_prep_args@PLTPC)
    77  #endif
    78  	addq.l	#8,%sp	
    79  
    80  	| Pass pointer to struct value, if any
    81  #ifdef __MINT__
    82  	move.l	%d0,%a1
    83  #else
    84  	move.l	%a0,%a1
    85  #endif
    86  
    87  	| Call the function
    88  	move.l	24(%fp),%a0
    89  	jsr	(%a0)
    90  
    91  	| Remove the space we pushed for the args
    92  	add.l	12(%fp),%sp
    93  
    94  	| Load the pointer to storage for the return value
    95  	move.l	20(%fp),%a1
    96  
    97  	| Load the return type code 
    98  	move.l	16(%fp),%d2
    99  
   100  	| If the return value pointer is NULL, assume no return value.
   101  	| NOTE: On the mc68000, tst on an address register is not supported.
   102  #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
   103  	cmp.w	#0, %a1
   104  #else
   105  	tst.l	%a1
   106  #endif
   107  	jbeq	noretval
   108  
   109  	btst	#0,%d2
   110  	jbeq	retlongint
   111  	move.l	%d0,(%a1)
   112  	jbra	epilogue
   113  
   114  retlongint:
   115  	btst	#1,%d2
   116  	jbeq	retfloat
   117  	move.l	%d0,(%a1)
   118  	move.l	%d1,4(%a1)
   119  	jbra	epilogue
   120  
   121  retfloat:
   122  	btst	#2,%d2
   123  	jbeq	retdouble
   124  #if defined(__MC68881__) || defined(__HAVE_68881__)
   125  	fmove.s	%fp0,(%a1)
   126  #else
   127  	move.l	%d0,(%a1)
   128  #endif
   129  	jbra	epilogue
   130  
   131  retdouble:
   132  	btst	#3,%d2
   133  	jbeq	retlongdouble
   134  #if defined(__MC68881__) || defined(__HAVE_68881__)
   135  	fmove.d	%fp0,(%a1)
   136  #else
   137  	move.l	%d0,(%a1)+
   138  	move.l	%d1,(%a1)
   139  #endif
   140  	jbra	epilogue
   141  
   142  retlongdouble:
   143  	btst	#4,%d2
   144  	jbeq	retpointer
   145  #if defined(__MC68881__) || defined(__HAVE_68881__)
   146  	fmove.x	%fp0,(%a1)
   147  #else
   148  	move.l	%d0,(%a1)+
   149  	move.l	%d1,(%a1)+
   150  	move.l	%d2,(%a1)
   151  #endif
   152  	jbra	epilogue
   153  
   154  retpointer:
   155  	btst	#5,%d2
   156  	jbeq	retstruct1
   157  #ifdef __MINT__
   158  	move.l	%d0,(%a1)
   159  #else
   160  	move.l	%a0,(%a1)
   161  #endif
   162  	jbra	epilogue
   163  
   164  retstruct1:
   165  	btst	#6,%d2
   166  	jbeq	retstruct2
   167  	move.b	%d0,(%a1)
   168  	jbra	epilogue
   169  
   170  retstruct2:
   171  	btst	#7,%d2
   172  	jbeq	retsint8
   173  	move.w	%d0,(%a1)
   174  	jbra	epilogue
   175  
   176  retsint8:
   177  	btst	#8,%d2
   178  	jbeq	retsint16
   179  	| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.
   180  #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
   181  	ext.w	%d0
   182  	ext.l	%d0
   183  #else
   184  	extb.l	%d0
   185  #endif
   186  	move.l	%d0,(%a1)
   187  	jbra	epilogue
   188  
   189  retsint16:
   190  	btst	#9,%d2
   191  	jbeq	noretval
   192  	ext.l	%d0
   193  	move.l	%d0,(%a1)
   194  
   195  noretval:
   196  epilogue:
   197  	move.l	(%sp)+,%d2
   198  	unlk	%fp
   199  	rts
   200  	CFI_ENDPROC()
   201  	.size	CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)
   202  
   203  	.globl	CALLFUNC(ffi_closure_SYSV)
   204  	.type	CALLFUNC(ffi_closure_SYSV), @function
   205  	.align	4
   206  
   207  CALLFUNC(ffi_closure_SYSV):
   208  	CFI_STARTPROC()
   209  	link	%fp,#-12
   210  	CFI_OFFSET(14,-8)
   211  	CFI_DEF_CFA(14,8)
   212  	move.l	%sp,-12(%fp)
   213  	pea	8(%fp)
   214  	pea	-12(%fp)
   215  	move.l	%a0,-(%sp)
   216  #if !defined __PIC__
   217  	jsr	CALLFUNC(ffi_closure_SYSV_inner)
   218  #else
   219  	bsr.l	CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
   220  #endif
   221  
   222  	lsr.l	#1,%d0
   223  	jne	1f
   224  	jcc	.Lcls_epilogue
   225  	| CIF_FLAGS_INT
   226  	move.l	-12(%fp),%d0
   227  .Lcls_epilogue:
   228  	| no CIF_FLAGS_*
   229  	unlk	%fp
   230  	rts
   231  1:
   232  	lea	-12(%fp),%a0
   233  	lsr.l	#2,%d0
   234  	jne	1f
   235  	jcs	.Lcls_ret_float
   236  	| CIF_FLAGS_DINT
   237  	move.l	(%a0)+,%d0
   238  	move.l	(%a0),%d1
   239  	jra	.Lcls_epilogue
   240  .Lcls_ret_float:
   241  #if defined(__MC68881__) || defined(__HAVE_68881__)
   242  	fmove.s	(%a0),%fp0
   243  #else
   244  	move.l	(%a0),%d0
   245  #endif
   246  	jra	.Lcls_epilogue
   247  1:
   248  	lsr.l	#2,%d0
   249  	jne	1f
   250  	jcs	.Lcls_ret_ldouble
   251  	| CIF_FLAGS_DOUBLE
   252  #if defined(__MC68881__) || defined(__HAVE_68881__)
   253  	fmove.d	(%a0),%fp0
   254  #else
   255  	move.l	(%a0)+,%d0
   256  	move.l	(%a0),%d1
   257  #endif
   258  	jra	.Lcls_epilogue
   259  .Lcls_ret_ldouble:
   260  #if defined(__MC68881__) || defined(__HAVE_68881__)
   261  	fmove.x	(%a0),%fp0
   262  #else
   263  	move.l	(%a0)+,%d0
   264  	move.l	(%a0)+,%d1
   265  	move.l	(%a0),%d2
   266  #endif
   267  	jra	.Lcls_epilogue
   268  1:
   269  	lsr.l	#2,%d0
   270  	jne	1f
   271  	jcs	.Lcls_ret_struct1
   272  	| CIF_FLAGS_POINTER
   273  	move.l	(%a0),%a0
   274  	move.l	%a0,%d0
   275  	jra	.Lcls_epilogue
   276  .Lcls_ret_struct1:
   277  	move.b	(%a0),%d0
   278  	jra	.Lcls_epilogue
   279  1:
   280  	lsr.l	#2,%d0
   281  	jne	1f
   282  	jcs	.Lcls_ret_sint8
   283  	| CIF_FLAGS_STRUCT2
   284  	move.w	(%a0),%d0
   285  	jra	.Lcls_epilogue
   286  .Lcls_ret_sint8:
   287  	move.l	(%a0),%d0
   288  	| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.
   289  #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
   290  	ext.w	%d0
   291  	ext.l	%d0
   292  #else
   293  	extb.l	%d0
   294  #endif
   295  	jra	.Lcls_epilogue
   296  1:
   297  	| CIF_FLAGS_SINT16
   298  	move.l	(%a0),%d0
   299  	ext.l	%d0
   300  	jra	.Lcls_epilogue
   301  	CFI_ENDPROC()
   302  
   303  	.size	CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)
   304  
   305  	.globl	CALLFUNC(ffi_closure_struct_SYSV)
   306  	.type	CALLFUNC(ffi_closure_struct_SYSV), @function
   307  	.align	4
   308  
   309  CALLFUNC(ffi_closure_struct_SYSV):
   310  	CFI_STARTPROC()
   311  	link	%fp,#0
   312  	CFI_OFFSET(14,-8)
   313  	CFI_DEF_CFA(14,8)
   314  	move.l	%sp,-12(%fp)
   315  	pea	8(%fp)
   316  	move.l	%a1,-(%sp)
   317  	move.l	%a0,-(%sp)
   318  #if !defined __PIC__
   319  	jsr	CALLFUNC(ffi_closure_SYSV_inner)
   320  #else
   321  	bsr.l	CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
   322  #endif
   323  	unlk	%fp
   324  	rts
   325  	CFI_ENDPROC()
   326  	.size	CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)
   327  
   328  #if defined __ELF__ && defined __linux__
   329  	.section	.note.GNU-stack,"",@progbits
   330  #endif