annotate libffi/src/xtensa/sysv.S @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* -----------------------------------------------------------------------
kono
parents:
diff changeset
2 sysv.S - Copyright (c) 2013 Tensilica, Inc.
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 XTENSA Foreign Function Interface
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 Permission is hereby granted, free of charge, to any person obtaining
kono
parents:
diff changeset
7 a copy of this software and associated documentation files (the
kono
parents:
diff changeset
8 ``Software''), to deal in the Software without restriction, including
kono
parents:
diff changeset
9 without limitation the rights to use, copy, modify, merge, publish,
kono
parents:
diff changeset
10 distribute, sublicense, and/or sell copies of the Software, and to
kono
parents:
diff changeset
11 permit persons to whom the Software is furnished to do so, subject to
kono
parents:
diff changeset
12 the following conditions:
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 The above copyright notice and this permission notice shall be included
kono
parents:
diff changeset
15 in all copies or substantial portions of the Software.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
kono
parents:
diff changeset
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kono
parents:
diff changeset
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
kono
parents:
diff changeset
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
kono
parents:
diff changeset
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
kono
parents:
diff changeset
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kono
parents:
diff changeset
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
kono
parents:
diff changeset
24 DEALINGS IN THE SOFTWARE.
kono
parents:
diff changeset
25 ----------------------------------------------------------------------- */
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #define LIBFFI_ASM
kono
parents:
diff changeset
28 #include <fficonfig.h>
kono
parents:
diff changeset
29 #include <ffi.h>
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 #define ENTRY(name) .text; .globl name; .type name,@function; .align 4; name:
kono
parents:
diff changeset
32 #define END(name) .size name , . - name
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 /* Assert that the table below is in sync with ffi.h. */
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 #if FFI_TYPE_UINT8 != 5 \
kono
parents:
diff changeset
37 || FFI_TYPE_SINT8 != 6 \
kono
parents:
diff changeset
38 || FFI_TYPE_UINT16 != 7 \
kono
parents:
diff changeset
39 || FFI_TYPE_SINT16 != 8 \
kono
parents:
diff changeset
40 || FFI_TYPE_UINT32 != 9 \
kono
parents:
diff changeset
41 || FFI_TYPE_SINT32 != 10 \
kono
parents:
diff changeset
42 || FFI_TYPE_UINT64 != 11
kono
parents:
diff changeset
43 #error "xtensa/sysv.S out of sync with ffi.h"
kono
parents:
diff changeset
44 #endif
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 /* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif)
kono
parents:
diff changeset
48 void *rvalue; a2
kono
parents:
diff changeset
49 unsigned long rbytes; a3
kono
parents:
diff changeset
50 unsigned flags; a4
kono
parents:
diff changeset
51 void (*fnaddr)(); a5
kono
parents:
diff changeset
52 unsigned long bytes; a6
kono
parents:
diff changeset
53 extended_cif* ecif) a7
kono
parents:
diff changeset
54 */
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 ENTRY(ffi_call_SYSV)
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 entry a1, 32 # 32 byte frame for using call8 below
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 mov a10, a7 # a10(->arg0): ecif
kono
parents:
diff changeset
61 sub a11, a1, a6 # a11(->arg1): stack pointer
kono
parents:
diff changeset
62 mov a7, a1 # fp
kono
parents:
diff changeset
63 movsp a1, a11 # set new sp = old_sp - bytes
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 movi a8, ffi_prep_args
kono
parents:
diff changeset
66 callx8 a8 # ffi_prep_args(ecif, stack)
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 # prepare to move stack pointer back up to 6 arguments
kono
parents:
diff changeset
69 # note that 'bytes' is already aligned
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 movi a10, 6*4
kono
parents:
diff changeset
72 sub a11, a6, a10
kono
parents:
diff changeset
73 movgez a6, a10, a11
kono
parents:
diff changeset
74 add a6, a1, a6
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 # we can pass up to 6 arguments in registers
kono
parents:
diff changeset
78 # for simplicity, just load 6 arguments
kono
parents:
diff changeset
79 # (the stack size is at least 32 bytes, so no risk to cross boundaries)
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 l32i a10, a1, 0
kono
parents:
diff changeset
82 l32i a11, a1, 4
kono
parents:
diff changeset
83 l32i a12, a1, 8
kono
parents:
diff changeset
84 l32i a13, a1, 12
kono
parents:
diff changeset
85 l32i a14, a1, 16
kono
parents:
diff changeset
86 l32i a15, a1, 20
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 # move stack pointer
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 movsp a1, a6
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 callx8 a5 # (*fn)(args...)
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 # Handle return value(s)
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 beqz a2, .Lexit
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 movi a5, FFI_TYPE_STRUCT
kono
parents:
diff changeset
99 bne a4, a5, .Lstore
kono
parents:
diff changeset
100 movi a5, 16
kono
parents:
diff changeset
101 blt a5, a3, .Lexit
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 s32i a10, a2, 0
kono
parents:
diff changeset
104 blti a3, 5, .Lexit
kono
parents:
diff changeset
105 addi a3, a3, -1
kono
parents:
diff changeset
106 s32i a11, a2, 4
kono
parents:
diff changeset
107 blti a3, 8, .Lexit
kono
parents:
diff changeset
108 s32i a12, a2, 8
kono
parents:
diff changeset
109 blti a3, 12, .Lexit
kono
parents:
diff changeset
110 s32i a13, a2, 12
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 .Lexit: retw
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 .Lstore:
kono
parents:
diff changeset
115 addi a4, a4, -FFI_TYPE_UINT8
kono
parents:
diff changeset
116 bgei a4, 7, .Lexit # should never happen
kono
parents:
diff changeset
117 movi a6, store_calls
kono
parents:
diff changeset
118 add a4, a4, a4
kono
parents:
diff changeset
119 addx4 a6, a4, a6 # store_table + idx * 8
kono
parents:
diff changeset
120 jx a6
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 .align 8
kono
parents:
diff changeset
123 store_calls:
kono
parents:
diff changeset
124 # UINT8
kono
parents:
diff changeset
125 s8i a10, a2, 0
kono
parents:
diff changeset
126 retw
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 # SINT8
kono
parents:
diff changeset
129 .align 8
kono
parents:
diff changeset
130 s8i a10, a2, 0
kono
parents:
diff changeset
131 retw
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 # UINT16
kono
parents:
diff changeset
134 .align 8
kono
parents:
diff changeset
135 s16i a10, a2, 0
kono
parents:
diff changeset
136 retw
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 # SINT16
kono
parents:
diff changeset
139 .align 8
kono
parents:
diff changeset
140 s16i a10, a2, 0
kono
parents:
diff changeset
141 retw
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 # UINT32
kono
parents:
diff changeset
144 .align 8
kono
parents:
diff changeset
145 s32i a10, a2, 0
kono
parents:
diff changeset
146 retw
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 # SINT32
kono
parents:
diff changeset
149 .align 8
kono
parents:
diff changeset
150 s32i a10, a2, 0
kono
parents:
diff changeset
151 retw
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 # UINT64
kono
parents:
diff changeset
154 .align 8
kono
parents:
diff changeset
155 s32i a10, a2, 0
kono
parents:
diff changeset
156 s32i a11, a2, 4
kono
parents:
diff changeset
157 retw
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 END(ffi_call_SYSV)
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 /*
kono
parents:
diff changeset
163 * void ffi_cacheflush (unsigned long start, unsigned long end)
kono
parents:
diff changeset
164 */
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 #define EXTRA_ARGS_SIZE 24
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 ENTRY(ffi_cacheflush)
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 entry a1, 16
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 1: dhwbi a2, 0
kono
parents:
diff changeset
173 ihi a2, 0
kono
parents:
diff changeset
174 addi a2, a2, 4
kono
parents:
diff changeset
175 blt a2, a3, 1b
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 retw
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 END(ffi_cacheflush)
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 /* ffi_trampoline is copied to the stack */
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 ENTRY(ffi_trampoline)
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 entry a1, 16 + (FFI_REGISTER_NARGS * 4) + (4 * 4) # [ 0]
kono
parents:
diff changeset
186 j 2f # [ 3]
kono
parents:
diff changeset
187 .align 4 # [ 6]
kono
parents:
diff changeset
188 1: .long 0 # [ 8]
kono
parents:
diff changeset
189 2: l32r a15, 1b # [12]
kono
parents:
diff changeset
190 _mov a14, a0 # [15]
kono
parents:
diff changeset
191 callx0 a15 # [18]
kono
parents:
diff changeset
192 # [21]
kono
parents:
diff changeset
193 END(ffi_trampoline)
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 /*
kono
parents:
diff changeset
196 * ffi_closure()
kono
parents:
diff changeset
197 *
kono
parents:
diff changeset
198 * a0: closure + 21
kono
parents:
diff changeset
199 * a14: return address (a0)
kono
parents:
diff changeset
200 */
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 ENTRY(ffi_closure_SYSV)
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 /* intentionally omitting entry here */
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 # restore return address (a0) and move pointer to closure to a10
kono
parents:
diff changeset
207 addi a10, a0, -21
kono
parents:
diff changeset
208 mov a0, a14
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 # allow up to 4 arguments as return values
kono
parents:
diff changeset
211 addi a11, a1, 4 * 4
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 # save up to 6 arguments to stack (allocated by entry below)
kono
parents:
diff changeset
214 s32i a2, a11, 0
kono
parents:
diff changeset
215 s32i a3, a11, 4
kono
parents:
diff changeset
216 s32i a4, a11, 8
kono
parents:
diff changeset
217 s32i a5, a11, 12
kono
parents:
diff changeset
218 s32i a6, a11, 16
kono
parents:
diff changeset
219 s32i a7, a11, 20
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 movi a8, ffi_closure_SYSV_inner
kono
parents:
diff changeset
222 mov a12, a1
kono
parents:
diff changeset
223 callx8 a8 # .._inner(*closure, **avalue, *rvalue)
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 # load up to four return arguments
kono
parents:
diff changeset
226 l32i a2, a1, 0
kono
parents:
diff changeset
227 l32i a3, a1, 4
kono
parents:
diff changeset
228 l32i a4, a1, 8
kono
parents:
diff changeset
229 l32i a5, a1, 12
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 # (sign-)extend return value
kono
parents:
diff changeset
232 movi a11, FFI_TYPE_UINT8
kono
parents:
diff changeset
233 bne a10, a11, 1f
kono
parents:
diff changeset
234 extui a2, a2, 0, 8
kono
parents:
diff changeset
235 retw
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 1: movi a11, FFI_TYPE_SINT8
kono
parents:
diff changeset
238 bne a10, a11, 1f
kono
parents:
diff changeset
239 sext a2, a2, 7
kono
parents:
diff changeset
240 retw
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 1: movi a11, FFI_TYPE_UINT16
kono
parents:
diff changeset
243 bne a10, a11, 1f
kono
parents:
diff changeset
244 extui a2, a2, 0, 16
kono
parents:
diff changeset
245 retw
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 1: movi a11, FFI_TYPE_SINT16
kono
parents:
diff changeset
248 bne a10, a11, 1f
kono
parents:
diff changeset
249 sext a2, a2, 15
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 1: retw
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 END(ffi_closure_SYSV)