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

     1  /*
     2   * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>
     3   *
     4   * Permission is hereby granted, free of charge, to any person obtaining
     5   * a copy of this software and associated documentation files (the
     6   * ``Software''), to deal in the Software without restriction, including
     7   * without limitation the rights to use, copy, modify, merge, publish,
     8   * distribute, sublicense, and/or sell copies of the Software, and to
     9   * permit persons to whom the Software is furnished to do so, subject to
    10   * the following conditions:
    11   * 
    12   * The above copyright notice and this permission notice shall be included
    13   * in all copies or substantial portions of the Software.
    14   * 
    15   * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    16   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    17   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    18   * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    19   * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    20   * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    21   * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    22   */
    23  
    24  /*
    25   * vax Foreign Function Interface
    26   */
    27  
    28  #define LIBFFI_ASM	
    29  #include <fficonfig.h>
    30  #include <ffi.h>
    31  
    32  	.text
    33  
    34  /*
    35   * void *					%r0
    36   * ffi_call_elfbsd(extended_cif *ecif,		4(%ap)
    37   *		   unsigned bytes,		8(%ap)
    38   *		   unsigned flags,		12(%ap)
    39   *		   void *rvalue,		16(%ap)
    40   *		   void (*fn)());		20(%ap)
    41   */
    42  	.globl	ffi_call_elfbsd
    43  	.type	ffi_call_elfbsd,@function
    44  	.align	2
    45  ffi_call_elfbsd:
    46  	.word	0x00c		# save R2 and R3
    47  
    48  	# Allocate stack space for the args
    49  	subl2	8(%ap), %sp
    50  
    51  	# Call ffi_prep_args
    52  	pushl	%sp
    53  	pushl	4(%ap)
    54  	calls	$2, ffi_prep_args
    55  
    56  	# Get function pointer
    57  	movl	20(%ap), %r1
    58  
    59  	# Build a CALLS frame
    60  	ashl	$-2, 8(%ap), %r0
    61  	pushl	%r0		# argument stack usage
    62  	movl	%sp, %r0	# future %ap
    63  	# saved registers
    64  	bbc	$11, 0(%r1), 1f
    65  	pushl	%r11
    66  1:	bbc	$10, 0(%r1), 1f
    67  	pushl	%r10
    68  1:	bbc	$9, 0(%r1), 1f
    69  	pushl	%r9
    70  1:	bbc	$8, 0(%r1), 1f
    71  	pushl	%r8
    72  1:	bbc	$7, 0(%r1), 1f
    73  	pushl	%r7
    74  1:	bbc	$6, 0(%r1), 1f
    75  	pushl	%r6
    76  1:	bbc	$5, 0(%r1), 1f
    77  	pushl	%r5
    78  1:	bbc	$4, 0(%r1), 1f
    79  	pushl	%r4
    80  1:	bbc	$3, 0(%r1), 1f
    81  	pushl	%r3
    82  1:	bbc	$2, 0(%r1), 1f
    83  	pushl	%r2
    84  1:	
    85  	pushal	9f
    86  	pushl	%fp
    87  	pushl	%ap
    88  	movl	16(%ap), %r3	# struct return address, if needed
    89  	movl	%r0, %ap
    90  	movzwl	4(%fp), %r0	# previous PSW, without the saved registers mask
    91  	bisl2	$0x20000000, %r0 # calls frame
    92  	movzwl	0(%r1), %r2
    93  	bicw2	$0xf003, %r2	# only keep R11-R2
    94  	ashl	$16, %r2, %r2
    95  	bisl2	%r2, %r0	# saved register mask of the called function
    96  	pushl	%r0	
    97  	pushl	$0
    98  	movl	%sp, %fp
    99  
   100  	# Invoke the function
   101  	pushal	2(%r1)		# skip procedure entry mask
   102  	movl	%r3, %r1
   103  	bicpsw	$0x000f
   104  	rsb
   105  
   106  9:
   107  	# Copy return value if necessary
   108  	tstl	16(%ap)
   109  	jeql	9f
   110  	movl	16(%ap), %r2
   111  
   112  	bbc	$0, 12(%ap), 1f	# CIF_FLAGS_CHAR
   113  	movb	%r0, 0(%r2)
   114  	brb	9f
   115  1:
   116  	bbc	$1, 12(%ap), 1f	# CIF_FLAGS_SHORT
   117  	movw	%r0, 0(%r2)
   118  	brb	9f
   119  1:
   120  	bbc	$2, 12(%ap), 1f	# CIF_FLAGS_INT
   121  	movl	%r0, 0(%r2)
   122  	brb	9f
   123  1:
   124  	bbc	$3, 12(%ap), 1f	# CIF_FLAGS_DINT
   125  	movq	%r0, 0(%r2)
   126  	brb	9f
   127  1:
   128  	movl	%r1, %r0	# might have been a struct
   129  	#brb	9f
   130  
   131  9:
   132  	ret
   133  
   134  /*
   135   * ffi_closure_elfbsd(void);
   136   * invoked with	%r0: ffi_closure *closure
   137   */
   138  	.globl	ffi_closure_elfbsd
   139  	.type	ffi_closure_elfbsd, @function
   140  	.align	2
   141  ffi_closure_elfbsd:
   142  	.word	0
   143  
   144  	# Allocate room on stack for return value
   145  	subl2	$8, %sp
   146  
   147  	# Invoke the closure function
   148  	pushal	4(%ap)		# calling stack
   149  	pushal	4(%sp)		# return value
   150  	pushl	%r0		# closure
   151  	calls	$3, ffi_closure_elfbsd_inner
   152  
   153  	# Copy return value if necessary
   154  	bitb	$1, %r0		# CIF_FLAGS_CHAR
   155  	beql	1f
   156  	movb	0(%sp), %r0
   157  	brb	9f
   158  1:
   159  	bitb	$2, %r0		# CIF_FLAGS_SHORT
   160  	beql	1f
   161  	movw	0(%sp), %r0
   162  	brb	9f
   163  1:
   164  	bitb	$4, %r0		# CIF_FLAGS_INT
   165  	beql	1f
   166  	movl	0(%sp), %r0
   167  	brb	9f
   168  1:
   169  	bitb	$8, %r0		# CIF_FLAGS_DINT
   170  	beql	1f
   171  	movq	0(%sp), %r0
   172  	#brb	9f
   173  1:
   174  
   175  9:
   176  	ret
   177  
   178  /*
   179   * ffi_closure_struct_elfbsd(void);
   180   * invoked with	%r0: ffi_closure *closure
   181   *		%r1: struct return address
   182   */
   183  	.globl	ffi_closure_struct_elfbsd
   184  	.type	ffi_closure_struct_elfbsd, @function
   185  	.align	2
   186  ffi_closure_struct_elfbsd:
   187  	.word	0
   188  
   189  	# Invoke the closure function
   190  	pushal	4(%ap)		# calling stack
   191  	pushl	%r1		# return value
   192  	pushl	%r0		# closure
   193  	calls	$3, ffi_closure_elfbsd_inner
   194  
   195  	ret