]>
Commit | Line | Data |
---|---|---|
1f2f436a A |
1 | // This file implements resolvers to assist dyld in choosing the correct |
2 | // implementation of <string.h> routines on ARMv7 processors. The | |
3 | // micro-architectural differences between Cortex-A8 and Cortex-A9 are such | |
4 | // that optimal write loops are quite different on the two processors. | |
5 | // | |
6 | // The MakeResolver_a8_a9(name) macro creates a function that dyld calls to | |
7 | // pick an implementation of the name function. It does a check to determine | |
8 | // if it is running on a8 or a9 hardware, and returns a pointer to either | |
9 | // | |
10 | // name$VARIANT$CortexA8 | |
11 | // or | |
12 | // name$VARIANT$CortexA9 | |
13 | // | |
14 | // This resolution only occurs once per process; once a symbol is bound to an | |
15 | // implementation in dyld, no further calls to the resolver occur. | |
16 | // | |
17 | // On unknown implementations of the ARMv7 architecture, the Cortex-A9 variant | |
18 | // is returned by these resolvers. | |
19 | ||
20 | #include <arm/arch.h> | |
21 | #if defined _ARM_ARCH_7 && !defined VARIANT_DYLD | |
22 | ||
23 | #include <stdlib.h> | |
24 | #include <machine/cpu_capabilities.h> | |
25 | #include <mach/machine.h> | |
26 | ||
27 | #define MakeResolver_a8_a9(name) \ | |
28 | void * name ## Resolver(void) __asm__("_" #name);\ | |
29 | void * name ## Resolver(void) {\ | |
30 | __asm__(".symbol_resolver _" #name);\ | |
31 | if (*(int *)_COMM_PAGE_CPUFAMILY == CPUFAMILY_ARM_13)\ | |
32 | return name ## $VARIANT$CortexA8;\ | |
33 | else\ | |
34 | return name ## $VARIANT$CortexA9;\ | |
35 | } | |
36 | ||
37 | void bcopy$VARIANT$CortexA8(const void *, void *, size_t); | |
38 | void bcopy$VARIANT$CortexA9(const void *, void *, size_t); | |
39 | MakeResolver_a8_a9(bcopy) | |
40 | ||
41 | void *memmove$VARIANT$CortexA8(void *, const void *, size_t); | |
42 | void *memmove$VARIANT$CortexA9(void *, const void *, size_t); | |
43 | MakeResolver_a8_a9(memmove) | |
44 | ||
45 | void *memcpy$VARIANT$CortexA8(void *, const void *, size_t); | |
46 | void *memcpy$VARIANT$CortexA9(void *, const void *, size_t); | |
47 | MakeResolver_a8_a9(memcpy) | |
48 | ||
49 | void bzero$VARIANT$CortexA8(void *, size_t); | |
50 | void bzero$VARIANT$CortexA9(void *, size_t); | |
51 | MakeResolver_a8_a9(bzero) | |
52 | ||
53 | void __bzero$VARIANT$CortexA8(void *, size_t); | |
54 | void __bzero$VARIANT$CortexA9(void *, size_t); | |
55 | MakeResolver_a8_a9(__bzero) | |
56 | ||
57 | void *memset$VARIANT$CortexA8(void *, int, size_t); | |
58 | void *memset$VARIANT$CortexA9(void *, int, size_t); | |
59 | MakeResolver_a8_a9(memset) | |
60 | ||
61 | #else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD | |
62 | ||
63 | typedef int emptyFilesArentCFiles; | |
64 | ||
65 | #endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD |