OSDN Git Service

libffi closures 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         .text
32
33 /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
34                  void *raddr, void (*fnaddr)());
35
36    Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
37    for this function.  This has been allocated by ffi_call.  We also
38    deallocate some of the stack that has been alloca'd.  */
39
40         .align  3
41         .globl  ffi_call_osf
42         .ent    ffi_call_osf
43 ffi_call_osf:
44         .frame  $15, 32, $26, 0
45         .mask   0x4008000, -32
46         addq    $16,$17,$1
47         mov     $16, $30
48         stq     $26, 0($1)
49         stq     $15, 8($1)
50         stq     $18, 16($1)
51         mov     $1, $15
52         .prologue 0
53
54         stq     $19, 24($1)
55         mov     $20, $27
56
57         # Load up all of the (potential) argument registers.
58         ldq     $16, 0($30)
59         ldt     $f16, 0($30)
60         ldt     $f17, 8($30)
61         ldq     $17, 8($30)
62         ldt     $f18, 16($30)
63         ldq     $18, 16($30)
64         ldt     $f19, 24($30)
65         ldq     $19, 24($30)
66         ldt     $f20, 32($30)
67         ldq     $20, 32($30)
68         ldt     $f21, 40($30)
69         ldq     $21, 40($30)
70
71         # Deallocate the register argument area.
72         lda     $30, 48($30)
73
74         jsr     $26, ($27), 0
75         ldgp    $29, 0($26)
76
77         # If the return value pointer is NULL, assume no return value.
78         ldq     $19, 24($15)
79         ldq     $18, 16($15)
80         ldq     $26, 0($15)
81         beq     $19, $noretval
82
83         # Store the return value out in the proper type.
84         cmpeq   $18, FFI_TYPE_INT, $1
85         bne     $1, $retint
86         cmpeq   $18, FFI_TYPE_FLOAT, $2
87         bne     $2, $retfloat
88         cmpeq   $18, FFI_TYPE_DOUBLE, $3
89         bne     $3, $retdouble
90
91 $noretval:
92         ldq     $15, 8($15)
93         ret
94
95 $retint:
96         stq     $0, 0($19)
97         nop
98         ldq     $15, 8($15)
99         ret
100
101 $retfloat:
102         sts     $f0, 0($19)
103         nop
104         ldq     $15, 8($15)
105         ret
106
107 $retdouble:
108         stt     $f0, 0($19)
109         nop
110         ldq     $15, 8($15)
111         ret
112
113         .end    ffi_call_osf
114
115 /* ffi_closure_osf(...)
116
117    Receives the closure argument in $1.   */
118
119         .align  3
120         .globl  ffi_closure_osf
121         .ent    ffi_closure_osf
122 ffi_closure_osf:
123         .frame  $30, 16*8, $26, 0
124         .mask   0x4000000, -14*8
125         ldgp    $29, 0($27)
126         subq    $30, 14*8, $30
127         stq     $26, 0($30)
128         .prologue 1
129
130         # Store all of the potential argument registers in va_list format.
131         stt     $f16, 4*8($30)
132         stt     $f17, 5*8($30)
133         stt     $f18, 6*8($30)
134         stt     $f19, 7*8($30)
135         stt     $f20, 8*8($30)
136         stt     $f21, 9*8($30)
137         stq     $16, 10*8($30)
138         stq     $17, 11*8($30)
139         stq     $18, 12*8($30)
140         stq     $19, 13*8($30)
141         stq     $20, 14*8($30)
142         stq     $21, 15*8($30)
143
144         # Call ffi_closure_osf_inner to do the bulk of the work.
145         mov     $1, $16
146         lda     $17, 2*8($30)
147         lda     $18, 10*8($30)
148         jsr     $26, ffi_closure_osf_inner
149         ldgp    $29, 0($26)
150         ldq     $26, 0($30)
151
152         # Load up the return value in the proper type.
153         cmpeq   $0, FFI_TYPE_INT, $1
154         bne     $1, $loadint
155         cmpeq   $0, FFI_TYPE_FLOAT, $2
156         bne     $2, $loadfloat
157         cmpeq   $18, FFI_TYPE_DOUBLE, $3
158         bne     $3, $loaddouble
159
160         addq    $30, 16*8, $30
161         ret
162
163         .align 3
164 $loadint:
165         ldq     $0, 16($30)
166         nop
167         addq    $30, 16*8, $30
168         ret
169
170 $loadfloat:
171         lds     $f0, 16($30)
172         nop
173         addq    $30, 16*8, $30
174         ret
175
176 $loaddouble:
177         ldt     $f0, 16($30)
178         nop
179         addq    $30, 16*8, $30
180         ret
181
182         .end    ffi_closure_osf