1 | /* -----------------------------------------------------------------------
|
---|
2 | v9.S - Copyright (c) 2000, 2003 Cygnus Solutions
|
---|
3 |
|
---|
4 | Sparc 64bit 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, EXPRESS
|
---|
18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
---|
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
---|
20 | IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
---|
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
---|
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
23 | OTHER DEALINGS IN THE SOFTWARE.
|
---|
24 | ----------------------------------------------------------------------- */
|
---|
25 |
|
---|
26 | #define LIBFFI_ASM
|
---|
27 | #include <ffi.h>
|
---|
28 |
|
---|
29 | #ifdef SPARC64
|
---|
30 | /* Only compile this in for 64bit builds, because otherwise the object file
|
---|
31 | will have inproper architecture due to used instructions. */
|
---|
32 |
|
---|
33 | #define STACKFRAME 128 /* Minimum stack framesize for SPARC */
|
---|
34 | #define STACK_BIAS 2047
|
---|
35 | #define ARGS (128) /* Offset of register area in frame */
|
---|
36 |
|
---|
37 | .text
|
---|
38 | .align 8
|
---|
39 | .globl ffi_call_V9
|
---|
40 | .globl _ffi_call_V9
|
---|
41 |
|
---|
42 | ffi_call_V9:
|
---|
43 | _ffi_call_V9:
|
---|
44 | .LLFB1:
|
---|
45 | save %sp, -STACKFRAME, %sp
|
---|
46 | .LLCFI0:
|
---|
47 |
|
---|
48 | sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
|
---|
49 | add %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of
|
---|
50 | ! frame to set up
|
---|
51 |
|
---|
52 | mov %l0, %o0 ! call routine to set up frame
|
---|
53 | call %i0
|
---|
54 | mov %i1, %o1 ! (delay)
|
---|
55 | brz,pt %o0, 1f
|
---|
56 | ldx [%l0+ARGS], %o0 ! call foreign function
|
---|
57 |
|
---|
58 | ldd [%l0+ARGS], %f0
|
---|
59 | ldd [%l0+ARGS+8], %f2
|
---|
60 | ldd [%l0+ARGS+16], %f4
|
---|
61 | ldd [%l0+ARGS+24], %f6
|
---|
62 | ldd [%l0+ARGS+32], %f8
|
---|
63 | ldd [%l0+ARGS+40], %f10
|
---|
64 | ldd [%l0+ARGS+48], %f12
|
---|
65 | ldd [%l0+ARGS+56], %f14
|
---|
66 | ldd [%l0+ARGS+64], %f16
|
---|
67 | ldd [%l0+ARGS+72], %f18
|
---|
68 | ldd [%l0+ARGS+80], %f20
|
---|
69 | ldd [%l0+ARGS+88], %f22
|
---|
70 | ldd [%l0+ARGS+96], %f24
|
---|
71 | ldd [%l0+ARGS+104], %f26
|
---|
72 | ldd [%l0+ARGS+112], %f28
|
---|
73 | ldd [%l0+ARGS+120], %f30
|
---|
74 |
|
---|
75 | 1: ldx [%l0+ARGS+8], %o1
|
---|
76 | ldx [%l0+ARGS+16], %o2
|
---|
77 | ldx [%l0+ARGS+24], %o3
|
---|
78 | ldx [%l0+ARGS+32], %o4
|
---|
79 | ldx [%l0+ARGS+40], %o5
|
---|
80 | call %i5
|
---|
81 | sub %l0, STACK_BIAS, %sp ! (delay) switch to frame
|
---|
82 |
|
---|
83 | ! If the return value pointer is NULL, assume no return value.
|
---|
84 | brz,pn %i4, done
|
---|
85 | nop
|
---|
86 |
|
---|
87 | cmp %i3, FFI_TYPE_INT
|
---|
88 | be,a,pt %icc, done
|
---|
89 | stx %o0, [%i4] ! (delay)
|
---|
90 |
|
---|
91 | cmp %i3, FFI_TYPE_FLOAT
|
---|
92 | be,a,pn %icc, done
|
---|
93 | st %f0, [%i4+0] ! (delay)
|
---|
94 |
|
---|
95 | cmp %i3, FFI_TYPE_DOUBLE
|
---|
96 | be,a,pn %icc, done
|
---|
97 | std %f0, [%i4+0] ! (delay)
|
---|
98 |
|
---|
99 | cmp %i3, FFI_TYPE_STRUCT
|
---|
100 | be,pn %icc, dostruct
|
---|
101 |
|
---|
102 | cmp %i3, FFI_TYPE_LONGDOUBLE
|
---|
103 | bne,pt %icc, done
|
---|
104 | nop
|
---|
105 | std %f0, [%i4+0]
|
---|
106 | std %f2, [%i4+8]
|
---|
107 |
|
---|
108 | done: ret
|
---|
109 | restore
|
---|
110 |
|
---|
111 | dostruct:
|
---|
112 | /* This will not work correctly for unions. */
|
---|
113 | stx %o0, [%i4+0]
|
---|
114 | stx %o1, [%i4+8]
|
---|
115 | stx %o2, [%i4+16]
|
---|
116 | stx %o3, [%i4+24]
|
---|
117 | std %f0, [%i4+32]
|
---|
118 | std %f2, [%i4+40]
|
---|
119 | std %f4, [%i4+48]
|
---|
120 | std %f6, [%i4+56]
|
---|
121 | ret
|
---|
122 | restore
|
---|
123 | .LLFE1:
|
---|
124 |
|
---|
125 | .ffi_call_V9_end:
|
---|
126 | .size ffi_call_V9,.ffi_call_V9_end-ffi_call_V9
|
---|
127 |
|
---|
128 |
|
---|
129 | #define STACKFRAME 240 /* 16*8 register window +
|
---|
130 | 6*8 args backing store +
|
---|
131 | 8*8 locals */
|
---|
132 | #define FP %fp+STACK_BIAS
|
---|
133 |
|
---|
134 | /* ffi_closure_v9(...)
|
---|
135 |
|
---|
136 | Receives the closure argument in %g1. */
|
---|
137 |
|
---|
138 | .text
|
---|
139 | .align 8
|
---|
140 | .globl ffi_closure_v9
|
---|
141 |
|
---|
142 | ffi_closure_v9:
|
---|
143 | .LLFB2:
|
---|
144 | save %sp, -STACKFRAME, %sp
|
---|
145 | .LLCFI1:
|
---|
146 |
|
---|
147 | ! Store all of the potential argument registers in va_list format.
|
---|
148 | stx %i0, [FP+128+0]
|
---|
149 | stx %i1, [FP+128+8]
|
---|
150 | stx %i2, [FP+128+16]
|
---|
151 | stx %i3, [FP+128+24]
|
---|
152 | stx %i4, [FP+128+32]
|
---|
153 | stx %i5, [FP+128+40]
|
---|
154 |
|
---|
155 | ! Store possible floating point argument registers too.
|
---|
156 | std %f0, [FP-48]
|
---|
157 | std %f2, [FP-40]
|
---|
158 | std %f4, [FP-32]
|
---|
159 | std %f6, [FP-24]
|
---|
160 | std %f8, [FP-16]
|
---|
161 | std %f10, [FP-8]
|
---|
162 |
|
---|
163 | ! Call ffi_closure_sparc_inner to do the bulk of the work.
|
---|
164 | mov %g1, %o0
|
---|
165 | add %fp, STACK_BIAS-64, %o1
|
---|
166 | add %fp, STACK_BIAS+128, %o2
|
---|
167 | call ffi_closure_sparc_inner
|
---|
168 | add %fp, STACK_BIAS-48, %o3
|
---|
169 |
|
---|
170 | ! Load up the return value in the proper type.
|
---|
171 | cmp %o0, FFI_TYPE_VOID
|
---|
172 | be,pn %icc, done1
|
---|
173 |
|
---|
174 | cmp %o0, FFI_TYPE_FLOAT
|
---|
175 | be,a,pn %icc, done1
|
---|
176 | ld [FP-64], %f0
|
---|
177 |
|
---|
178 | cmp %o0, FFI_TYPE_DOUBLE
|
---|
179 | be,a,pn %icc, done1
|
---|
180 | ldd [FP-64], %f0
|
---|
181 |
|
---|
182 | cmp %o0, FFI_TYPE_LONGDOUBLE
|
---|
183 | be,a,pn %icc, longdouble1
|
---|
184 | ldd [FP-64], %f0
|
---|
185 |
|
---|
186 | cmp %o0, FFI_TYPE_STRUCT
|
---|
187 | be,pn %icc, struct1
|
---|
188 |
|
---|
189 | ! FFI_TYPE_UINT64 | FFI_TYPE_SINT64 | FFI_TYPE_POINTER
|
---|
190 | ldx [FP-64], %i0
|
---|
191 |
|
---|
192 | done1:
|
---|
193 | ret
|
---|
194 | restore
|
---|
195 |
|
---|
196 | struct1:
|
---|
197 | ldx [FP-56], %i2
|
---|
198 | ret
|
---|
199 | restore
|
---|
200 |
|
---|
201 | longdouble1:
|
---|
202 | ldd [FP-56], %f2
|
---|
203 | ret
|
---|
204 | restore
|
---|
205 | .LLFE2:
|
---|
206 |
|
---|
207 | .ffi_closure_v9_end:
|
---|
208 | .size ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
|
---|
209 |
|
---|
210 | .section ".eh_frame",#alloc,#write
|
---|
211 | .LLframe1:
|
---|
212 | .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry
|
---|
213 | .LLSCIE1:
|
---|
214 | .uaword 0x0 ! CIE Identifier Tag
|
---|
215 | .byte 0x1 ! CIE Version
|
---|
216 | .ascii "zR\0" ! CIE Augmentation
|
---|
217 | .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor
|
---|
218 | .byte 0x78 ! sleb128 -8; CIE Data Alignment Factor
|
---|
219 | .byte 0xf ! CIE RA Column
|
---|
220 | .byte 0x1 ! uleb128 0x1; Augmentation size
|
---|
221 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
---|
222 | .byte 0x1b ! FDE Encoding (pcrel sdata4)
|
---|
223 | #else
|
---|
224 | .byte 0x50 ! FDE Encoding (aligned absolute)
|
---|
225 | #endif
|
---|
226 | .byte 0xc ! DW_CFA_def_cfa
|
---|
227 | .byte 0xe ! uleb128 0xe
|
---|
228 | .byte 0xff,0xf ! uleb128 0x7ff
|
---|
229 | .align 8
|
---|
230 | .LLECIE1:
|
---|
231 | .LLSFDE1:
|
---|
232 | .uaword .LLEFDE1-.LLASFDE1 ! FDE Length
|
---|
233 | .LLASFDE1:
|
---|
234 | .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset
|
---|
235 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
---|
236 | .uaword %r_disp32(.LLFB1)
|
---|
237 | .uaword .LLFE1-.LLFB1 ! FDE address range
|
---|
238 | #else
|
---|
239 | .align 8
|
---|
240 | .xword .LLFB1
|
---|
241 | .uaxword .LLFE1-.LLFB1 ! FDE address range
|
---|
242 | #endif
|
---|
243 | .byte 0x0 ! uleb128 0x0; Augmentation size
|
---|
244 | .byte 0x4 ! DW_CFA_advance_loc4
|
---|
245 | .uaword .LLCFI0-.LLFB1
|
---|
246 | .byte 0xd ! DW_CFA_def_cfa_register
|
---|
247 | .byte 0x1e ! uleb128 0x1e
|
---|
248 | .byte 0x2d ! DW_CFA_GNU_window_save
|
---|
249 | .byte 0x9 ! DW_CFA_register
|
---|
250 | .byte 0xf ! uleb128 0xf
|
---|
251 | .byte 0x1f ! uleb128 0x1f
|
---|
252 | .align 8
|
---|
253 | .LLEFDE1:
|
---|
254 | .LLSFDE2:
|
---|
255 | .uaword .LLEFDE2-.LLASFDE2 ! FDE Length
|
---|
256 | .LLASFDE2:
|
---|
257 | .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset
|
---|
258 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
---|
259 | .uaword %r_disp32(.LLFB2)
|
---|
260 | .uaword .LLFE2-.LLFB2 ! FDE address range
|
---|
261 | #else
|
---|
262 | .align 8
|
---|
263 | .xword .LLFB2
|
---|
264 | .uaxword .LLFE2-.LLFB2 ! FDE address range
|
---|
265 | #endif
|
---|
266 | .byte 0x0 ! uleb128 0x0; Augmentation size
|
---|
267 | .byte 0x4 ! DW_CFA_advance_loc4
|
---|
268 | .uaword .LLCFI1-.LLFB2
|
---|
269 | .byte 0xd ! DW_CFA_def_cfa_register
|
---|
270 | .byte 0x1e ! uleb128 0x1e
|
---|
271 | .byte 0x2d ! DW_CFA_GNU_window_save
|
---|
272 | .byte 0x9 ! DW_CFA_register
|
---|
273 | .byte 0xf ! uleb128 0xf
|
---|
274 | .byte 0x1f ! uleb128 0x1f
|
---|
275 | .align 8
|
---|
276 | .LLEFDE2:
|
---|
277 | #endif
|
---|