111
|
1 /* -----------------------------------------------------------------------
|
|
2 arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com)
|
|
3
|
|
4 ARCompact 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 RENESAS TECHNOLOGY 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 <fficonfig.h>
|
|
28 #include <ffi.h>
|
|
29 #ifdef HAVE_MACHINE_ASM_H
|
|
30 #include <machine/asm.h>
|
|
31 #else
|
|
32 #define CNAME(x) x
|
|
33 #define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x):
|
|
34 #endif
|
|
35
|
|
36 .text
|
|
37
|
|
38 /* R0: ffi_prep_args */
|
|
39 /* R1: &ecif */
|
|
40 /* R2: cif->bytes */
|
|
41 /* R3: fig->flags */
|
|
42 /* R4: ecif.rvalue */
|
|
43 /* R5: fn */
|
|
44 ENTRY(ffi_call_ARCompact)
|
|
45 /* Save registers. */
|
|
46 st.a fp, [sp, -4] /* fp + 20, fp */
|
|
47 push_s blink /* fp + 16, blink */
|
|
48 st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */
|
|
49 push_s r3 /* fp + 8, fig->flags */
|
|
50 st.a r5, [sp, -4] /* fp + 4, fn */
|
|
51 push_s r2 /* fp + 0, cif->bytes */
|
|
52 mov fp, sp
|
|
53
|
|
54 /* Make room for all of the new args. */
|
|
55 sub sp, sp, r2
|
|
56
|
|
57 /* Place all of the ffi_prep_args in position. */
|
|
58 /* ffi_prep_args(char *stack, extended_cif *ecif) */
|
|
59 /* R1 already set. */
|
|
60
|
|
61 /* And call. */
|
|
62 jl_s.d [r0]
|
|
63 mov_s r0, sp
|
|
64
|
|
65 ld.ab r12, [fp, 4] /* cif->bytes */
|
|
66 ld.ab r11, [fp, 4] /* fn */
|
|
67
|
|
68 /* Move first 8 parameters in registers... */
|
|
69 ld_s r0, [sp]
|
|
70 ld_s r1, [sp, 4]
|
|
71 ld_s r2, [sp, 8]
|
|
72 ld_s r3, [sp, 12]
|
|
73 ld r4, [sp, 16]
|
|
74 ld r5, [sp, 20]
|
|
75 ld r6, [sp, 24]
|
|
76 ld r7, [sp, 28]
|
|
77
|
|
78 /* ...and adjust the stack. */
|
|
79 min r12, r12, 32
|
|
80
|
|
81 /* Call the function. */
|
|
82 jl.d [r11]
|
|
83 add sp, sp, r12
|
|
84
|
|
85 mov sp, fp
|
|
86 pop_s r3 /* fig->flags, return type */
|
|
87 pop_s r2 /* ecif.rvalue, pointer for return value */
|
|
88
|
|
89 /* If the return value pointer is NULL, assume no return value. */
|
|
90 breq.d r2, 0, epilogue
|
|
91 pop_s blink
|
|
92
|
|
93 /* Return INT. */
|
|
94 brne r3, FFI_TYPE_INT, return_double
|
|
95 b.d epilogue
|
|
96 st_s r0, [r2]
|
|
97
|
|
98 return_double:
|
|
99 brne r3, FFI_TYPE_DOUBLE, epilogue
|
|
100 st_s r0, [r2]
|
|
101 st_s r1, [r2,4]
|
|
102
|
|
103 epilogue:
|
|
104 j_s.d [blink]
|
|
105 ld.ab fp, [sp, 4]
|
|
106
|
|
107 ENTRY(ffi_closure_ARCompact)
|
|
108 st.a r0, [sp, -32]
|
|
109 st_s r1, [sp, 4]
|
|
110 st_s r2, [sp, 8]
|
|
111 st_s r3, [sp, 12]
|
|
112 st r4, [sp, 16]
|
|
113 st r5, [sp, 20]
|
|
114 st r6, [sp, 24]
|
|
115 st r7, [sp, 28]
|
|
116
|
|
117 /* pointer to arguments */
|
|
118 mov_s r2, sp
|
|
119
|
|
120 /* return value goes here */
|
|
121 sub sp, sp, 8
|
|
122 mov_s r1, sp
|
|
123
|
|
124 push_s blink
|
|
125
|
|
126 bl.d ffi_closure_inner_ARCompact
|
|
127 mov_s r0, r8 /* codeloc, set by trampoline */
|
|
128
|
|
129 pop_s blink
|
|
130
|
|
131 /* set return value to r1:r0 */
|
|
132 pop_s r0
|
|
133 pop_s r1
|
|
134 j_s.d [blink]
|
|
135 add_s sp, sp, 32
|