source: trunk/gcc/libffi/src/sh/sysv.S

Last change on this file was 1389, checked in by bird, 21 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 9.7 KB
Line 
1/* -----------------------------------------------------------------------
2 sysv.S - Copyright (c) 2002 Kaz Kojima
3
4 SuperH 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#if defined(__HITACHI__)
37#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
38#else
39#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
40#endif
41
42.text
43
44 # r4: ffi_prep_args
45 # r5: &ecif
46 # r6: bytes
47 # r7: flags
48 # sp+0: rvalue
49 # sp+4: fn
50
51 # This assumes we are using gas.
52ENTRY(ffi_call_SYSV)
53#if defined(__SH4__)
54 # Save registers
55 mov.l r8,@-r15
56 mov.l r9,@-r15
57 mov.l r10,@-r15
58 mov.l r12,@-r15
59 mov.l r14,@-r15
60 sts.l pr,@-r15
61 mov r15,r14
62
63 mov r6,r8
64 mov r7,r9
65
66 sub r6,r15
67 add #-16,r15
68 mov #~7,r0
69 and r0,r15
70
71 mov r4,r0
72 jsr @r0
73 mov r15,r4
74
75 mov r9,r1
76 shlr8 r9
77 shlr8 r9
78 shlr8 r9
79
80 mov #FFI_TYPE_STRUCT,r2
81 cmp/eq r2,r9
82 bf 1f
83#if STRUCT_VALUE_ADDRESS_WITH_ARG
84 mov.l @r15+,r4
85 bra 2f
86 mov #5,r2
87#else
88 mov.l @r15+,r10
89#endif
901:
91 mov #4,r2
922:
93 mov #4,r3
94
95L_pass:
96 cmp/pl r8
97 bf L_call_it
98
99 mov r1,r0
100 and #3,r0
101
102L_pass_d:
103 cmp/eq #FFI_TYPE_DOUBLE,r0
104 bf L_pass_f
105
106 mov r3,r0
107 and #1,r0
108 tst r0,r0
109 bt 1f
110 add #1,r3
1111:
112 mov r15,r0
113 and #7,r0
114 tst r0,r0
115 bt 2f
116 add #4,r15
1172:
118 mov #12,r0
119 cmp/hs r0,r3
120 bt/s 3f
121 shlr2 r1
122 bsr L_pop_d
123 nop
1243:
125 add #2,r3
126 bra L_pass
127 add #-8,r8
128
129L_pop_d:
130 mov r3,r0
131 add r0,r0
132 add r3,r0
133 add #-12,r0
134 braf r0
135 nop
136#ifdef __LITTLE_ENDIAN__
137 fmov.s @r15+,fr5
138 rts
139 fmov.s @r15+,fr4
140 fmov.s @r15+,fr7
141 rts
142 fmov.s @r15+,fr6
143 fmov.s @r15+,fr9
144 rts
145 fmov.s @r15+,fr8
146 fmov.s @r15+,fr11
147 rts
148 fmov.s @r15+,fr10
149#else
150 fmov.s @r15+,fr4
151 rts
152 fmov.s @r15+,fr5
153 fmov.s @r15+,fr6
154 rts
155 fmov.s @r15+,fr7
156 fmov.s @r15+,fr8
157 rts
158 fmov.s @r15+,fr9
159 fmov.s @r15+,fr10
160 rts
161 fmov.s @r15+,fr11
162#endif
163
164L_pass_f:
165 cmp/eq #FFI_TYPE_FLOAT,r0
166 bf L_pass_i
167
168 mov #12,r0
169 cmp/hs r0,r3
170 bt/s 2f
171 shlr2 r1
172 bsr L_pop_f
173 nop
1742:
175 add #1,r3
176 bra L_pass
177 add #-4,r8
178
179L_pop_f:
180 mov r3,r0
181 shll2 r0
182 add #-16,r0
183 braf r0
184 nop
185#ifdef __LITTLE_ENDIAN__
186 rts
187 fmov.s @r15+,fr5
188 rts
189 fmov.s @r15+,fr4
190 rts
191 fmov.s @r15+,fr7
192 rts
193 fmov.s @r15+,fr6
194 rts
195 fmov.s @r15+,fr9
196 rts
197 fmov.s @r15+,fr8
198 rts
199 fmov.s @r15+,fr11
200 rts
201 fmov.s @r15+,fr10
202#else
203 rts
204 fmov.s @r15+,fr4
205 rts
206 fmov.s @r15+,fr5
207 rts
208 fmov.s @r15+,fr6
209 rts
210 fmov.s @r15+,fr7
211 rts
212 fmov.s @r15+,fr8
213 rts
214 fmov.s @r15+,fr9
215 rts
216 fmov.s @r15+,fr10
217 rts
218 fmov.s @r15+,fr11
219#endif
220
221L_pass_i:
222 cmp/eq #FFI_TYPE_INT,r0
223 bf L_call_it
224
225 mov #8,r0
226 cmp/hs r0,r2
227 bt/s 2f
228 shlr2 r1
229 bsr L_pop_i
230 nop
2312:
232 add #1,r2
233 bra L_pass
234 add #-4,r8
235
236L_pop_i:
237 mov r2,r0
238 shll2 r0
239 add #-16,r0
240 braf r0
241 nop
242 rts
243 mov.l @r15+,r4
244 rts
245 mov.l @r15+,r5
246 rts
247 mov.l @r15+,r6
248 rts
249 mov.l @r15+,r7
250
251L_call_it:
252 # call function
253#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
254 mov r10, r2
255#endif
256 mov.l @(28,r14),r1
257 jsr @r1
258 nop
259
260L_ret_d:
261 mov #FFI_TYPE_DOUBLE,r2
262 cmp/eq r2,r9
263 bf L_ret_ll
264
265 mov.l @(24,r14),r1
266#ifdef __LITTLE_ENDIAN__
267 fmov.s fr1,@r1
268 add #4,r1
269 bra L_epilogue
270 fmov.s fr0,@r1
271#else
272 fmov.s fr0,@r1
273 add #4,r1
274 bra L_epilogue
275 fmov.s fr1,@r1
276#endif
277
278L_ret_ll:
279 mov #FFI_TYPE_SINT64,r2
280 cmp/eq r2,r9
281 bt/s 1f
282 mov #FFI_TYPE_UINT64,r2
283 cmp/eq r2,r9
284 bf L_ret_f
285
2861:
287 mov.l @(24,r14),r2
288 mov.l r0,@r2
289 bra L_epilogue
290 mov.l r1,@(4,r2)
291
292L_ret_f:
293 mov #FFI_TYPE_FLOAT,r2
294 cmp/eq r2,r9
295 bf L_ret_i
296
297 mov.l @(24,r14),r1
298 bra L_epilogue
299 fmov.s fr0,@r1
300
301L_ret_i:
302 mov #FFI_TYPE_INT,r2
303 cmp/eq r2,r9
304 bf L_epilogue
305
306 mov.l @(24,r14),r1
307 bra L_epilogue
308 mov.l r0,@r1
309
310L_epilogue:
311 # Remove the space we pushed for the args
312 mov r14,r15
313
314 lds.l @r15+,pr
315 mov.l @r15+,r14
316 mov.l @r15+,r12
317 mov.l @r15+,r10
318 mov.l @r15+,r9
319 rts
320 mov.l @r15+,r8
321#else
322 # Save registers
323 mov.l r8,@-r15
324 mov.l r9,@-r15
325 mov.l r10,@-r15
326 mov.l r12,@-r15
327 mov.l r14,@-r15
328 sts.l pr,@-r15
329 mov r15,r14
330
331 mov r6,r8
332 mov r7,r9
333
334 sub r6,r15
335 add #-16,r15
336 mov #~7,r0
337 and r0,r15
338
339 mov r4,r0
340 jsr @r0
341 mov r15,r4
342
343 mov r9,r3
344 shlr8 r9
345 shlr8 r9
346 shlr8 r9
347
348 mov #FFI_TYPE_STRUCT,r2
349 cmp/eq r2,r9
350 bf 1f
351#if STRUCT_VALUE_ADDRESS_WITH_ARG
352 mov.l @r15+,r4
353 bra 2f
354 mov #5,r2
355#else
356 mov.l @r15+,r10
357#endif
3581:
359 mov #4,r2
3602:
361
362L_pass:
363 cmp/pl r8
364 bf L_call_it
365
366 mov r3,r0
367 and #3,r0
368
369L_pass_d:
370 cmp/eq #FFI_TYPE_DOUBLE,r0
371 bf L_pass_i
372
373 mov r15,r0
374 and #7,r0
375 tst r0,r0
376 bt 1f
377 add #4,r15
3781:
379 mov #8,r0
380 cmp/hs r0,r2
381 bt/s 2f
382 shlr2 r3
383 bsr L_pop_d
384 nop
3852:
386 add #2,r2
387 bra L_pass
388 add #-8,r8
389
390L_pop_d:
391 mov r2,r0
392 add r0,r0
393 add r2,r0
394 add #-12,r0
395 add r0,r0
396 braf r0
397 nop
398 mov.l @r15+,r4
399 rts
400 mov.l @r15+,r5
401 mov.l @r15+,r5
402 rts
403 mov.l @r15+,r6
404 mov.l @r15+,r6
405 rts
406 mov.l @r15+,r7
407 rts
408 mov.l @r15+,r7
409
410L_pass_i:
411 mov #8,r0
412 cmp/hs r0,r2
413 bt/s 2f
414 shlr2 r3
415 bsr L_pop_i
416 nop
4172:
418 add #1,r2
419 bra L_pass
420 add #-4,r8
421
422L_pop_i:
423 mov r2,r0
424 shll2 r0
425 add #-16,r0
426 braf r0
427 nop
428 rts
429 mov.l @r15+,r4
430 rts
431 mov.l @r15+,r5
432 rts
433 mov.l @r15+,r6
434 rts
435 mov.l @r15+,r7
436
437L_call_it:
438 # call function
439#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
440 mov r10, r2
441#endif
442 mov.l @(28,r14),r1
443 jsr @r1
444 nop
445
446L_ret_d:
447 mov #FFI_TYPE_DOUBLE,r2
448 cmp/eq r2,r9
449 bf L_ret_ll
450
451 mov.l @(24,r14),r2
452 mov.l r0,@r2
453 bra L_epilogue
454 mov.l r1,@(4,r2)
455
456L_ret_ll:
457 mov #FFI_TYPE_SINT64,r2
458 cmp/eq r2,r9
459 bt/s 1f
460 mov #FFI_TYPE_UINT64,r2
461 cmp/eq r2,r9
462 bf L_ret_i
463
4641:
465 mov.l @(24,r14),r2
466 mov.l r0,@r2
467 bra L_epilogue
468 mov.l r1,@(4,r2)
469
470L_ret_i:
471 mov #FFI_TYPE_FLOAT,r2
472 cmp/eq r2,r9
473 bt 1f
474 mov #FFI_TYPE_INT,r2
475 cmp/eq r2,r9
476 bf L_epilogue
4771:
478 mov.l @(24,r14),r1
479 bra L_epilogue
480 mov.l r0,@r1
481
482L_epilogue:
483 # Remove the space we pushed for the args
484 mov r14,r15
485
486 lds.l @r15+,pr
487 mov.l @r15+,r14
488 mov.l @r15+,r12
489 mov.l @r15+,r10
490 mov.l @r15+,r9
491 rts
492 mov.l @r15+,r8
493#endif
494
495.ffi_call_SYSV_end:
496 .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
497
498.globl ffi_closure_helper_SYSV
499
500ENTRY(ffi_closure_SYSV)
501 mov.l r14,@-r15
502 sts.l pr,@-r15
503
504 /* Stack layout:
505 ...
506 32 bytes (floating register parameters, SH-4 only)
507 16 bytes (register parameters)
508 4 bytes (result)
509 4 bytes (5th arg)
510 <- new stack pointer
511 */
512#if defined(__SH4__)
513 add #-56,r15
514#else
515 add #-24,r15
516#endif
517 mov r15,r14
518
519 mov r14,r1
520 add #24,r1
521 mov.l r7,@-r1
522 mov.l r6,@-r1
523 mov.l r5,@-r1
524 mov.l r4,@-r1
525 mov r1,r6
526
527#if defined(__SH4__)
528 mov r14,r1
529 add #56,r1
530#ifdef __LITTLE_ENDIAN__
531 fmov.s fr10,@-r1
532 fmov.s fr11,@-r1
533 fmov.s fr8,@-r1
534 fmov.s fr9,@-r1
535 fmov.s fr6,@-r1
536 fmov.s fr7,@-r1
537 fmov.s fr4,@-r1
538 fmov.s fr5,@-r1
539#else
540 fmov.s fr11,@-r1
541 fmov.s fr10,@-r1
542 fmov.s fr9,@-r1
543 fmov.s fr8,@-r1
544 fmov.s fr7,@-r1
545 fmov.s fr6,@-r1
546 fmov.s fr5,@-r1
547 fmov.s fr4,@-r1
548#endif
549 mov r1,r7
550#endif
551
552 mov r14,r1
553 add #4,r1
554 mov r1,r5
555
556 mov r14,r1
557#if defined(__SH4__)
558 add #64,r1
559#else
560 add #32,r1
561#endif
562 mov.l r1,@r14
563
564 mov.l L_helper,r0
565 jsr @r0
566 mov r3,r4
567
568 shll r0
569 mov r0,r1
570 mova L_table,r0
571 add r1,r0
572 mov.w @r0,r0
573 mov r14,r2
574 braf r0
575 add #4,r2
5760:
577 .align 2
578L_helper:
579 .long ffi_closure_helper_SYSV
580L_table:
581 .short L_case_v - 0b /* FFI_TYPE_VOID */
582 .short L_case_i - 0b /* FFI_TYPE_INT */
583#if defined(__SH4__)
584 .short L_case_f - 0b /* FFI_TYPE_FLOAT */
585 .short L_case_d - 0b /* FFI_TYPE_DOUBLE */
586 .short L_case_d - 0b /* FFI_TYPE_LONGDOUBLE */
587#else
588 .short L_case_i - 0b /* FFI_TYPE_FLOAT */
589 .short L_case_ll - 0b /* FFI_TYPE_DOUBLE */
590 .short L_case_ll - 0b /* FFI_TYPE_LONGDOUBLE */
591#endif
592 .short L_case_uq - 0b /* FFI_TYPE_UINT8 */
593 .short L_case_q - 0b /* FFI_TYPE_SINT8 */
594 .short L_case_uh - 0b /* FFI_TYPE_UINT16 */
595 .short L_case_h - 0b /* FFI_TYPE_SINT16 */
596 .short L_case_i - 0b /* FFI_TYPE_UINT32 */
597 .short L_case_i - 0b /* FFI_TYPE_SINT32 */
598 .short L_case_ll - 0b /* FFI_TYPE_UINT64 */
599 .short L_case_ll - 0b /* FFI_TYPE_SINT64 */
600 .short L_case_v - 0b /* FFI_TYPE_STRUCT */
601 .short L_case_i - 0b /* FFI_TYPE_POINTER */
602
603#if defined(__SH4__)
604L_case_d:
605#ifdef __LITTLE_ENDIAN__
606 fmov.s @r2+,fr1
607 bra L_case_v
608 fmov.s @r2,fr0
609#else
610 fmov.s @r2+,fr0
611 bra L_case_v
612 fmov.s @r2,fr1
613#endif
614
615L_case_f:
616 bra L_case_v
617 fmov.s @r2,fr0
618#endif
619
620L_case_ll:
621 mov.l @r2+,r0
622 bra L_case_v
623 mov.l @r2,r1
624
625L_case_i:
626 bra L_case_v
627 mov.l @r2,r0
628
629L_case_q:
630#ifdef __LITTLE_ENDIAN__
631#else
632 add #3,r2
633#endif
634 bra L_case_v
635 mov.b @r2,r0
636
637L_case_uq:
638#ifdef __LITTLE_ENDIAN__
639#else
640 add #3,r2
641#endif
642 mov.b @r2,r0
643 bra L_case_v
644 extu.b r0,r0
645
646L_case_h:
647#ifdef __LITTLE_ENDIAN__
648#else
649 add #2,r2
650#endif
651 bra L_case_v
652 mov.w @r2,r0
653
654L_case_uh:
655#ifdef __LITTLE_ENDIAN__
656#else
657 add #2,r2
658#endif
659 mov.w @r2,r0
660 extu.w r0,r0
661 /* fall through */
662
663L_case_v:
664#if defined(__SH4__)
665 add #56,r15
666#else
667 add #24,r15
668#endif
669 lds.l @r15+,pr
670 rts
671 mov.l @r15+,r14
672
673.ffi_closure_SYSV_end:
674 .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
Note: See TracBrowser for help on using the repository browser.