OSDN Git Service

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