111
|
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
|