Initial commit
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / libcperciva / cpusupport / cpusupport.h
1 #ifndef _CPUSUPPORT_H_
2 #define _CPUSUPPORT_H_
3
4 /*
5 * To enable support for non-portable CPU features at compile time, one or
6 * more CPUSUPPORT_ARCH_FEATURE macros should be defined. This can be done
7 * directly on the compiler command line via -D CPUSUPPORT_ARCH_FEATURE or
8 * -D CPUSUPPORT_ARCH_FEATURE=1; or a file can be created with the
9 * necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h
10 * (or similar) can be provided to include that file here.
11 */
12 #ifdef CPUSUPPORT_CONFIG_FILE
13 #include CPUSUPPORT_CONFIG_FILE
14 #endif
15
16 /**
17 * The CPUSUPPORT_FEATURE macro declares the necessary variables and
18 * functions for detecting CPU feature support at run time. The function
19 * defined in the macro acts to cache the result of the ..._detect function
20 * using the ..._present and ..._init variables. The _detect function and the
21 * _present and _init variables are turn defined by CPUSUPPORT_FEATURE_DECL in
22 * appropriate cpusupport_foo_bar.c file.
23 *
24 * In order to allow CPUSUPPORT_FEATURE to be used for features which do not
25 * have corresponding CPUSUPPORT_FEATURE_DECL blocks in another source file,
26 * we abuse the C preprocessor: If CPUSUPPORT_${enabler} is defined to 1, then
27 * we access _present_1, _init_1, and _detect_1; but if it is not defined, we
28 * access _present_CPUSUPPORT_${enabler} etc., which we define as static, thus
29 * preventing the compiler from emitting a reference to an external symbol.
30 *
31 * In this way, it becomes possible to issue CPUSUPPORT_FEATURE invocations
32 * for nonexistent features without running afoul of the requirement that
33 * "If an identifier declared with external linkage is used... in the entire
34 * program there shall be exactly one external definition" (C99 standard, 6.9
35 * paragraph 5). In practice, this means that users of the cpusupport code
36 * can omit build and runtime detection files without changing the framework
37 * code.
38 */
39 #define CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled) \
40 static int cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler; \
41 static int cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler; \
42 static inline int cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler(void) { return (0); } \
43 extern int cpusupport_ ## arch_feature ## _present_ ## enabled; \
44 extern int cpusupport_ ## arch_feature ## _init_ ## enabled; \
45 int cpusupport_ ## arch_feature ## _detect_ ## enabled(void); \
46 \
47 static inline int \
48 cpusupport_ ## arch_feature(void) \
49 { \
50 \
51 if (cpusupport_ ## arch_feature ## _present_ ## enabled) \
52 return (1); \
53 else if (cpusupport_ ## arch_feature ## _init_ ## enabled) \
54 return (0); \
55 cpusupport_ ## arch_feature ## _present_ ## enabled = \
56 cpusupport_ ## arch_feature ## _detect_ ## enabled(); \
57 cpusupport_ ## arch_feature ## _init_ ## enabled = 1; \
58 return (cpusupport_ ## arch_feature ## _present_ ## enabled); \
59 } \
60 static void (* cpusupport_ ## arch_feature ## _dummyptr)(void); \
61 static inline void \
62 cpusupport_ ## arch_feature ## _dummyfunc(void) \
63 { \
64 \
65 (void)cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler; \
66 (void)cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler; \
67 (void)cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler; \
68 (void)cpusupport_ ## arch_feature ## _present_ ## enabled; \
69 (void)cpusupport_ ## arch_feature ## _init_ ## enabled; \
70 (void)cpusupport_ ## arch_feature ## _detect_ ## enabled; \
71 (void)cpusupport_ ## arch_feature ## _dummyptr; \
72 } \
73 static void (* cpusupport_ ## arch_feature ## _dummyptr)(void) = cpusupport_ ## arch_feature ## _dummyfunc; \
74 struct cpusupport_ ## arch_feature ## _dummy
75 #define CPUSUPPORT_FEATURE_(arch_feature, enabler, enabled) \
76 CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled)
77 #define CPUSUPPORT_FEATURE(arch, feature, enabler) \
78 CPUSUPPORT_FEATURE_(arch ## _ ## feature, enabler, CPUSUPPORT_ ## enabler)
79
80 /*
81 * CPUSUPPORT_FEATURE_DECL(arch, feature):
82 * Macro which defines variables and provides a function declaration for
83 * detecting the presence of "feature" on the "arch" architecture. The
84 * function body following this macro expansion must return nonzero if the
85 * feature is present, or zero if the feature is not present or the detection
86 * fails for any reason.
87 */
88 #define CPUSUPPORT_FEATURE_DECL(arch, feature) \
89 int cpusupport_ ## arch ## _ ## feature ## _present_1 = 0; \
90 int cpusupport_ ## arch ## _ ## feature ## _init_1 = 0; \
91 int cpusupport_ ## arch ## _ ## feature ## _detect_1(void); \
92 int \
93 cpusupport_ ## arch ## _ ## feature ## _detect_1(void)
94
95 /*
96 * List of features. If a feature here is not enabled by the appropriate
97 * CPUSUPPORT_ARCH_FEATURE macro being defined, it has no effect; but if the
98 * relevant macro may be defined (e.g., by Build/cpusupport.sh successfully
99 * compiling Build/cpusupport-ARCH-FEATURE.c) then the C file containing the
100 * corresponding run-time detection code (cpusupport_arch_feature.c) must be
101 * compiled and linked in.
102 */
103 CPUSUPPORT_FEATURE(x86, aesni, X86_AESNI);
104 CPUSUPPORT_FEATURE(x86, sse2, X86_SSE2);
105
106 #endif /* !_CPUSUPPORT_H_ */
This page took 0.02413 seconds and 4 git commands to generate.