github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/m88k/obsd.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   * m88k Foreign Function Interface
    26   */
    27  
    28  #define LIBFFI_ASM	
    29  #include <fficonfig.h>
    30  #include <ffi.h>
    31  
    32  	.text
    33  
    34  /*
    35   * ffi_cacheflush_OBSD(unsigned int addr,	%r2
    36   *		       unsigned int size);	%r3
    37   */
    38  	.align	4
    39  	.globl	ffi_cacheflush_OBSD
    40  	.type	ffi_cacheflush_OBSD,@function
    41  ffi_cacheflush_OBSD:
    42  	tb0	0,   %r0, 451
    43  	or	%r0, %r0, %r0
    44  	jmp	%r1
    45  	.size	ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD
    46  
    47  /*
    48   * ffi_call_OBSD(unsigned bytes,		%r2
    49   *		 extended_cif *ecif,		%r3
    50   *		 unsigned flags,		%r4
    51   *		 void *rvalue,			%r5
    52   *		 void (*fn)());			%r6
    53   */
    54  	.align	4
    55  	.globl	ffi_call_OBSD
    56  	.type	ffi_call_OBSD,@function
    57  ffi_call_OBSD:
    58  	subu	%r31, %r31, 32
    59  	st	%r30, %r31, 4
    60  	st	%r1,  %r31, 0
    61  	addu	%r30, %r31, 32
    62  
    63  	| Save the few arguments we'll need after ffi_prep_args()
    64  	st.d	%r4, %r31, 8
    65  	st	%r6, %r31, 16
    66  
    67  	| Allocate room for the image of r2-r9, and the stack space for
    68  	| the args (rounded to a 16-byte boundary)
    69  	addu	%r2,  %r2,  (8 * 4) + 15
    70  	clr	%r2,  %r2,  4<0>
    71  	subu	%r31, %r31, %r2
    72  
    73  	| Fill register and stack image
    74  	or	%r2, %r31, %r0
    75  #ifdef PIC
    76  	bsr	ffi_prep_args#plt
    77  #else
    78  	bsr	ffi_prep_args
    79  #endif
    80  
    81  	| Save pointer to return struct address, if any
    82  	or	%r12, %r2, %r0
    83  
    84  	| Get function pointer
    85  	subu	%r4,  %r30, 32
    86  	ld	%r1,  %r4,  16
    87  
    88  	| Fetch the register arguments
    89  	ld.d	%r2, %r31, (0 * 4)
    90  	ld.d	%r4, %r31, (2 * 4)
    91  	ld.d	%r6, %r31, (4 * 4)
    92  	ld.d	%r8, %r31, (6 * 4)
    93  	addu	%r31, %r31, (8 * 4)
    94  
    95  	| Invoke the function
    96  	jsr	%r1
    97  
    98  	| Restore stack now that we don't need the args anymore
    99  	subu	%r31, %r30, 32
   100  
   101  	| Figure out what to return as the function's return value
   102  	ld	%r5, %r31, 12		| rvalue
   103  	ld	%r4, %r31, 8		| flags
   104  
   105  	bcnd	eq0, %r5, 9f
   106  
   107  	bb0	0, %r4, 1f		| CIF_FLAGS_INT
   108  	st	%r2, %r5, 0
   109  	br	9f
   110  
   111  1:
   112  	bb0	1, %r4, 1f		| CIF_FLAGS_DINT
   113  	st.d	%r2, %r5, 0
   114  	br	9f
   115  
   116  1:
   117  9:
   118  	ld	%r1,  %r31, 0
   119  	ld	%r30, %r31, 4
   120  	jmp.n	%r1
   121  	 addu	%r31, %r31, 32
   122  	.size	ffi_call_OBSD, . - ffi_call_OBSD
   123  
   124  /*
   125   * ffi_closure_OBSD(ffi_closure *closure);	%r13
   126   */
   127  	.align	4
   128  	.globl	ffi_closure_OBSD
   129  	.type	ffi_closure_OBSD, @function
   130  ffi_closure_OBSD:
   131  	subu	%r31, %r31, 16
   132  	st	%r30, %r31, 4
   133  	st	%r1,  %r31, 0
   134  	addu	%r30, %r31, 16
   135  
   136  	| Make room on the stack for saved register arguments and return
   137  	| value
   138  	subu	%r31, %r31, (8 * 4) + (2 * 4)
   139  	st.d	%r2,  %r31, (0 * 4)
   140  	st.d	%r4,  %r31, (2 * 4)
   141  	st.d	%r6,  %r31, (4 * 4)
   142  	st.d	%r8,  %r31, (6 * 4)
   143  
   144  	| Invoke the closure function
   145  	or	%r5,  %r30, 0			| calling stack
   146  	addu	%r4,  %r31, 0			| saved registers
   147  	addu	%r3,  %r31, (8 * 4)		| return value
   148  	or	%r2,  %r13, %r0			| closure
   149  #ifdef PIC
   150  	bsr	ffi_closure_OBSD_inner#plt
   151  #else
   152  	bsr	ffi_closure_OBSD_inner
   153  #endif
   154  
   155  	| Figure out what to return as the function's return value
   156  	bb0	0, %r2, 1f		| CIF_FLAGS_INT
   157  	ld	%r2, %r31, (8 * 4)
   158  	br	9f
   159  
   160  1:
   161  	bb0	1, %r2, 1f		| CIF_FLAGS_DINT
   162  	ld.d	%r2, %r31, (8 * 4)
   163  	br	9f
   164  
   165  1:
   166  9:
   167  	subu	%r31, %r30, 16
   168  	ld	%r1,  %r31, 0
   169  	ld	%r30, %r31, 4
   170  	jmp.n	%r1
   171  	 addu	%r31, %r31, 16
   172  	.size	ffi_closure_OBSD,.-ffi_closure_OBSD
   173  
   174  /*
   175   * ffi_closure_struct_OBSD(ffi_closure *closure);	%r13
   176   */
   177  	.align	4
   178  	.globl	ffi_closure_struct_OBSD
   179  	.type	ffi_closure_struct_OBSD, @function
   180  ffi_closure_struct_OBSD:
   181  	subu	%r31, %r31, 16
   182  	st	%r30, %r31, 4
   183  	st	%r1,  %r31, 0
   184  	addu	%r30, %r31, 16
   185  
   186  	| Make room on the stack for saved register arguments
   187  	subu	%r31, %r31, (8 * 4)
   188  	st.d	%r2,  %r31, (0 * 4)
   189  	st.d	%r4,  %r31, (2 * 4)
   190  	st.d	%r6,  %r31, (4 * 4)
   191  	st.d	%r8,  %r31, (6 * 4)
   192  
   193  	| Invoke the closure function
   194  	or	%r5,  %r30, 0			| calling stack
   195  	addu	%r4,  %r31, 0			| saved registers
   196  	or	%r3,  %r12, 0			| return value
   197  	or	%r2,  %r13, %r0			| closure
   198  #ifdef PIC
   199  	bsr	ffi_closure_OBSD_inner#plt
   200  #else
   201  	bsr	ffi_closure_OBSD_inner
   202  #endif
   203  
   204  	subu	%r31, %r30, 16
   205  	ld	%r1,  %r31, 0
   206  	ld	%r30, %r31, 4
   207  	jmp.n	%r1
   208  	 addu	%r31, %r31, 16
   209  	.size	ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD