]> git.ipfire.org Git - thirdparty/gcc.git/blob - libffi/src/alpha/osf.S
Merge libffi to upstream commit c82cc159426d8d4402375fa1ae3f045b9cf82e16
[thirdparty/gcc.git] / libffi / src / alpha / osf.S
1 /* -----------------------------------------------------------------------
2 osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 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,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 DEALINGS IN THE SOFTWARE.
25 ----------------------------------------------------------------------- */
26
27 #define LIBFFI_ASM
28 #include <fficonfig.h>
29 #include <ffi.h>
30 #include <ffi_cfi.h>
31 #include "internal.h"
32
33 .arch ev6
34 .text
35
36 /* Aid in building a direct addressed jump table, 4 insns per entry. */
37 .macro E index
38 .align 4
39 .org 99b + \index * 16
40 .endm
41
42 /* ffi_call_osf (void *stack, void *frame, unsigned flags,
43 void *raddr, void (*fnaddr)(void), void *closure)
44
45 Bit o trickiness here -- FRAME is the base of the stack frame
46 for this function. This has been allocated by ffi_call. We also
47 deallocate some of the stack that has been alloca'd. */
48
49 .align 4
50 .globl ffi_call_osf
51 .ent ffi_call_osf
52 FFI_HIDDEN(ffi_call_osf)
53
54 ffi_call_osf:
55 cfi_startproc
56 cfi_def_cfa($17, 32)
57 mov $16, $30
58 stq $26, 0($17)
59 stq $15, 8($17)
60 mov $17, $15
61 .prologue 0
62 cfi_def_cfa_register($15)
63 cfi_rel_offset($26, 0)
64 cfi_rel_offset($15, 8)
65
66 stq $18, 16($17) # save flags into frame
67 stq $19, 24($17) # save rvalue into frame
68 mov $20, $27 # fn into place for call
69 mov $21, $1 # closure into static chain
70
71 # Load up all of the (potential) argument registers.
72 ldq $16, 0($30)
73 ldt $f16, 0($30)
74 ldt $f17, 8($30)
75 ldq $17, 8($30)
76 ldt $f18, 16($30)
77 ldq $18, 16($30)
78 ldt $f19, 24($30)
79 ldq $19, 24($30)
80 ldt $f20, 32($30)
81 ldq $20, 32($30)
82 ldt $f21, 40($30)
83 ldq $21, 40($30)
84
85 # Deallocate the register argument area.
86 lda $30, 48($30)
87
88 jsr $26, ($27), 0
89 0:
90 ldah $29, 0($26) !gpdisp!1
91 ldq $2, 24($15) # reload rvalue
92 lda $29, 0($29) !gpdisp!1
93 ldq $3, 16($15) # reload flags
94 lda $1, 99f-0b($26)
95 ldq $26, 0($15)
96 ldq $15, 8($15)
97 cfi_restore($26)
98 cfi_restore($15)
99 cfi_def_cfa($sp, 0)
100 cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void
101 addq $3, $3, $3
102 s8addq $3, $1, $1 # 99f + stcode * 16
103 jmp $31, ($1), $st_int
104
105 .align 4
106 99:
107 E ALPHA_ST_VOID
108 ret
109 E ALPHA_ST_INT
110 $st_int:
111 stq $0, 0($2)
112 ret
113 E ALPHA_ST_FLOAT
114 sts $f0, 0($2)
115 ret
116 E ALPHA_ST_DOUBLE
117 stt $f0, 0($2)
118 ret
119 E ALPHA_ST_CPLXF
120 sts $f0, 0($2)
121 sts $f1, 4($2)
122 ret
123 E ALPHA_ST_CPLXD
124 stt $f0, 0($2)
125 stt $f1, 8($2)
126 ret
127
128 cfi_endproc
129 .end ffi_call_osf
130
131 /* ffi_closure_osf(...)
132
133 Receives the closure argument in $1. */
134
135 #define CLOSURE_FS (16*8)
136
137 .align 4
138 .globl ffi_go_closure_osf
139 .ent ffi_go_closure_osf
140 FFI_HIDDEN(ffi_go_closure_osf)
141
142 ffi_go_closure_osf:
143 cfi_startproc
144 ldgp $29, 0($27)
145 subq $30, CLOSURE_FS, $30
146 cfi_adjust_cfa_offset(CLOSURE_FS)
147 stq $26, 0($30)
148 .prologue 1
149 cfi_rel_offset($26, 0)
150
151 stq $16, 10*8($30)
152 stq $17, 11*8($30)
153 stq $18, 12*8($30)
154
155 ldq $16, 8($1) # load cif
156 ldq $17, 16($1) # load fun
157 mov $1, $18 # closure is user_data
158 br $do_closure
159
160 cfi_endproc
161 .end ffi_go_closure_osf
162
163 .align 4
164 .globl ffi_closure_osf
165 .ent ffi_closure_osf
166 FFI_HIDDEN(ffi_closure_osf)
167
168 ffi_closure_osf:
169 cfi_startproc
170 ldgp $29, 0($27)
171 subq $30, CLOSURE_FS, $30
172 cfi_adjust_cfa_offset(CLOSURE_FS)
173 stq $26, 0($30)
174 .prologue 1
175 cfi_rel_offset($26, 0)
176
177 # Store all of the potential argument registers in va_list format.
178 stq $16, 10*8($30)
179 stq $17, 11*8($30)
180 stq $18, 12*8($30)
181
182 ldq $16, 24($1) # load cif
183 ldq $17, 32($1) # load fun
184 ldq $18, 40($1) # load user_data
185
186 $do_closure:
187 stq $19, 13*8($30)
188 stq $20, 14*8($30)
189 stq $21, 15*8($30)
190 stt $f16, 4*8($30)
191 stt $f17, 5*8($30)
192 stt $f18, 6*8($30)
193 stt $f19, 7*8($30)
194 stt $f20, 8*8($30)
195 stt $f21, 9*8($30)
196
197 # Call ffi_closure_osf_inner to do the bulk of the work.
198 lda $19, 2*8($30)
199 lda $20, 10*8($30)
200 jsr $26, ffi_closure_osf_inner
201 0:
202 ldah $29, 0($26) !gpdisp!2
203 lda $2, 99f-0b($26)
204 s4addq $0, 0, $1 # ldcode * 4
205 ldq $0, 16($30) # preload return value
206 s4addq $1, $2, $1 # 99f + ldcode * 16
207 lda $29, 0($29) !gpdisp!2
208 ldq $26, 0($30)
209 cfi_restore($26)
210 jmp $31, ($1), $load_32
211
212 .macro epilogue
213 addq $30, CLOSURE_FS, $30
214 cfi_adjust_cfa_offset(-CLOSURE_FS)
215 ret
216 .align 4
217 cfi_adjust_cfa_offset(CLOSURE_FS)
218 .endm
219
220 .align 4
221 99:
222 E ALPHA_LD_VOID
223 epilogue
224
225 E ALPHA_LD_INT64
226 epilogue
227
228 E ALPHA_LD_INT32
229 $load_32:
230 sextl $0, $0
231 epilogue
232
233 E ALPHA_LD_UINT16
234 zapnot $0, 3, $0
235 epilogue
236
237 E ALPHA_LD_SINT16
238 #ifdef __alpha_bwx__
239 sextw $0, $0
240 #else
241 sll $0, 48, $0
242 sra $0, 48, $0
243 #endif
244 epilogue
245
246 E ALPHA_LD_UINT8
247 and $0, 0xff, $0
248 epilogue
249
250 E ALPHA_LD_SINT8
251 #ifdef __alpha_bwx__
252 sextb $0, $0
253 #else
254 sll $0, 56, $0
255 sra $0, 56, $0
256 #endif
257 epilogue
258
259 E ALPHA_LD_FLOAT
260 lds $f0, 16($sp)
261 epilogue
262
263 E ALPHA_LD_DOUBLE
264 ldt $f0, 16($sp)
265 epilogue
266
267 E ALPHA_LD_CPLXF
268 lds $f0, 16($sp)
269 lds $f1, 20($sp)
270 epilogue
271
272 E ALPHA_LD_CPLXD
273 ldt $f0, 16($sp)
274 ldt $f1, 24($sp)
275 epilogue
276
277 cfi_endproc
278 .end ffi_closure_osf
279
280 #if defined __ELF__ && defined __linux__
281 .section .note.GNU-stack,"",@progbits
282 #endif