OSDN Git Service

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