Home | History | Annotate | Download | only in m68k
      1 /* -----------------------------------------------------------------------
      2    sysv.S - Copyright (c) 1998 Andreas Schwab
      3 	    Copyright (c) 2008 Red Hat, Inc.
      4 
      5    m68k Foreign Function Interface
      6 
      7    Permission is hereby granted, free of charge, to any person obtaining
      8    a copy of this software and associated documentation files (the
      9    ``Software''), to deal in the Software without restriction, including
     10    without limitation the rights to use, copy, modify, merge, publish,
     11    distribute, sublicense, and/or sell copies of the Software, and to
     12    permit persons to whom the Software is furnished to do so, subject to
     13    the following conditions:
     14 
     15    The above copyright notice and this permission notice shall be included
     16    in all copies or substantial portions of the Software.
     17 
     18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
     19    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     21    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     22    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     23    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     24    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     25    DEALINGS IN THE SOFTWARE.
     26    ----------------------------------------------------------------------- */
     27 
     28 #define LIBFFI_ASM
     29 #include <fficonfig.h>
     30 #include <ffi.h>
     31 
     32 #ifdef HAVE_AS_CFI_PSEUDO_OP
     33 #define CFI_STARTPROC()		.cfi_startproc
     34 #define CFI_OFFSET(reg,off)	.cfi_offset	reg,off
     35 #define CFI_DEF_CFA(reg,off)	.cfi_def_cfa	reg,off
     36 #define CFI_ENDPROC()		.cfi_endproc
     37 #else
     38 #define CFI_STARTPROC()
     39 #define CFI_OFFSET(reg,off)
     40 #define CFI_DEF_CFA(reg,off)
     41 #define CFI_ENDPROC()
     42 #endif
     43 
     44 	.text
     45 
     46 	.globl	ffi_call_SYSV
     47 	.type	ffi_call_SYSV,@function
     48 	.align	4
     49 
     50 ffi_call_SYSV:
     51 	CFI_STARTPROC()
     52 	link	%fp,#0
     53 	CFI_OFFSET(14,-8)
     54 	CFI_DEF_CFA(14,8)
     55 	move.l	%d2,-(%sp)
     56 	CFI_OFFSET(2,-12)
     57 
     58 	| Make room for all of the new args.
     59 	sub.l	12(%fp),%sp
     60 
     61 	| Call ffi_prep_args
     62 	move.l	8(%fp),-(%sp)
     63 	pea	4(%sp)
     64 #if !defined __PIC__
     65 	jsr	ffi_prep_args
     66 #else
     67 	bsr.l	ffi_prep_args@PLTPC
     68 #endif
     69 	addq.l	#8,%sp
     70 
     71 	| Pass pointer to struct value, if any
     72 	move.l	%a0,%a1
     73 
     74 	| Call the function
     75 	move.l	24(%fp),%a0
     76 	jsr	(%a0)
     77 
     78 	| Remove the space we pushed for the args
     79 	add.l	12(%fp),%sp
     80 
     81 	| Load the pointer to storage for the return value
     82 	move.l	20(%fp),%a1
     83 
     84 	| Load the return type code
     85 	move.l	16(%fp),%d2
     86 
     87 	| If the return value pointer is NULL, assume no return value.
     88 	tst.l	%a1
     89 	jbeq	noretval
     90 
     91 	btst	#0,%d2
     92 	jbeq	retlongint
     93 	move.l	%d0,(%a1)
     94 	jbra	epilogue
     95 
     96 retlongint:
     97 	btst	#1,%d2
     98 	jbeq	retfloat
     99 	move.l	%d0,(%a1)
    100 	move.l	%d1,4(%a1)
    101 	jbra	epilogue
    102 
    103 retfloat:
    104 	btst	#2,%d2
    105 	jbeq	retdouble
    106 	fmove.s	%fp0,(%a1)
    107 	jbra	epilogue
    108 
    109 retdouble:
    110 	btst	#3,%d2
    111 	jbeq	retlongdouble
    112 	fmove.d	%fp0,(%a1)
    113 	jbra	epilogue
    114 
    115 retlongdouble:
    116 	btst	#4,%d2
    117 	jbeq	retpointer
    118 	fmove.x	%fp0,(%a1)
    119 	jbra	epilogue
    120 
    121 retpointer:
    122 	btst	#5,%d2
    123 	jbeq	retstruct1
    124 	move.l	%a0,(%a1)
    125 	jbra	epilogue
    126 
    127 retstruct1:
    128 	btst	#6,%d2
    129 	jbeq	retstruct2
    130 	move.b	%d0,(%a1)
    131 	jbra	epilogue
    132 
    133 retstruct2:
    134 	btst	#7,%d2
    135 	jbeq	noretval
    136 	move.w	%d0,(%a1)
    137 
    138 noretval:
    139 epilogue:
    140 	move.l	(%sp)+,%d2
    141 	unlk	%fp
    142 	rts
    143 	CFI_ENDPROC()
    144 	.size	ffi_call_SYSV,.-ffi_call_SYSV
    145 
    146 	.globl	ffi_closure_SYSV
    147 	.type	ffi_closure_SYSV, @function
    148 	.align	4
    149 
    150 ffi_closure_SYSV:
    151 	CFI_STARTPROC()
    152 	link	%fp,#-12
    153 	CFI_OFFSET(14,-8)
    154 	CFI_DEF_CFA(14,8)
    155 	move.l	%sp,-12(%fp)
    156 	pea	8(%fp)
    157 	pea	-12(%fp)
    158 	move.l	%a0,-(%sp)
    159 #if !defined __PIC__
    160 	jsr	ffi_closure_SYSV_inner
    161 #else
    162 	bsr.l	ffi_closure_SYSV_inner@PLTPC
    163 #endif
    164 
    165 	lsr.l	#1,%d0
    166 	jne	1f
    167 	jcc	.Lcls_epilogue
    168 	move.l	-12(%fp),%d0
    169 .Lcls_epilogue:
    170 	unlk	%fp
    171 	rts
    172 1:
    173 	lea	-12(%fp),%a0
    174 	lsr.l	#2,%d0
    175 	jne	1f
    176 	jcs	.Lcls_ret_float
    177 	move.l	(%a0)+,%d0
    178 	move.l	(%a0),%d1
    179 	jra	.Lcls_epilogue
    180 .Lcls_ret_float:
    181 	fmove.s	(%a0),%fp0
    182 	jra	.Lcls_epilogue
    183 1:
    184 	lsr.l	#2,%d0
    185 	jne	1f
    186 	jcs	.Lcls_ret_ldouble
    187 	fmove.d	(%a0),%fp0
    188 	jra	.Lcls_epilogue
    189 .Lcls_ret_ldouble:
    190 	fmove.x	(%a0),%fp0
    191 	jra	.Lcls_epilogue
    192 1:
    193 	lsr.l	#2,%d0
    194 	jne	.Lcls_ret_struct2
    195 	jcs	.Lcls_ret_struct1
    196 	move.l	(%a0),%a0
    197 	move.l	%a0,%d0
    198 	jra	.Lcls_epilogue
    199 .Lcls_ret_struct1:
    200 	move.b	(%a0),%d0
    201 	jra	.Lcls_epilogue
    202 .Lcls_ret_struct2:
    203 	move.w	(%a0),%d0
    204 	jra	.Lcls_epilogue
    205 	CFI_ENDPROC()
    206 
    207 	.size	ffi_closure_SYSV,.-ffi_closure_SYSV
    208 
    209 	.globl	ffi_closure_struct_SYSV
    210 	.type	ffi_closure_struct_SYSV, @function
    211 	.align	4
    212 
    213 ffi_closure_struct_SYSV:
    214 	CFI_STARTPROC()
    215 	link	%fp,#0
    216 	CFI_OFFSET(14,-8)
    217 	CFI_DEF_CFA(14,8)
    218 	move.l	%sp,-12(%fp)
    219 	pea	8(%fp)
    220 	move.l	%a1,-(%sp)
    221 	move.l	%a0,-(%sp)
    222 #if !defined __PIC__
    223 	jsr	ffi_closure_SYSV_inner
    224 #else
    225 	bsr.l	ffi_closure_SYSV_inner@PLTPC
    226 #endif
    227 	unlk	%fp
    228 	rts
    229 	CFI_ENDPROC()
    230 	.size	ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
    231 
    232 #if defined __ELF__ && defined __linux__
    233 	.section	.note.GNU-stack,"",@progbits
    234 #endif
    235