Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(116249)

Side by Side Diff: Modules/_ctypes/libffi_ios/arm/sysv_armv7.S

Issue 23670: Modifications to support iOS as a development platform
Patch Set: Created 3 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #ifdef __arm__
2
3 /* -----------------------------------------------------------------------
4 sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
5 Copyright (c) 2011 Plausible Labs Cooperative, Inc.
6
7 ARM Foreign Function Interface
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 ``Software''), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 DEALINGS IN THE SOFTWARE.
28 ----------------------------------------------------------------------- */
29
30 #define LIBFFI_ASM
31 #include <fficonfig.h>
32 #include <ffi.h>
33 #include <ffi_cfi.h>
34 #include "internal.h"
35
36 /* GCC 4.8 provides __ARM_ARCH; construct it otherwise. */
37 #ifndef __ARM_ARCH
38 # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
39 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
40 || defined(__ARM_ARCH_7EM__)
41 # define __ARM_ARCH 7
42 # elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
43 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
44 || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
45 || defined(__ARM_ARCH_6M__)
46 # define __ARM_ARCH 6
47 # elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
48 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
49 || defined(__ARM_ARCH_5TEJ__)
50 # define __ARM_ARCH 5
51 # else
52 # define __ARM_ARCH 4
53 # endif
54 #endif
55
56 /* Conditionally compile unwinder directives. */
57 #ifdef __ARM_EABI__
58 # define UNWIND(...) __VA_ARGS__
59 #else
60 # define UNWIND(...)
61 #endif
62
63 #if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)
64 .cfi_sections .debug_frame
65 #endif
66
67 #define CONCAT(a, b) CONCAT2(a, b)
68 #define CONCAT2(a, b) a ## b
69
70 #ifdef __USER_LABEL_PREFIX__
71 # define CNAME(X) CONCAT (__USER_LABEL_PREFIX__, X)
72 #else
73 # define CNAME(X) X
74 #endif
75 #ifdef __ELF__
76 # define SIZE(X) .size CNAME(X), . - CNAME(X)
77 # define TYPE(X, Y) .type CNAME(X), Y
78 #else
79 # define SIZE(X)
80 # define TYPE(X, Y)
81 #endif
82
83 #define ARM_FUNC_START_LOCAL(name) \
84 .align 3; \
85 TYPE(CNAME(name), %function); \
86 CNAME(name):
87
88 #define ARM_FUNC_START(name) \
89 .globl CNAME(name); \
90 FFI_HIDDEN(CNAME(name)); \
91 ARM_FUNC_START_LOCAL(name)
92
93 #define ARM_FUNC_END(name) \
94 SIZE(name)
95
96 /* Aid in defining a jump table with 8 bytes between entries. */
97 /* ??? The clang assembler doesn't handle .if with symbolic expressions. */
98 #ifdef __clang__
99 # define E(index)
100 #else
101 # define E(index) \
102 .if . - 0b - 8*index; \
103 .error "type table out of sync"; \
104 .endif
105 #endif
106
107 .text
108 .syntax unified
109 .arm
110
111 #ifndef __clang__
112 /* We require interworking on LDM, which implies ARMv5T,
113 which implies the existance of BLX. */
114 .arch armv5t
115 #endif
116
117 /* Note that we use STC and LDC to encode VFP instructions,
118 so that we do not need ".fpu vfp", nor get that added to
119 the object file attributes. These will not be executed
120 unless the FFI_VFP abi is used. */
121
122 @ r0: stack
123 @ r1: frame
124 @ r2: fn
125 @ r3: vfp_used
126
127 ARM_FUNC_START(ffi_call_VFP)
128 UNWIND(.fnstart)
129 cfi_startproc
130
131 cmp r3, #3 @ load only d0 if possible
132 #ifdef __clang__
133 vldrle d0, [sp]
134 vldmgt sp, {d0-d7}
135 #else
136 ldcle p11, cr0, [r0] @ vldrle d0, [sp]
137 ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7}
138 #endif
139 add r0, r0, #64 @ discard the vfp register args
140 /* FALLTHRU */
141 ARM_FUNC_END(ffi_call_VFP)
142
143 ARM_FUNC_START(ffi_call_SYSV)
144 stm r1, {fp, lr}
145 mov fp, r1
146
147 @ This is a bit of a lie wrt the origin of the unwind info, but
148 @ now we've got the usual frame pointer and two saved registers.
149 UNWIND(.save {fp,lr})
150 UNWIND(.setfp fp, sp)
151 cfi_def_cfa(fp, 8)
152 cfi_rel_offset(fp, 0)
153 cfi_rel_offset(lr, 4)
154
155 mov sp, r0 @ install the stack pointer
156 mov lr, r2 @ move the fn pointer out of the way
157 ldr ip, [fp, #16] @ install the static chain
158 ldmia sp!, {r0-r3} @ move first 4 parameters in registers.
159 blx lr @ call fn
160
161 @ Load r2 with the pointer to storage for the return value
162 @ Load r3 with the return type code
163 ldr r2, [fp, #8]
164 ldr r3, [fp, #12]
165
166 @ Deallocate the stack with the arguments.
167 mov sp, fp
168 cfi_def_cfa_register(sp)
169
170 @ Store values stored in registers.
171 .align 3
172 add pc, pc, r3, lsl #3
173 nop
174 0:
175 E(ARM_TYPE_VFP_S)
176 #ifdef __clang__
177 vstr s0, [r2]
178 #else
179 stc p10, cr0, [r2] @ vstr s0, [r2]
180 #endif
181 pop {fp,pc}
182 E(ARM_TYPE_VFP_D)
183 #ifdef __clang__
184 vstr d0, [r2]
185 #else
186 stc p11, cr0, [r2] @ vstr d0, [r2]
187 #endif
188 pop {fp,pc}
189 E(ARM_TYPE_VFP_N)
190 #ifdef __clang__
191 vstm r2, {d0-d3}
192 #else
193 stc p11, cr0, [r2], {8} @ vstm r2, {d0-d3}
194 #endif
195 pop {fp,pc}
196 E(ARM_TYPE_INT64)
197 str r1, [r2, #4]
198 nop
199 E(ARM_TYPE_INT)
200 str r0, [r2]
201 pop {fp,pc}
202 E(ARM_TYPE_VOID)
203 pop {fp,pc}
204 nop
205 E(ARM_TYPE_STRUCT)
206 pop {fp,pc}
207
208 cfi_endproc
209 UNWIND(.fnend)
210 ARM_FUNC_END(ffi_call_SYSV)
211
212
213 /*
214 int ffi_closure_inner_* (cif, fun, user_data, frame)
215 */
216
217 ARM_FUNC_START(ffi_go_closure_SYSV)
218 cfi_startproc
219 stmdb sp!, {r0-r3} @ save argument regs
220 cfi_adjust_cfa_offset(16)
221 ldr r0, [ip, #4] @ load cif
222 ldr r1, [ip, #8] @ load fun
223 mov r2, ip @ load user_data
224 b 0f
225 cfi_endproc
226 ARM_FUNC_END(ffi_go_closure_SYSV)
227
228 ARM_FUNC_START(ffi_closure_SYSV)
229 UNWIND(.fnstart)
230 cfi_startproc
231 stmdb sp!, {r0-r3} @ save argument regs
232 cfi_adjust_cfa_offset(16)
233
234 #if FFI_EXEC_TRAMPOLINE_TABLE
235 ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
236 #endif
237 ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
238 ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
239 ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
240 0:
241 add ip, sp, #16 @ compute entry sp
242 sub sp, sp, #64+32 @ allocate frame
243 cfi_adjust_cfa_offset(64+32)
244 stmdb sp!, {ip,lr}
245
246 /* Remember that EABI unwind info only applies at call sites.
247 We need do nothing except note the save of the stack pointer
248 and the link registers. */
249 UNWIND(.save {sp,lr})
250 cfi_adjust_cfa_offset(8)
251 cfi_rel_offset(lr, 4)
252
253 add r3, sp, #8 @ load frame
254 bl CNAME(ffi_closure_inner_SYSV)
255
256 @ Load values returned in registers.
257 add r2, sp, #8+64 @ load result
258 adr r3, CNAME(ffi_closure_ret)
259 add pc, r3, r0, lsl #3
260 cfi_endproc
261 UNWIND(.fnend)
262 ARM_FUNC_END(ffi_closure_SYSV)
263
264 ARM_FUNC_START(ffi_go_closure_VFP)
265 cfi_startproc
266 stmdb sp!, {r0-r3} @ save argument regs
267 cfi_adjust_cfa_offset(16)
268 ldr r0, [ip, #4] @ load cif
269 ldr r1, [ip, #8] @ load fun
270 mov r2, ip @ load user_data
271 b 0f
272 cfi_endproc
273 ARM_FUNC_END(ffi_go_closure_VFP)
274
275 ARM_FUNC_START(ffi_closure_VFP)
276 UNWIND(.fnstart)
277 cfi_startproc
278 stmdb sp!, {r0-r3} @ save argument regs
279 cfi_adjust_cfa_offset(16)
280
281 #if FFI_EXEC_TRAMPOLINE_TABLE
282 ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
283 #endif
284 ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
285 ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
286 ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
287 0:
288 add ip, sp, #16
289 sub sp, sp, #64+32 @ allocate frame
290 cfi_adjust_cfa_offset(64+32)
291 #ifdef __clang__
292 vstm sp, {d0-d7}
293 #else
294 stc p11, cr0, [sp], {16} @ vstm sp, {d0-d7}
295 #endif
296 stmdb sp!, {ip,lr}
297
298 /* See above. */
299 UNWIND(.save {sp,lr})
300 cfi_adjust_cfa_offset(8)
301 cfi_rel_offset(lr, 4)
302
303 add r3, sp, #8 @ load frame
304 bl CNAME(ffi_closure_inner_VFP)
305
306 @ Load values returned in registers.
307 add r2, sp, #8+64 @ load result
308 adr r3, CNAME(ffi_closure_ret)
309 add pc, r3, r0, lsl #3
310 cfi_endproc
311 UNWIND(.fnend)
312 ARM_FUNC_END(ffi_closure_VFP)
313
314 /* Load values returned in registers for both closure entry points.
315 Note that we use LDM with SP in the register set. This is deprecated
316 by ARM, but not yet unpredictable. */
317
318 ARM_FUNC_START_LOCAL(ffi_closure_ret)
319 cfi_startproc
320 cfi_rel_offset(sp, 0)
321 cfi_rel_offset(lr, 4)
322 0:
323 E(ARM_TYPE_VFP_S)
324 #ifdef __clang__
325 vldr s0, [r2]
326 #else
327 ldc p10, cr0, [r2] @ vldr s0, [r2]
328 #endif
329 ldm sp, {sp,pc}
330 E(ARM_TYPE_VFP_D)
331 #ifdef __clang__
332 vldr d0, [r2]
333 #else
334 ldc p11, cr0, [r2] @ vldr d0, [r2]
335 #endif
336 ldm sp, {sp,pc}
337 E(ARM_TYPE_VFP_N)
338 #ifdef __clang__
339 vldm r2, {d0-d3}
340 #else
341 ldc p11, cr0, [r2], {8} @ vldm r2, {d0-d3}
342 #endif
343 ldm sp, {sp,pc}
344 E(ARM_TYPE_INT64)
345 ldr r1, [r2, #4]
346 nop
347 E(ARM_TYPE_INT)
348 ldr r0, [r2]
349 ldm sp, {sp,pc}
350 E(ARM_TYPE_VOID)
351 ldm sp, {sp,pc}
352 nop
353 E(ARM_TYPE_STRUCT)
354 ldm sp, {sp,pc}
355 cfi_endproc
356 ARM_FUNC_END(ffi_closure_ret)
357
358 #if FFI_EXEC_TRAMPOLINE_TABLE
359
360 #ifdef __MACH__
361 #include <mach/vm_param.h>
362
363 .align PAGE_MAX_SHIFT
364 ARM_FUNC_START(ffi_closure_trampoline_table_page)
365 .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
366 adr ip, #-PAGE_MAX_SIZE @ the config page is PAGE_MAX_SIZE behind the trampoline page
367 sub ip, #8 @ account for pc bias
368 ldr pc, [ip, #4] @ jump to ffi_closure_SYSV or ffi_clos ure_VFP
369 .endr
370 ARM_FUNC_END(ffi_closure_trampoline_table_page)
371 #endif
372
373 #else
374
375 ARM_FUNC_START(ffi_arm_trampoline)
376 0: adr ip, 0b
377 ldr pc, 1f
378 1: .long 0
379 ARM_FUNC_END(ffi_arm_trampoline)
380
381 #endif /* FFI_EXEC_TRAMPOLINE_TABLE */
382
383 #if defined __ELF__ && defined __linux__
384 .section .note.GNU-stack,"",%progbits
385 #endif
386
387
388 #endif
OLDNEW
« no previous file with comments | « Modules/_ctypes/libffi_ios/arm/internal.h ('k') | Modules/_ctypes/libffi_ios/arm/trampoline_armv7.S » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+