OSDN Git Service

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