[combine] Only restrict pure simplification in mult-extend subst case, allow other...
[official-gcc.git] / libffi / src / alpha / osf.S
blobb0318282a015ac2802a7dc0fcbe313c4ce4a082e
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    ----------------------------------------------------------------------- */
27 #define LIBFFI_ASM
28 #include <fficonfig.h>
29 #include <ffi.h>
30 #include <ffi_cfi.h>
31 #include "internal.h"
33         .arch ev6
34         .text
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
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.  */
49         .align  4
50         .globl  ffi_call_osf
51         .ent    ffi_call_osf
52         FFI_HIDDEN(ffi_call_osf)
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)
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.
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)
85         # Deallocate the register argument area.
86         lda     $30, 48($30)
88         jsr     $26, ($27), 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
105         .align  4
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
128         cfi_endproc
129         .end    ffi_call_osf
131 /* ffi_closure_osf(...)
133    Receives the closure argument in $1.   */
135 #define CLOSURE_FS      (16*8)
137         .align  4
138         .globl  ffi_go_closure_osf
139         .ent    ffi_go_closure_osf
140         FFI_HIDDEN(ffi_go_closure_osf)
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)
151         stq     $16, 10*8($30)
152         stq     $17, 11*8($30)
153         stq     $18, 12*8($30)
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
160         cfi_endproc
161         .end    ffi_go_closure_osf
163         .align  4
164         .globl  ffi_closure_osf
165         .ent    ffi_closure_osf
166         FFI_HIDDEN(ffi_closure_osf)
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)
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)
182         ldq     $16, 24($1)                     # load cif
183         ldq     $17, 32($1)                     # load fun
184         ldq     $18, 40($1)                     # load user_data
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)
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
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
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
220         .align 4
222 E ALPHA_LD_VOID
223         epilogue
225 E ALPHA_LD_INT64
226         epilogue
228 E ALPHA_LD_INT32
229 $load_32:
230         sextl   $0, $0
231         epilogue
233 E ALPHA_LD_UINT16
234         zapnot  $0, 3, $0
235         epilogue
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
246 E ALPHA_LD_UINT8
247         and     $0, 0xff, $0
248         epilogue
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
259 E ALPHA_LD_FLOAT
260         lds     $f0, 16($sp)
261         epilogue
263 E ALPHA_LD_DOUBLE
264         ldt     $f0, 16($sp)
265         epilogue
267 E ALPHA_LD_CPLXF
268         lds     $f0, 16($sp)
269         lds     $f1, 20($sp)
270         epilogue
272 E ALPHA_LD_CPLXD
273         ldt     $f0, 16($sp)
274         ldt     $f1, 24($sp)
275         epilogue
277         cfi_endproc
278         .end    ffi_closure_osf
280 #if defined __ELF__ && defined __linux__
281         .section        .note.GNU-stack,"",@progbits
282 #endif