1 /* -----------------------------------------------------------------------
2 osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat
4 Alpha/OSF Foreign Function Interface
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:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
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 ----------------------------------------------------------------------- */
28 #include <fficonfig.h>
36 /* Aid in building a direct addressed jump table, 4 insns per entry. */
39 .org 99b + \index * 16
42 /* ffi_call_osf (void *stack, void *frame, unsigned flags,
43 void *raddr, void (*fnaddr)(void), void *closure)
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. */
52 FFI_HIDDEN(ffi_call_osf)
62 cfi_def_cfa_register($15)
63 cfi_rel_offset($26, 0)
64 cfi_rel_offset($15, 8)
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
71 # Load up all of the (potential) argument registers.
85 # Deallocate the register argument area.
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
100 cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void
102 s8addq $3, $1, $1 # 99f + stcode * 16
103 jmp $31, ($1), $st_int
131 /* ffi_closure_osf(...)
133 Receives the closure argument in $1. */
135 #define CLOSURE_FS (16*8)
138 .globl ffi_go_closure_osf
139 .ent ffi_go_closure_osf
140 FFI_HIDDEN(ffi_go_closure_osf)
145 subq $30, CLOSURE_FS, $30
146 cfi_adjust_cfa_offset(CLOSURE_FS)
149 cfi_rel_offset($26, 0)
155 ldq $16, 8($1) # load cif
156 ldq $17, 16($1) # load fun
157 mov $1, $18 # closure is user_data
161 .end ffi_go_closure_osf
164 .globl ffi_closure_osf
166 FFI_HIDDEN(ffi_closure_osf)
171 subq $30, CLOSURE_FS, $30
172 cfi_adjust_cfa_offset(CLOSURE_FS)
175 cfi_rel_offset($26, 0)
177 # Store all of the potential argument registers in va_list format.
182 ldq $16, 24($1) # load cif
183 ldq $17, 32($1) # load fun
184 ldq $18, 40($1) # load user_data
197 # Call ffi_closure_osf_inner to do the bulk of the work.
200 jsr $26, ffi_closure_osf_inner
202 ldah $29, 0($26) !gpdisp!2
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
210 jmp $31, ($1), $load_32
213 addq $30, CLOSURE_FS, $30
214 cfi_adjust_cfa_offset(-CLOSURE_FS)
217 cfi_adjust_cfa_offset(CLOSURE_FS)
280 #if defined __ELF__ && defined __linux__
281 .section .note.GNU-stack,"",@progbits