]> git.saurik.com Git - apple/libc.git/blob - arm/string/dyld_resolvers.c
Libc-825.24.tar.gz
[apple/libc.git] / arm / string / dyld_resolvers.c
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 #include <arm/arch.h>
7 #if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
8
9 #include <stdlib.h>
10 #include <machine/cpu_capabilities.h>
11 #include <mach/machine.h>
12
13 // The MakeResolver(name) macro creates a function that dyld calls to
14 // pick an implementation of the name function. It does a check to determine
15 // if it is running on a8 or a9 hardware, and returns a pointer to either
16 //
17 // name$VARIANT$CortexA8
18 // or
19 // name$VARIANT$CortexA9
20 // or
21 // name$VARIANT$Swift
22 //
23 // This resolution only occurs once per process; once a symbol is bound to an
24 // implementation in dyld, no further calls to the resolver occur.
25 //
26 // On unknown implementations of the ARMv7 architecture, the Swift variant
27 // is returned by these resolvers.
28 #define MakeResolver(name) \
29 void * name ## Resolver(void) __asm__("_" #name); \
30 void * name ## Resolver(void) { \
31 __asm__(".symbol_resolver _" #name); \
32 switch (*(int *)_COMM_PAGE_CPUFAMILY) { \
33 case CPUFAMILY_ARM_13: return name ## $VARIANT$CortexA8; \
34 case CPUFAMILY_ARM_14: return name ## $VARIANT$CortexA9; \
35 default: return name ## $VARIANT$Swift; \
36 } \
37 }
38
39 void bzero$VARIANT$CortexA8(void *, size_t);
40 void bzero$VARIANT$CortexA9(void *, size_t);
41 void bzero$VARIANT$Swift(void *, size_t);
42 MakeResolver(bzero)
43
44 void __bzero$VARIANT$CortexA8(void *, size_t);
45 void __bzero$VARIANT$CortexA9(void *, size_t);
46 void __bzero$VARIANT$Swift(void *, size_t);
47 MakeResolver(__bzero)
48
49 void *memset$VARIANT$CortexA8(void *, int, size_t);
50 void *memset$VARIANT$CortexA9(void *, int, size_t);
51 void *memset$VARIANT$Swift(void *, int, size_t);
52 MakeResolver(memset)
53
54 void bcopy$VARIANT$CortexA8(const void *, void *, size_t);
55 void bcopy$VARIANT$CortexA9(const void *, void *, size_t);
56 void bcopy$VARIANT$Swift(const void *, void *, size_t);
57 MakeResolver(bcopy)
58
59 void *memmove$VARIANT$CortexA8(void *, const void *, size_t);
60 void *memmove$VARIANT$CortexA9(void *, const void *, size_t);
61 void *memmove$VARIANT$Swift(void *, const void *, size_t);
62 MakeResolver(memmove)
63
64 void *memcpy$VARIANT$CortexA8(void *, const void *, size_t);
65 void *memcpy$VARIANT$CortexA9(void *, const void *, size_t);
66 void *memcpy$VARIANT$Swift(void *, const void *, size_t);
67 MakeResolver(memcpy)
68
69 // The memset_patternx resolvers are a little different, because we only have
70 // a generic implementation and a Swift implementation.
71 #define MakeResolver_Swift(name) \
72 void * name ## Resolver(void) __asm__("_" #name); \
73 void * name ## Resolver(void) { \
74 __asm__(".symbol_resolver _" #name); \
75 switch (*(int *)_COMM_PAGE_CPUFAMILY) { \
76 case CPUFAMILY_ARM_13: return name ## $VARIANT$Generic; \
77 case CPUFAMILY_ARM_14: return name ## $VARIANT$Generic; \
78 default: return name ## $VARIANT$Swift; \
79 } \
80 }
81
82 void memset_pattern4$VARIANT$Generic(void *b, const void *c4, size_t len);
83 void memset_pattern4$VARIANT$Swift(void *b, const void *c4, size_t len);
84 MakeResolver_Swift(memset_pattern4);
85
86 void memset_pattern8$VARIANT$Generic(void *b, const void *c8, size_t len);
87 void memset_pattern8$VARIANT$Swift(void *b, const void *c8, size_t len);
88 MakeResolver_Swift(memset_pattern8);
89
90 void memset_pattern16$VARIANT$Generic(void *b, const void *c16, size_t len);
91 void memset_pattern16$VARIANT$Swift(void *b, const void *c16, size_t len);
92 MakeResolver_Swift(memset_pattern16);
93
94 #else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
95
96 typedef int emptyFilesArentCFiles;
97
98 #endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD