OSDN Git Service

Richards changes to the closure code for alpha
[pf3gnuchains/gcc-fork.git] / libffi / src / alpha / osf.S
1 /* -----------------------------------------------------------------------
2    osf.S - Copyright (c) 1998 Cygnus Solutions
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         addq    $16,$17,$1
48         mov     $16, $30
49         stq     $26, 0($1)
50         stq     $15, 8($1)
51         stq     $18, 16($1)
52         mov     $1, $15
53         .prologue 0
54
55         stq     $19, 24($1)
56         mov     $20, $27
57
58         # Load up all of the (potential) argument registers.
59         ldq     $16, 0($30)
60         ldt     $f16, 0($30)
61         ldt     $f17, 8($30)
62         ldq     $17, 8($30)
63         ldt     $f18, 16($30)
64         ldq     $18, 16($30)
65         ldt     $f19, 24($30)
66         ldq     $19, 24($30)
67         ldt     $f20, 32($30)
68         ldq     $20, 32($30)
69         ldt     $f21, 40($30)
70         ldq     $21, 40($30)
71
72         # Deallocate the register argument area.
73         lda     $30, 48($30)
74
75         jsr     $26, ($27), 0
76         ldgp    $29, 0($26)
77
78         # If the return value pointer is NULL, assume no return value.
79         ldq     $19, 24($15)
80         ldq     $18, 16($15)
81         ldq     $26, 0($15)
82         beq     $19, $noretval
83
84         # Store the return value out in the proper type.
85         cmpeq   $18, FFI_TYPE_INT, $1
86         bne     $1, $retint
87         cmpeq   $18, FFI_TYPE_FLOAT, $2
88         bne     $2, $retfloat
89         cmpeq   $18, FFI_TYPE_DOUBLE, $3
90         bne     $3, $retdouble
91
92 $noretval:
93         ldq     $15, 8($15)
94         ret
95
96 $retint:
97         stq     $0, 0($19)
98         nop
99         ldq     $15, 8($15)
100         ret
101
102 $retfloat:
103         sts     $f0, 0($19)
104         nop
105         ldq     $15, 8($15)
106         ret
107
108 $retdouble:
109         stt     $f0, 0($19)
110         nop
111         ldq     $15, 8($15)
112         ret
113
114         .end    ffi_call_osf
115
116 /* ffi_closure_osf(...)
117
118    Receives the closure argument in $1.   */
119
120         .align  3
121         .globl  ffi_closure_osf
122         .ent    ffi_closure_osf
123 ffi_closure_osf:
124         .frame  $30, 16*8, $26, 0
125         .mask   0x4000000, -16*8
126         ldgp    $29, 0($27)
127         subq    $30, 16*8, $30
128         stq     $26, 0($30)
129         .prologue 1
130
131         # Store all of the potential argument registers in va_list format.
132         stt     $f16, 4*8($30)
133         stt     $f17, 5*8($30)
134         stt     $f18, 6*8($30)
135         stt     $f19, 7*8($30)
136         stt     $f20, 8*8($30)
137         stt     $f21, 9*8($30)
138         stq     $16, 10*8($30)
139         stq     $17, 11*8($30)
140         stq     $18, 12*8($30)
141         stq     $19, 13*8($30)
142         stq     $20, 14*8($30)
143         stq     $21, 15*8($30)
144
145         # Call ffi_closure_osf_inner to do the bulk of the work.
146         mov     $1, $16
147         lda     $17, 2*8($30)
148         lda     $18, 10*8($30)
149         jsr     $26, ffi_closure_osf_inner
150         ldgp    $29, 0($26)
151         ldq     $26, 0($30)
152
153         # Load up the return value in the proper type.
154         lda     $1, $load_table
155         s4addq  $0, $1, $1
156         ldl     $1, 0($1)
157         addq    $1, $29, $1
158         jmp     $31, ($1), $load_32
159
160         .align 4
161 $load_none:
162         addq    $30, 16*8, $30
163         ret
164
165         .align 4
166 $load_float:
167         lds     $f0, 16($30)
168         nop
169         addq    $30, 16*8, $30
170         ret
171
172         .align 4
173 $load_double:
174         ldt     $f0, 16($30)
175         nop
176         addq    $30, 16*8, $30
177         ret
178
179         .align 4
180 $load_u8:
181 #ifdef __alpha_bwx__
182         ldbu    $0, 16($30)
183         nop
184 #else
185         ldq     $0, 16($30)
186         and     $0, 255, $0
187 #endif
188         addq    $30, 16*8, $30
189         ret
190
191         .align 4
192 $load_s8:
193 #ifdef __alpha_bwx__
194         ldbu    $0, 16($30)
195         sextb   $0, $0
196 #else
197         ldq     $0, 16($30)
198         sll     $0, 56, $0
199         sra     $0, 56, $0
200 #endif
201         addq    $30, 16*8, $30
202         ret
203
204         .align 4
205 $load_u16:
206 #ifdef __alpha_bwx__
207         ldwu    $0, 16($30)
208         nop
209 #else
210         ldq     $0, 16($30)
211         zapnot  $0, 3, $0
212 #endif
213         addq    $30, 16*8, $30
214         ret
215
216         .align 4
217 $load_s16:
218 #ifdef __alpha_bwx__
219         ldwu    $0, 16($30)
220         sextw   $0, $0
221 #else
222         ldq     $0, 16($30)
223         sll     $0, 48, $0
224         sra     $0, 48, $0
225 #endif
226         addq    $30, 16*8, $30
227         ret
228
229         .align 4
230 $load_32:
231         ldl     $0, 16($30)
232         nop
233         addq    $30, 16*8, $30
234         ret
235
236         .align 4
237 $load_64:
238         ldq     $0, 16($30)
239         nop
240         addq    $30, 16*8, $30
241         ret
242
243         .end    ffi_closure_osf
244
245 .section .rodata
246 $load_table:
247         .gprel32 $load_none     # FFI_TYPE_VOID
248         .gprel32 $load_32       # FFI_TYPE_INT
249         .gprel32 $load_float    # FFI_TYPE_FLOAT
250         .gprel32 $load_double   # FFI_TYPE_DOUBLE
251         .gprel32 $load_double   # FFI_TYPE_LONGDOUBLE
252         .gprel32 $load_u8       # FFI_TYPE_UINT8
253         .gprel32 $load_s8       # FFI_TYPE_SINT8
254         .gprel32 $load_u16      # FFI_TYPE_UINT16
255         .gprel32 $load_s16      # FFI_TYPE_SINT16
256         .gprel32 $load_32       # FFI_TYPE_UINT32
257         .gprel32 $load_32       # FFI_TYPE_SINT32
258         .gprel32 $load_64       # FFI_TYPE_UINT64
259         .gprel32 $load_64       # FFI_TYPE_SINT64
260         .gprel32 $load_none     # FFI_TYPE_STRUCT
261         .gprel32 $load_64       # FFI_TYPE_POINTER
262
263 /* Assert that the table above is in sync with ffi.h.  */
264
265 #if        FFI_TYPE_FLOAT != 2          \
266         || FFI_TYPE_DOUBLE != 3         \
267         || FFI_TYPE_UINT8 != 5          \
268         || FFI_TYPE_SINT8 != 6          \
269         || FFI_TYPE_UINT16 != 7         \
270         || FFI_TYPE_SINT16 != 8         \
271         || FFI_TYPE_UINT32 != 9         \
272         || FFI_TYPE_SINT32 != 10        \
273         || FFI_TYPE_UINT64 != 11        \
274         || FFI_TYPE_SINT64 != 12        \
275         || FFI_TYPE_STRUCT != 13        \
276         || FFI_TYPE_POINTER != 14       \
277         || FFI_TYPE_LAST != 14
278 #error "osf.S out of sync with ffi.h"
279 #endif