]> git.ipfire.org Git - thirdparty/gcc.git/blob - libffi/src/sh64/sysv.S
Makefile.am: Add SHmedia support.
[thirdparty/gcc.git] / libffi / src / sh64 / sysv.S
1 /* -----------------------------------------------------------------------
2 sysv.S - Copyright (c) 2003 Kaz Kojima
3
4 SuperH SHmedia 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 #ifdef HAVE_MACHINE_ASM_H
29 #include <machine/asm.h>
30 #else
31 /* XXX these lose for some platforms, I'm sure. */
32 #define CNAME(x) x
33 #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
34 #endif
35
36 #ifdef __LITTLE_ENDIAN__
37 #define OFS_FLT 0
38 #else
39 #define OFS_FLT 4
40 #endif
41
42 .section .text..SHmedia32,"ax"
43
44 # r2: ffi_prep_args
45 # r3: &ecif
46 # r4: bytes
47 # r5: flags
48 # r6: flags2
49 # r7: rvalue
50 # r8: fn
51
52 # This assumes we are using gas.
53 .align 5
54 ENTRY(ffi_call_SYSV)
55 # Save registers
56 .LFB1:
57 addi.l r15, -48, r15
58 .LCFI0:
59 st.q r15, 40, r32
60 st.q r15, 32, r31
61 st.q r15, 24, r30
62 st.q r15, 16, r29
63 st.q r15, 8, r28
64 st.l r15, 4, r18
65 st.l r15, 0, r14
66 add.l r15, r63, r14
67 .LCFI1:
68 # add r4, r63, r28
69 add r5, r63, r29
70 add r6, r63, r30
71 add r7, r63, r31
72 add r8, r63, r32
73
74 addi r4, (64 + 7), r4
75 andi r4, ~7, r4
76 sub.l r15, r4, r15
77
78 ptabs/l r2, tr0
79 add r15, r63, r2
80 blink tr0, r18
81
82 addi r15, 64, r22
83 movi 0, r0
84 movi 0, r1
85
86 pt/l 1f, tr1
87 bnei/l r29, FFI_TYPE_STRUCT, tr1
88 ld.l r15, 0, r19
89 addi r15, 8, r15
90 addi r0, 1, r0
91 1:
92
93 .L_pass:
94 andi r30, 3, r20
95 shlri r30, 2, r30
96
97 pt/l .L_call_it, tr0
98 pt/l .L_pass_i, tr1
99 pt/l .L_pass_f, tr2
100
101 beqi/l r20, FFI_TYPE_VOID, tr0
102 beqi/l r20, FFI_TYPE_INT, tr1
103 beqi/l r20, FFI_TYPE_FLOAT, tr2
104
105 .L_pass_d:
106 addi r0, 1, r0
107 addi r1, 1, r1
108 andi r1, ~1, r1
109
110 pt/l 3f, tr0
111 movi 12, r20
112 bge/l r1, r20, tr0
113
114 pt/l .L_pop_d, tr1
115 pt/l 2f, tr0
116 blink tr1, r63
117 2:
118 addi.l r15, 8, r15
119 3:
120 pt/l .L_pass, tr0
121 addi r1, 2, r1
122 blink tr0, r63
123
124 .L_pop_d:
125 pt/l .L_pop_d_tbl, tr1
126 gettr tr1, r20
127 shlli r1, 2, r21
128 add r20, r21, r20
129 ptabs/l r20, tr1
130 blink tr1, r63
131
132 .L_pop_d_tbl:
133 fld.d r15, 0, dr0
134 blink tr0, r63
135 fld.d r15, 0, dr2
136 blink tr0, r63
137 fld.d r15, 0, dr4
138 blink tr0, r63
139 fld.d r15, 0, dr6
140 blink tr0, r63
141 fld.d r15, 0, dr8
142 blink tr0, r63
143 fld.d r15, 0, dr10
144 blink tr0, r63
145
146 .L_pass_f:
147 addi r0, 1, r0
148 pt/l 3f, tr0
149 movi 12, r20
150 bge/l r1, r20, tr0
151
152 pt/l .L_pop_f, tr1
153 pt/l 2f, tr0
154 blink tr1, r63
155 2:
156 addi.l r15, 8, r15
157 3:
158 pt/l .L_pass, tr0
159 addi r1, 1, r1
160 blink tr0, r63
161
162 .L_pop_f:
163 pt/l .L_pop_f_tbl, tr1
164 gettr tr1, r20
165 shlli r1, 3, r21
166 add r20, r21, r20
167 ptabs/l r20, tr1
168 blink tr1, r63
169
170 .L_pop_f_tbl:
171 fld.s r15, OFS_FLT, fr0
172 blink tr0, r63
173 fld.s r15, OFS_FLT, fr1
174 blink tr0, r63
175 fld.s r15, OFS_FLT, fr2
176 blink tr0, r63
177 fld.s r15, OFS_FLT, fr3
178 blink tr0, r63
179 fld.s r15, OFS_FLT, fr4
180 blink tr0, r63
181 fld.s r15, OFS_FLT, fr5
182 blink tr0, r63
183 fld.s r15, OFS_FLT, fr6
184 blink tr0, r63
185 fld.s r15, OFS_FLT, fr7
186 blink tr0, r63
187 fld.s r15, OFS_FLT, fr8
188 blink tr0, r63
189 fld.s r15, OFS_FLT, fr9
190 blink tr0, r63
191 fld.s r15, OFS_FLT, fr10
192 blink tr0, r63
193 fld.s r15, OFS_FLT, fr11
194 blink tr0, r63
195
196 .L_pass_i:
197 pt/l 3f, tr0
198 movi 8, r20
199 bge/l r0, r20, tr0
200
201 pt/l .L_pop_i, tr1
202 pt/l 2f, tr0
203 blink tr1, r63
204 2:
205 addi.l r15, 8, r15
206 3:
207 pt/l .L_pass, tr0
208 addi r0, 1, r0
209 blink tr0, r63
210
211 .L_pop_i:
212 pt/l .L_pop_i_tbl, tr1
213 gettr tr1, r20
214 shlli r0, 3, r21
215 add r20, r21, r20
216 ptabs/l r20, tr1
217 blink tr1, r63
218
219 .L_pop_i_tbl:
220 ld.q r15, 0, r2
221 blink tr0, r63
222 ld.q r15, 0, r3
223 blink tr0, r63
224 ld.q r15, 0, r4
225 blink tr0, r63
226 ld.q r15, 0, r5
227 blink tr0, r63
228 ld.q r15, 0, r6
229 blink tr0, r63
230 ld.q r15, 0, r7
231 blink tr0, r63
232 ld.q r15, 0, r8
233 blink tr0, r63
234 ld.q r15, 0, r9
235 blink tr0, r63
236
237 .L_call_it:
238 # call function
239 pt/l 1f, tr1
240 bnei/l r29, FFI_TYPE_STRUCT, tr1
241 add r19, r63, r2
242 1:
243 add r22, r63, r15
244 ptabs/l r32, tr0
245 blink tr0, r18
246
247 pt/l .L_ret_i, tr0
248 pt/l .L_ret_ll, tr1
249 pt/l .L_ret_d, tr2
250 pt/l .L_ret_f, tr3
251 pt/l .L_epilogue, tr4
252
253 beqi/l r29, FFI_TYPE_INT, tr0
254 beqi/l r29, FFI_TYPE_SINT64, tr1
255 beqi/l r29, FFI_TYPE_UINT64, tr1
256 beqi/l r29, FFI_TYPE_DOUBLE, tr2
257 beqi/l r29, FFI_TYPE_FLOAT, tr3
258 blink tr4, r63
259
260 .L_ret_d:
261 fst.d r31, 0, dr0
262 blink tr4, r63
263
264 .L_ret_ll:
265 st.q r31, 0, r2
266 blink tr4, r63
267
268 .L_ret_f:
269 fst.s r31, OFS_FLT, fr0
270 blink tr4, r63
271
272 .L_ret_i:
273 st.l r31, 0, r2
274 # Fall
275
276 .L_epilogue:
277 # Remove the space we pushed for the args
278 add r14, r63, r15
279
280 ld.l r15, 0, r14
281 ld.l r15, 4, r18
282 ld.q r15, 8, r28
283 ld.q r15, 16, r29
284 ld.q r15, 24, r30
285 ld.q r15, 32, r31
286 ld.q r15, 40, r32
287 addi.l r15, 48, r15
288 ptabs r18, tr0
289 blink tr0, r63
290
291 .LFE1:
292 .ffi_call_SYSV_end:
293 .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
294
295 .align 5
296 ENTRY(ffi_closure_SYSV)
297 .LFB2:
298 addi.l r15, -136, r15
299 .LCFI2:
300 st.l r15, 12, r18
301 st.l r15, 8, r14
302 st.l r15, 4, r12
303 add r15, r63, r14
304 .LCFI3:
305 /* Stack layout:
306 ...
307 64 bytes (register parameters)
308 48 bytes (floating register parameters)
309 8 bytes (result)
310 4 bytes (r18)
311 4 bytes (r14)
312 4 bytes (r12)
313 4 bytes (for align)
314 <- new stack pointer
315 */
316 fst.d r14, 24, dr0
317 fst.d r14, 32, dr2
318 fst.d r14, 40, dr4
319 fst.d r14, 48, dr6
320 fst.d r14, 56, dr8
321 fst.d r14, 64, dr10
322 st.q r14, 72, r2
323 st.q r14, 80, r3
324 st.q r14, 88, r4
325 st.q r14, 96, r5
326 st.q r14, 104, r6
327 st.q r14, 112, r7
328 st.q r14, 120, r8
329 st.q r14, 128, r9
330
331 add r1, r63, r2
332 addi r14, 16, r3
333 addi r14, 72, r4
334 addi r14, 24, r5
335 addi r14, 136, r6
336 #ifdef PIC
337 movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
338 shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
339 .LPCS0: ptrel/u r12, tr0
340 movi ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1
341 gettr tr0, r12
342 ldx.l r1, r12, r1
343 ptabs r1, tr0
344 #else
345 pt/l ffi_closure_helper_SYSV, tr0
346 #endif
347 blink tr0, r18
348
349 shlli r2, 1, r1
350 movi (((datalabel .L_table) >> 16) & 65535), r2
351 shori ((datalabel .L_table) & 65535), r2
352 ldx.w r2, r1, r1
353 add r1, r2, r1
354 pt/l .L_case_v, tr1
355 ptabs r1, tr0
356 blink tr0, r63
357
358 .align 2
359 .L_table:
360 .word .L_case_v - datalabel .L_table /* FFI_TYPE_VOID */
361 .word .L_case_i - datalabel .L_table /* FFI_TYPE_INT */
362 .word .L_case_f - datalabel .L_table /* FFI_TYPE_FLOAT */
363 .word .L_case_d - datalabel .L_table /* FFI_TYPE_DOUBLE */
364 .word .L_case_d - datalabel .L_table /* FFI_TYPE_LONGDOUBLE */
365 .word .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */
366 .word .L_case_q - datalabel .L_table /* FFI_TYPE_SINT8 */
367 .word .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */
368 .word .L_case_h - datalabel .L_table /* FFI_TYPE_SINT16 */
369 .word .L_case_i - datalabel .L_table /* FFI_TYPE_UINT32 */
370 .word .L_case_i - datalabel .L_table /* FFI_TYPE_SINT32 */
371 .word .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */
372 .word .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */
373 .word .L_case_v - datalabel .L_table /* FFI_TYPE_STRUCT */
374 .word .L_case_i - datalabel .L_table /* FFI_TYPE_POINTER */
375
376 .align 2
377 .L_case_d:
378 fld.d r14, 16, dr0
379 blink tr1, r63
380 .L_case_f:
381 fld.s r14, 16, fr0
382 blink tr1, r63
383 .L_case_ll:
384 ld.q r14, 16, r2
385 blink tr1, r63
386 .L_case_i:
387 ld.l r14, 16, r2
388 blink tr1, r63
389 .L_case_q:
390 ld.b r14, 16, r2
391 blink tr1, r63
392 .L_case_uq:
393 ld.ub r14, 16, r2
394 blink tr1, r63
395 .L_case_h:
396 ld.w r14, 16, r2
397 blink tr1, r63
398 .L_case_uh:
399 ld.uw r14, 16, r2
400 blink tr1, r63
401 .L_case_v:
402 add.l r14, r63, r15
403 ld.l r15, 4, r12
404 ld.l r15, 8, r14
405 ld.l r15, 12, r18
406 addi.l r15, 136, r15
407 ptabs r18, tr0
408 blink tr0, r63
409
410 .LFE2:
411 .ffi_closure_SYSV_end:
412 .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
413
414 .section ".eh_frame","aw",@progbits
415 __FRAME_BEGIN__:
416 .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
417 .LSCIE1:
418 .4byte 0x0 /* CIE Identifier Tag */
419 .byte 0x1 /* CIE Version */
420 .ascii "zR\0" /* CIE Augmentation */
421 .uleb128 0x1 /* CIE Code Alignment Factor */
422 .sleb128 -4 /* CIE Data Alignment Factor */
423 .byte 0x12 /* CIE RA Column */
424 .uleb128 0x1 /* Augmentation size */
425 .byte 0x1b /* FDE Encoding (pcrel sdata4) */
426 .byte 0xc /* DW_CFA_def_cfa */
427 .uleb128 0xf
428 .uleb128 0x0
429 .align 2
430 .LECIE1:
431 .LSFDE1:
432 .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
433 .LASFDE1:
434 .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__
435 .4byte datalabel .LFB1-. /* FDE initial location */
436 .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */
437 .byte 0x4 /* DW_CFA_advance_loc4 */
438 .4byte datalabel .LCFI0-datalabel .LFB1
439 .byte 0xe /* DW_CFA_def_cfa_offset */
440 .uleb128 0x30
441 .byte 0x4 /* DW_CFA_advance_loc4 */
442 .4byte datalabel .LCFI1-datalabel .LCFI0
443 .byte 0x8e /* DW_CFA_offset, column 0xe */
444 .uleb128 0xc
445 .byte 0x92 /* DW_CFA_offset, column 0x12 */
446 .uleb128 0xb
447 .byte 0x9c /* DW_CFA_offset, column 0x1c */
448 .uleb128 0xa
449 .byte 0x9d /* DW_CFA_offset, column 0x1d */
450 .uleb128 0x8
451 .byte 0x9e /* DW_CFA_offset, column 0x1e */
452 .uleb128 0x6
453 .byte 0x9f /* DW_CFA_offset, column 0x1f */
454 .uleb128 0x4
455 .byte 0xa0 /* DW_CFA_offset, column 0x20 */
456 .uleb128 0x2
457 .byte 0xd /* DW_CFA_def_cfa_register */
458 .uleb128 0xe
459 .align 2
460 .LEFDE1:
461
462 .LSFDE3:
463 .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
464 .LASFDE3:
465 .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__
466 .4byte datalabel .LFB2-. /* FDE initial location */
467 .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */
468 .byte 0x4 /* DW_CFA_advance_loc4 */
469 .4byte datalabel .LCFI2-datalabel .LFB2
470 .byte 0xe /* DW_CFA_def_cfa_offset */
471 .uleb128 0x88
472 .byte 0x4 /* DW_CFA_advance_loc4 */
473 .4byte datalabel .LCFI3-datalabel .LCFI2
474 .byte 0x8c /* DW_CFA_offset, column 0xc */
475 .uleb128 0x21
476 .byte 0x8e /* DW_CFA_offset, column 0xe */
477 .uleb128 0x20
478 .byte 0x92 /* DW_CFA_offset, column 0x12 */
479 .uleb128 0x1f
480 .byte 0xd /* DW_CFA_def_cfa_register */
481 .uleb128 0xe
482 .align 2
483 .LEFDE3: