[RS6000] powerpc64le -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 ICE
[official-gcc.git] / libffi / src / vax / elfbsd.S
blob01ca313402b20e2f5b7aff45d2c08995b78da2d6
1 /*
2  * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * ``Software''), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
25  * vax Foreign Function Interface
26  */
28 #define LIBFFI_ASM      
29 #include <fficonfig.h>
30 #include <ffi.h>
32         .text
35  * void *                                       %r0
36  * ffi_call_elfbsd(extended_cif *ecif,          4(%ap)
37  *                 unsigned bytes,              8(%ap)
38  *                 unsigned flags,              12(%ap)
39  *                 void *rvalue,                16(%ap)
40  *                 void (*fn)());               20(%ap)
41  */
42         .globl  ffi_call_elfbsd
43         .type   ffi_call_elfbsd,@function
44         .align  2
45 ffi_call_elfbsd:
46         .word   0x00c           # save R2 and R3
48         # Allocate stack space for the args
49         subl2   8(%ap), %sp
51         # Call ffi_prep_args
52         pushl   %sp
53         pushl   4(%ap)
54         calls   $2, ffi_prep_args
56         # Get function pointer
57         movl    20(%ap), %r1
59         # Build a CALLS frame
60         ashl    $-2, 8(%ap), %r0
61         pushl   %r0             # argument stack usage
62         movl    %sp, %r0        # future %ap
63         # saved registers
64         bbc     $11, 0(%r1), 1f
65         pushl   %r11
66 1:      bbc     $10, 0(%r1), 1f
67         pushl   %r10
68 1:      bbc     $9, 0(%r1), 1f
69         pushl   %r9
70 1:      bbc     $8, 0(%r1), 1f
71         pushl   %r8
72 1:      bbc     $7, 0(%r1), 1f
73         pushl   %r7
74 1:      bbc     $6, 0(%r1), 1f
75         pushl   %r6
76 1:      bbc     $5, 0(%r1), 1f
77         pushl   %r5
78 1:      bbc     $4, 0(%r1), 1f
79         pushl   %r4
80 1:      bbc     $3, 0(%r1), 1f
81         pushl   %r3
82 1:      bbc     $2, 0(%r1), 1f
83         pushl   %r2
84 1:      
85         pushal  9f
86         pushl   %fp
87         pushl   %ap
88         movl    16(%ap), %r3    # struct return address, if needed
89         movl    %r0, %ap
90         movzwl  4(%fp), %r0     # previous PSW, without the saved registers mask
91         bisl2   $0x20000000, %r0 # calls frame
92         movzwl  0(%r1), %r2
93         bicw2   $0xf003, %r2    # only keep R11-R2
94         ashl    $16, %r2, %r2
95         bisl2   %r2, %r0        # saved register mask of the called function
96         pushl   %r0     
97         pushl   $0
98         movl    %sp, %fp
100         # Invoke the function
101         pushal  2(%r1)          # skip procedure entry mask
102         movl    %r3, %r1
103         bicpsw  $0x000f
104         rsb
107         # Copy return value if necessary
108         tstl    16(%ap)
109         jeql    9f
110         movl    16(%ap), %r2
112         bbc     $0, 12(%ap), 1f # CIF_FLAGS_CHAR
113         movb    %r0, 0(%r2)
114         brb     9f
116         bbc     $1, 12(%ap), 1f # CIF_FLAGS_SHORT
117         movw    %r0, 0(%r2)
118         brb     9f
120         bbc     $2, 12(%ap), 1f # CIF_FLAGS_INT
121         movl    %r0, 0(%r2)
122         brb     9f
124         bbc     $3, 12(%ap), 1f # CIF_FLAGS_DINT
125         movq    %r0, 0(%r2)
126         brb     9f
128         movl    %r1, %r0        # might have been a struct
129         #brb    9f
132         ret
135  * ffi_closure_elfbsd(void);
136  * invoked with %r0: ffi_closure *closure
137  */
138         .globl  ffi_closure_elfbsd
139         .type   ffi_closure_elfbsd, @function
140         .align  2
141 ffi_closure_elfbsd:
142         .word   0
144         # Allocate room on stack for return value
145         subl2   $8, %sp
147         # Invoke the closure function
148         pushal  4(%ap)          # calling stack
149         pushal  4(%sp)          # return value
150         pushl   %r0             # closure
151         calls   $3, ffi_closure_elfbsd_inner
153         # Copy return value if necessary
154         bitb    $1, %r0         # CIF_FLAGS_CHAR
155         beql    1f
156         movb    0(%sp), %r0
157         brb     9f
159         bitb    $2, %r0         # CIF_FLAGS_SHORT
160         beql    1f
161         movw    0(%sp), %r0
162         brb     9f
164         bitb    $4, %r0         # CIF_FLAGS_INT
165         beql    1f
166         movl    0(%sp), %r0
167         brb     9f
169         bitb    $8, %r0         # CIF_FLAGS_DINT
170         beql    1f
171         movq    0(%sp), %r0
172         #brb    9f
176         ret
179  * ffi_closure_struct_elfbsd(void);
180  * invoked with %r0: ffi_closure *closure
181  *              %r1: struct return address
182  */
183         .globl  ffi_closure_struct_elfbsd
184         .type   ffi_closure_struct_elfbsd, @function
185         .align  2
186 ffi_closure_struct_elfbsd:
187         .word   0
189         # Invoke the closure function
190         pushal  4(%ap)          # calling stack
191         pushl   %r1             # return value
192         pushl   %r0             # closure
193         calls   $3, ffi_closure_elfbsd_inner
195         ret