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.
7 #if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
10 #include <machine/cpu_capabilities.h>
11 #include <mach/machine.h>
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
17 // name$VARIANT$CortexA8
19 // name$VARIANT$CortexA9
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.
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; \
39 void bzero$VARIANT$
CortexA8(void *, size_t);
40 void bzero$VARIANT$
CortexA9(void *, size_t);
41 void bzero$VARIANT$
Swift(void *, size_t);
44 void __bzero$VARIANT$
CortexA8(void *, size_t);
45 void __bzero$VARIANT$
CortexA9(void *, size_t);
46 void __bzero$VARIANT$
Swift(void *, size_t);
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);
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);
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);
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);
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; \
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
);
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
);
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
);
94 #else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
96 typedef int emptyFilesArentCFiles
;
98 #endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD