1 | /* -----------------------------------------------------------------------
|
---|
2 | osf.S - Copyright (c) 1998, 2001 Red Hat
|
---|
3 |
|
---|
4 | Alpha/OSF Foreign Function Interface
|
---|
5 |
|
---|
6 | $Id: osf.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
|
---|
7 |
|
---|
8 | Permission is hereby granted, free of charge, to any person obtaining
|
---|
9 | a copy of this software and associated documentation files (the
|
---|
10 | ``Software''), to deal in the Software without restriction, including
|
---|
11 | without limitation the rights to use, copy, modify, merge, publish,
|
---|
12 | distribute, sublicense, and/or sell copies of the Software, and to
|
---|
13 | permit persons to whom the Software is furnished to do so, subject to
|
---|
14 | the following conditions:
|
---|
15 |
|
---|
16 | The above copyright notice and this permission notice shall be included
|
---|
17 | in all copies or substantial portions of the Software.
|
---|
18 |
|
---|
19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
20 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
---|
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
---|
22 | IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
---|
23 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
---|
24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
25 | OTHER DEALINGS IN THE SOFTWARE.
|
---|
26 | ----------------------------------------------------------------------- */
|
---|
27 |
|
---|
28 | #define LIBFFI_ASM
|
---|
29 | #include <ffi.h>
|
---|
30 |
|
---|
31 | .arch ev6
|
---|
32 | .text
|
---|
33 |
|
---|
34 | /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
|
---|
35 | void *raddr, void (*fnaddr)());
|
---|
36 |
|
---|
37 | Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
|
---|
38 | for this function. This has been allocated by ffi_call. We also
|
---|
39 | deallocate some of the stack that has been alloca'd. */
|
---|
40 |
|
---|
41 | .align 3
|
---|
42 | .globl ffi_call_osf
|
---|
43 | .ent ffi_call_osf
|
---|
44 | ffi_call_osf:
|
---|
45 | .frame $15, 32, $26, 0
|
---|
46 | .mask 0x4008000, -32
|
---|
47 | $LFB1:
|
---|
48 | addq $16,$17,$1
|
---|
49 | mov $16, $30
|
---|
50 | stq $26, 0($1)
|
---|
51 | $LCFI0:
|
---|
52 | stq $15, 8($1)
|
---|
53 | $LCFI1:
|
---|
54 | stq $18, 16($1)
|
---|
55 | mov $1, $15
|
---|
56 | $LCFI2:
|
---|
57 | .prologue 0
|
---|
58 |
|
---|
59 | stq $19, 24($1)
|
---|
60 | mov $20, $27
|
---|
61 |
|
---|
62 | # Load up all of the (potential) argument registers.
|
---|
63 | ldq $16, 0($30)
|
---|
64 | ldt $f16, 0($30)
|
---|
65 | ldt $f17, 8($30)
|
---|
66 | ldq $17, 8($30)
|
---|
67 | ldt $f18, 16($30)
|
---|
68 | ldq $18, 16($30)
|
---|
69 | ldt $f19, 24($30)
|
---|
70 | ldq $19, 24($30)
|
---|
71 | ldt $f20, 32($30)
|
---|
72 | ldq $20, 32($30)
|
---|
73 | ldt $f21, 40($30)
|
---|
74 | ldq $21, 40($30)
|
---|
75 |
|
---|
76 | # Deallocate the register argument area.
|
---|
77 | lda $30, 48($30)
|
---|
78 |
|
---|
79 | jsr $26, ($27), 0
|
---|
80 | ldgp $29, 0($26)
|
---|
81 |
|
---|
82 | # If the return value pointer is NULL, assume no return value.
|
---|
83 | ldq $19, 24($15)
|
---|
84 | ldq $18, 16($15)
|
---|
85 | ldq $26, 0($15)
|
---|
86 | beq $19, $noretval
|
---|
87 |
|
---|
88 | # Store the return value out in the proper type.
|
---|
89 | cmpeq $18, FFI_TYPE_INT, $1
|
---|
90 | bne $1, $retint
|
---|
91 | cmpeq $18, FFI_TYPE_FLOAT, $2
|
---|
92 | bne $2, $retfloat
|
---|
93 | cmpeq $18, FFI_TYPE_DOUBLE, $3
|
---|
94 | bne $3, $retdouble
|
---|
95 |
|
---|
96 | $noretval:
|
---|
97 | ldq $15, 8($15)
|
---|
98 | ret
|
---|
99 |
|
---|
100 | $retint:
|
---|
101 | stq $0, 0($19)
|
---|
102 | nop
|
---|
103 | ldq $15, 8($15)
|
---|
104 | ret
|
---|
105 |
|
---|
106 | $retfloat:
|
---|
107 | sts $f0, 0($19)
|
---|
108 | nop
|
---|
109 | ldq $15, 8($15)
|
---|
110 | ret
|
---|
111 |
|
---|
112 | $retdouble:
|
---|
113 | stt $f0, 0($19)
|
---|
114 | nop
|
---|
115 | ldq $15, 8($15)
|
---|
116 | ret
|
---|
117 | $LFE1:
|
---|
118 |
|
---|
119 | .end ffi_call_osf
|
---|
120 |
|
---|
121 | /* ffi_closure_osf(...)
|
---|
122 |
|
---|
123 | Receives the closure argument in $1. */
|
---|
124 |
|
---|
125 | .align 3
|
---|
126 | .globl ffi_closure_osf
|
---|
127 | .ent ffi_closure_osf
|
---|
128 | ffi_closure_osf:
|
---|
129 | .frame $30, 16*8, $26, 0
|
---|
130 | .mask 0x4000000, -16*8
|
---|
131 | $LFB2:
|
---|
132 | ldgp $29, 0($27)
|
---|
133 | subq $30, 16*8, $30
|
---|
134 | $LCFI5:
|
---|
135 | stq $26, 0($30)
|
---|
136 | $LCFI6:
|
---|
137 | .prologue 1
|
---|
138 |
|
---|
139 | # Store all of the potential argument registers in va_list format.
|
---|
140 | stt $f16, 4*8($30)
|
---|
141 | stt $f17, 5*8($30)
|
---|
142 | stt $f18, 6*8($30)
|
---|
143 | stt $f19, 7*8($30)
|
---|
144 | stt $f20, 8*8($30)
|
---|
145 | stt $f21, 9*8($30)
|
---|
146 | stq $16, 10*8($30)
|
---|
147 | stq $17, 11*8($30)
|
---|
148 | stq $18, 12*8($30)
|
---|
149 | stq $19, 13*8($30)
|
---|
150 | stq $20, 14*8($30)
|
---|
151 | stq $21, 15*8($30)
|
---|
152 |
|
---|
153 | # Call ffi_closure_osf_inner to do the bulk of the work.
|
---|
154 | mov $1, $16
|
---|
155 | lda $17, 2*8($30)
|
---|
156 | lda $18, 10*8($30)
|
---|
157 | jsr $26, ffi_closure_osf_inner
|
---|
158 | ldgp $29, 0($26)
|
---|
159 | ldq $26, 0($30)
|
---|
160 |
|
---|
161 | # Load up the return value in the proper type.
|
---|
162 | lda $1, $load_table
|
---|
163 | s4addq $0, $1, $1
|
---|
164 | ldl $1, 0($1)
|
---|
165 | addq $1, $29, $1
|
---|
166 | jmp $31, ($1), $load_32
|
---|
167 |
|
---|
168 | .align 4
|
---|
169 | $load_none:
|
---|
170 | addq $30, 16*8, $30
|
---|
171 | ret
|
---|
172 |
|
---|
173 | .align 4
|
---|
174 | $load_float:
|
---|
175 | lds $f0, 16($30)
|
---|
176 | nop
|
---|
177 | addq $30, 16*8, $30
|
---|
178 | ret
|
---|
179 |
|
---|
180 | .align 4
|
---|
181 | $load_double:
|
---|
182 | ldt $f0, 16($30)
|
---|
183 | nop
|
---|
184 | addq $30, 16*8, $30
|
---|
185 | ret
|
---|
186 |
|
---|
187 | .align 4
|
---|
188 | $load_u8:
|
---|
189 | #ifdef __alpha_bwx__
|
---|
190 | ldbu $0, 16($30)
|
---|
191 | nop
|
---|
192 | #else
|
---|
193 | ldq $0, 16($30)
|
---|
194 | and $0, 255, $0
|
---|
195 | #endif
|
---|
196 | addq $30, 16*8, $30
|
---|
197 | ret
|
---|
198 |
|
---|
199 | .align 4
|
---|
200 | $load_s8:
|
---|
201 | #ifdef __alpha_bwx__
|
---|
202 | ldbu $0, 16($30)
|
---|
203 | sextb $0, $0
|
---|
204 | #else
|
---|
205 | ldq $0, 16($30)
|
---|
206 | sll $0, 56, $0
|
---|
207 | sra $0, 56, $0
|
---|
208 | #endif
|
---|
209 | addq $30, 16*8, $30
|
---|
210 | ret
|
---|
211 |
|
---|
212 | .align 4
|
---|
213 | $load_u16:
|
---|
214 | #ifdef __alpha_bwx__
|
---|
215 | ldwu $0, 16($30)
|
---|
216 | nop
|
---|
217 | #else
|
---|
218 | ldq $0, 16($30)
|
---|
219 | zapnot $0, 3, $0
|
---|
220 | #endif
|
---|
221 | addq $30, 16*8, $30
|
---|
222 | ret
|
---|
223 |
|
---|
224 | .align 4
|
---|
225 | $load_s16:
|
---|
226 | #ifdef __alpha_bwx__
|
---|
227 | ldwu $0, 16($30)
|
---|
228 | sextw $0, $0
|
---|
229 | #else
|
---|
230 | ldq $0, 16($30)
|
---|
231 | sll $0, 48, $0
|
---|
232 | sra $0, 48, $0
|
---|
233 | #endif
|
---|
234 | addq $30, 16*8, $30
|
---|
235 | ret
|
---|
236 |
|
---|
237 | .align 4
|
---|
238 | $load_32:
|
---|
239 | ldl $0, 16($30)
|
---|
240 | nop
|
---|
241 | addq $30, 16*8, $30
|
---|
242 | ret
|
---|
243 |
|
---|
244 | .align 4
|
---|
245 | $load_64:
|
---|
246 | ldq $0, 16($30)
|
---|
247 | nop
|
---|
248 | addq $30, 16*8, $30
|
---|
249 | ret
|
---|
250 | $LFE2:
|
---|
251 |
|
---|
252 | .end ffi_closure_osf
|
---|
253 |
|
---|
254 | #ifdef __ELF__
|
---|
255 | .section .rodata
|
---|
256 | #else
|
---|
257 | .rdata
|
---|
258 | #endif
|
---|
259 | $load_table:
|
---|
260 | .gprel32 $load_none # FFI_TYPE_VOID
|
---|
261 | .gprel32 $load_32 # FFI_TYPE_INT
|
---|
262 | .gprel32 $load_float # FFI_TYPE_FLOAT
|
---|
263 | .gprel32 $load_double # FFI_TYPE_DOUBLE
|
---|
264 | .gprel32 $load_double # FFI_TYPE_LONGDOUBLE
|
---|
265 | .gprel32 $load_u8 # FFI_TYPE_UINT8
|
---|
266 | .gprel32 $load_s8 # FFI_TYPE_SINT8
|
---|
267 | .gprel32 $load_u16 # FFI_TYPE_UINT16
|
---|
268 | .gprel32 $load_s16 # FFI_TYPE_SINT16
|
---|
269 | .gprel32 $load_32 # FFI_TYPE_UINT32
|
---|
270 | .gprel32 $load_32 # FFI_TYPE_SINT32
|
---|
271 | .gprel32 $load_64 # FFI_TYPE_UINT64
|
---|
272 | .gprel32 $load_64 # FFI_TYPE_SINT64
|
---|
273 | .gprel32 $load_none # FFI_TYPE_STRUCT
|
---|
274 | .gprel32 $load_64 # FFI_TYPE_POINTER
|
---|
275 |
|
---|
276 | /* Assert that the table above is in sync with ffi.h. */
|
---|
277 |
|
---|
278 | #if FFI_TYPE_FLOAT != 2 \
|
---|
279 | || FFI_TYPE_DOUBLE != 3 \
|
---|
280 | || FFI_TYPE_UINT8 != 5 \
|
---|
281 | || FFI_TYPE_SINT8 != 6 \
|
---|
282 | || FFI_TYPE_UINT16 != 7 \
|
---|
283 | || FFI_TYPE_SINT16 != 8 \
|
---|
284 | || FFI_TYPE_UINT32 != 9 \
|
---|
285 | || FFI_TYPE_SINT32 != 10 \
|
---|
286 | || FFI_TYPE_UINT64 != 11 \
|
---|
287 | || FFI_TYPE_SINT64 != 12 \
|
---|
288 | || FFI_TYPE_STRUCT != 13 \
|
---|
289 | || FFI_TYPE_POINTER != 14 \
|
---|
290 | || FFI_TYPE_LAST != 14
|
---|
291 | #error "osf.S out of sync with ffi.h"
|
---|
292 | #endif
|
---|
293 |
|
---|
294 | #ifdef __ELF__
|
---|
295 | .section .eh_frame,"aw",@progbits
|
---|
296 | __FRAME_BEGIN__:
|
---|
297 | .4byte $LECIE1-$LSCIE1 # Length of Common Information Entry
|
---|
298 | $LSCIE1:
|
---|
299 | .4byte 0x0 # CIE Identifier Tag
|
---|
300 | .byte 0x1 # CIE Version
|
---|
301 | .ascii "zR\0" # CIE Augmentation
|
---|
302 | .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
|
---|
303 | .byte 0x78 # sleb128 -8; CIE Data Alignment Factor
|
---|
304 | .byte 0x1a # CIE RA Column
|
---|
305 | .byte 0x1 # uleb128 0x1; Augmentation size
|
---|
306 | .byte 0x1b # FDE Encoding (pcrel sdata4)
|
---|
307 | .byte 0xc # DW_CFA_def_cfa
|
---|
308 | .byte 0x1e # uleb128 0x1e
|
---|
309 | .byte 0x0 # uleb128 0x0
|
---|
310 | .align 3
|
---|
311 | $LECIE1:
|
---|
312 | $LSFDE1:
|
---|
313 | .4byte $LEFDE1-$LASFDE1 # FDE Length
|
---|
314 | $LASFDE1:
|
---|
315 | .4byte $LASFDE1-__FRAME_BEGIN__ # FDE CIE offset
|
---|
316 | .4byte $LFB1-. # FDE initial location
|
---|
317 | .4byte $LFE1-$LFB1 # FDE address range
|
---|
318 | .byte 0x0 # uleb128 0x0; Augmentation size
|
---|
319 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
320 | .4byte $LCFI0-$LFB1
|
---|
321 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
322 | .byte 0x30 # uleb128 0x30
|
---|
323 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
324 | .4byte $LCFI1-$LCFI0
|
---|
325 | .byte 0x9a # DW_CFA_offset, column 0x1a
|
---|
326 | .byte 0x6 # uleb128 0x6
|
---|
327 | .byte 0x8f # DW_CFA_offset, column 0xf
|
---|
328 | .byte 0x5 # uleb128 0x5
|
---|
329 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
330 | .4byte $LCFI2-$LCFI1
|
---|
331 | .byte 0xc # DW_CFA_def_cfa
|
---|
332 | .byte 0xf # uleb128 0xf
|
---|
333 | .byte 0x30 # uleb128 0x30
|
---|
334 | .align 3
|
---|
335 | $LEFDE1:
|
---|
336 |
|
---|
337 | $LSFDE3:
|
---|
338 | .4byte $LEFDE3-$LASFDE3 # FDE Length
|
---|
339 | $LASFDE3:
|
---|
340 | .4byte $LASFDE3-__FRAME_BEGIN__ # FDE CIE offset
|
---|
341 | .4byte $LFB2-. # FDE initial location
|
---|
342 | .4byte $LFE2-$LFB2 # FDE address range
|
---|
343 | .byte 0x0 # uleb128 0x0; Augmentation size
|
---|
344 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
345 | .4byte $LCFI5-$LFB2
|
---|
346 | .byte 0xe # DW_CFA_def_cfa_offset
|
---|
347 | .byte 0x90,0x1 # uleb128 0x90
|
---|
348 | .byte 0x4 # DW_CFA_advance_loc4
|
---|
349 | .4byte $LCFI6-$LCFI5
|
---|
350 | .byte 0x9a # DW_CFA_offset, column 0x1a
|
---|
351 | .byte 0x12 # uleb128 0x12
|
---|
352 | .align 3
|
---|
353 | $LEFDE3:
|
---|
354 | #endif
|
---|