update libressl to v2.7.4
[unleashed.git] / lib / libcrypto / armcap.c
blob7ee94d48b12fc7f3af29d307cce59afa708eb424
1 /* $OpenBSD: armcap.c,v 1.6 2014/06/20 21:00:46 deraadt Exp $ */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <setjmp.h>
6 #include <signal.h>
7 #include <crypto.h>
9 #include "arm_arch.h"
11 unsigned int OPENSSL_armcap_P;
13 #if __ARM_ARCH__ >= 7
14 static sigset_t all_masked;
16 static sigjmp_buf ill_jmp;
17 static void ill_handler (int sig) { siglongjmp(ill_jmp, sig);
21 * Following subroutines could have been inlined, but it's not all
22 * ARM compilers support inline assembler...
24 void _armv7_neon_probe(void);
25 #endif
27 #if defined(__GNUC__) && __GNUC__>=2
28 void OPENSSL_cpuid_setup(void) __attribute__((constructor));
29 #endif
31 void
32 OPENSSL_cpuid_setup(void)
34 #ifndef __OpenBSD__
35 char *e;
36 #endif
37 #if __ARM_ARCH__ >= 7
38 struct sigaction ill_oact, ill_act;
39 sigset_t oset;
40 #endif
41 static int trigger = 0;
43 if (trigger)
44 return;
45 trigger = 1;
47 OPENSSL_armcap_P = 0;
49 #if __ARM_ARCH__ >= 7
50 sigfillset(&all_masked);
51 sigdelset(&all_masked, SIGILL);
52 sigdelset(&all_masked, SIGTRAP);
53 sigdelset(&all_masked, SIGFPE);
54 sigdelset(&all_masked, SIGBUS);
55 sigdelset(&all_masked, SIGSEGV);
57 memset(&ill_act, 0, sizeof(ill_act));
58 ill_act.sa_handler = ill_handler;
59 ill_act.sa_mask = all_masked;
61 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
62 sigaction(SIGILL, &ill_act, &ill_oact);
64 if (sigsetjmp(ill_jmp, 1) == 0) {
65 _armv7_neon_probe();
66 OPENSSL_armcap_P |= ARMV7_NEON;
69 sigaction (SIGILL, &ill_oact, NULL);
70 sigprocmask(SIG_SETMASK, &oset, NULL);
71 #endif