1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/* -----------------------------------------------------------------------
sysv.S
m68k Foreign Function Interface
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
.text
.globl ffi_call_SYSV
.type ffi_call_SYSV,@function
ffi_call_SYSV:
link %fp,#0
move.l %d2,-(%sp)
| Make room for all of the new args.
sub.l 16(%fp),%sp
| Call ffi_prep_args
move.l 12(%fp),-(%sp)
pea 4(%sp)
move.l 8(%fp),%a0
jsr (%a0)
addq.l #8,%sp
| Pass pointer to struct value, if any
move.l %a0,%a1
| Call the function
move.l 32(%fp),%a0
jsr (%a0)
| Remove the space we pushed for the args
add.l 16(%fp),%sp
| Load the pointer to storage for the return value
move.l 28(%fp),%a1
| Load the return type code
move.l 20(%fp),%d2
| If the return value pointer is NULL, assume no return value.
tst.l %a1
jbeq noretval
btst #0,%d2
jbeq retlongint
move.l %d0,(%a1)
jbra epilogue
retlongint:
btst #1,%d2
jbeq retfloat
move.l %d0,(%a1)
move.l %d1,4(%a1)
jbra epilogue
retfloat:
btst #2,%d2
jbeq retdouble
fmove.s %fp0,(%a1)
jbra epilogue
retdouble:
btst #3,%d2
jbeq retlongdouble
fmove.d %fp0,(%a1)
jbra epilogue
retlongdouble:
btst #4,%d2
jbeq retpointer
fmove.x %fp0,(%a1)
jbra epilogue
retpointer:
btst #5,%d2
jbeq retstruct
move.l %a0,(%a1)
jbra epilogue
retstruct:
btst #6,%d2
jbeq noretval
move.l 24(%fp),%d2
bfins %d0,(%a1){#0,%d2}
noretval:
epilogue:
move.l (%sp)+,%d2
unlk %a6
rts
.size ffi_call_SYSV,.-ffi_call_SYSV
|