]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/armcap.c
Correction of make depend merge error
[thirdparty/openssl.git] / crypto / armcap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <setjmp.h>
5 #include <signal.h>
6 #include <crypto.h>
7
8 #include "arm_arch.h"
9
10 unsigned int OPENSSL_armcap_P;
11
12 static sigset_t all_masked;
13
14 static sigjmp_buf ill_jmp;
15 static void ill_handler(int sig)
16 {
17 siglongjmp(ill_jmp, sig);
18 }
19
20 /*
21 * Following subroutines could have been inlined, but it's not all
22 * ARM compilers support inline assembler...
23 */
24 void _armv7_neon_probe(void);
25 unsigned int _armv7_tick(void);
26
27 unsigned int OPENSSL_rdtsc(void)
28 {
29 if (OPENSSL_armcap_P & ARMV7_TICK)
30 return _armv7_tick();
31 else
32 return 0;
33 }
34
35 #if defined(__GNUC__) && __GNUC__>=2
36 void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
37 #endif
38 void OPENSSL_cpuid_setup(void)
39 {
40 char *e;
41 struct sigaction ill_oact, ill_act;
42 sigset_t oset;
43 static int trigger = 0;
44
45 if (trigger)
46 return;
47 trigger = 1;
48
49 if ((e = getenv("OPENSSL_armcap"))) {
50 OPENSSL_armcap_P = strtoul(e, NULL, 0);
51 return;
52 }
53
54 sigfillset(&all_masked);
55 sigdelset(&all_masked, SIGILL);
56 sigdelset(&all_masked, SIGTRAP);
57 sigdelset(&all_masked, SIGFPE);
58 sigdelset(&all_masked, SIGBUS);
59 sigdelset(&all_masked, SIGSEGV);
60
61 OPENSSL_armcap_P = 0;
62
63 memset(&ill_act, 0, sizeof(ill_act));
64 ill_act.sa_handler = ill_handler;
65 ill_act.sa_mask = all_masked;
66
67 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
68 sigaction(SIGILL, &ill_act, &ill_oact);
69
70 if (sigsetjmp(ill_jmp, 1) == 0) {
71 _armv7_neon_probe();
72 OPENSSL_armcap_P |= ARMV7_NEON;
73 }
74 if (sigsetjmp(ill_jmp, 1) == 0) {
75 _armv7_tick();
76 OPENSSL_armcap_P |= ARMV7_TICK;
77 }
78
79 sigaction(SIGILL, &ill_oact, NULL);
80 sigprocmask(SIG_SETMASK, &oset, NULL);
81 }