Home | History | Annotate | Download | only in m88k
      1 /*
      2  * Copyright (c) 2013 Miodrag Vallat.  <miod (at) 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
    210