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

     1  /* Low-level libffi support for Altera Nios II.
     2  
     3     Copyright (c) 2013 Mentor Graphics.
     4  
     5     Permission is hereby granted, free of charge, to any person obtaining
     6     a copy of this software and associated documentation files (the
     7     ``Software''), to deal in the Software without restriction, including
     8     without limitation the rights to use, copy, modify, merge, publish,
     9     distribute, sublicense, and/or sell copies of the Software, and to
    10     permit persons to whom the Software is furnished to do so, subject to
    11     the following conditions:
    12     
    13     The above copyright notice and this permission notice shall be
    14     included in all copies or substantial portions of the Software.
    15     
    16     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    17     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    18     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    19     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    20     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    21     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    22     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
    23  
    24  /* This function is declared on the C side as 
    25  
    26     extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *),
    27  	  		        extended_cif *ecif,
    28  				unsigned nbytes, 
    29  				void (*fn) (void));
    30  	
    31     On input, the arguments appear as
    32  	r4 = arghook
    33  	r5 = ecif
    34  	r6 = nbytes
    35  	r7 = fn
    36  */
    37  
    38  	.section	.text
    39  	.align	2
    40  	.global	ffi_call_sysv
    41  	.type	ffi_call_sysv, @function
    42  
    43  ffi_call_sysv:
    44  	.cfi_startproc
    45  
    46  	/* Create the stack frame, saving r16 so we can use it locally.  */
    47  	addi	sp, sp, -12
    48  	.cfi_def_cfa_offset 12
    49  	stw	ra, 8(sp)
    50  	stw	fp, 4(sp)
    51  	stw	r16, 0(sp)
    52  	.cfi_offset 31, -4
    53  	.cfi_offset 28, -8
    54  	.cfi_offset 16, -12
    55  	mov	fp, sp
    56  	.cfi_def_cfa_register 28
    57  	mov	r16, r7
    58  
    59  	/* Adjust the stack pointer to create the argument buffer
    60  	   nbytes long.  */
    61  	sub	sp, sp, r6
    62  
    63  	/* Call the arghook function.  */
    64  	mov	r2, r4		/* fn */
    65  	mov	r4, sp		/* argbuffer */
    66  	callr	r2		/* r5 already contains ecif */
    67  
    68  	/* Pop off the first 16 bytes of the argument buffer on the stack,
    69  	   transferring the contents to the argument registers.  */
    70  	ldw	r4, 0(sp)
    71  	ldw	r5, 4(sp)
    72  	ldw	r6, 8(sp)
    73  	ldw	r7, 12(sp)
    74  	addi	sp, sp, 16
    75  
    76  	/* Call the user function, which leaves its result in r2 and r3.  */
    77  	callr	r16
    78  
    79  	/* Pop off the stack frame.  */
    80  	mov	sp, fp
    81  	ldw	ra, 8(sp)
    82  	ldw	fp, 4(sp)
    83  	ldw	r16, 0(sp)
    84  	addi	sp, sp, 12
    85  	ret
    86  	.cfi_endproc
    87  	.size	ffi_call_sysv, .-ffi_call_sysv
    88  
    89  
    90  /* Closure trampolines jump here after putting the C helper address
    91     in r9 and the closure pointer in r10.  The user-supplied arguments
    92     to the closure are in the normal places, in r4-r7 and on the
    93     stack.  Push the register arguments on the stack too and then call the
    94     C helper function to deal with them.  */
    95     
    96  	.section	.text
    97  	.align	2
    98  	.global	ffi_closure_sysv
    99  	.type	ffi_closure_sysv, @function
   100  
   101  ffi_closure_sysv:
   102  	.cfi_startproc
   103  
   104  	/* Create the stack frame, pushing the register args on the stack
   105  	   just below the stack args.  This is the same trick illustrated
   106  	   in Figure 7-3 in the Nios II Processor Reference Handbook, used
   107  	   for variable arguments and structures passed by value.  */
   108  	addi	sp, sp, -20
   109  	.cfi_def_cfa_offset 20
   110  	stw	ra, 0(sp)
   111  	.cfi_offset 31, -20
   112  	stw	r4, 4(sp)
   113  	.cfi_offset 4, -16
   114  	stw	r5, 8(sp)
   115  	.cfi_offset 5, -12
   116  	stw	r6, 12(sp)
   117  	.cfi_offset 6, -8
   118  	stw	r7, 16(sp)
   119  	.cfi_offset 7, -4
   120  
   121  	/* Call the helper.
   122  	   r4 = pointer to arguments on stack
   123  	   r5 = closure pointer (loaded in r10 by the trampoline)
   124  	   r9 = address of helper function (loaded by trampoline) */
   125  	addi	r4, sp, 4
   126  	mov	r5, r10
   127  	callr	r9
   128  	
   129  	/* Pop the stack and return.  */
   130  	ldw	ra, 0(sp)
   131  	addi	sp, sp, 20
   132  	.cfi_def_cfa_offset -20
   133  	ret
   134  	.cfi_endproc
   135  	.size	ffi_closure_sysv, .-ffi_closure_sysv
   136