]>
Commit | Line | Data |
---|---|---|
b4b48a10 AP |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | #include <setjmp.h> | |
5 | #include <signal.h> | |
6 | #include <openssl/bn.h> | |
7 | ||
8 | #define PPC_FPU64 (1<<0) | |
9 | ||
10 | static int OPENSSL_ppccap_P = 0; | |
11 | ||
12 | static sigset_t all_masked; | |
13 | ||
d741cf22 | 14 | #ifdef OPENSSL_BN_ASM_MONT |
b4b48a10 AP |
15 | int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num) |
16 | { | |
17 | int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); | |
18 | int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); | |
19 | ||
20 | if (sizeof(size_t)==4) | |
21 | { | |
22 | #if (defined(__APPLE__) && defined(__MACH__)) | |
23 | if ((OPENSSL_ppccap_P&PPC_FPU64)) | |
24 | return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); | |
25 | #else | |
26 | /* boundary of 32 was experimentally determined on | |
27 | Linux 2.6.22, might have to be adjusted on AIX... */ | |
28 | if ((num>=32) && (OPENSSL_ppccap_P&PPC_FPU64)) | |
29 | { | |
30 | sigset_t oset; | |
31 | int ret; | |
32 | ||
33 | sigprocmask(SIG_SETMASK,&all_masked,&oset); | |
34 | ret=bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); | |
35 | sigprocmask(SIG_SETMASK,&oset,NULL); | |
36 | ||
37 | return ret; | |
38 | } | |
39 | #endif | |
40 | } | |
41 | else if ((OPENSSL_ppccap_P&PPC_FPU64)) | |
42 | /* this is a "must" on Power 6, but run-time detection | |
43 | * is not implemented yet... */ | |
44 | return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); | |
45 | ||
46 | return bn_mul_mont_int(rp,ap,bp,np,n0,num); | |
47 | } | |
d741cf22 | 48 | #endif |
b4b48a10 AP |
49 | |
50 | static sigjmp_buf ill_jmp; | |
51 | static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } | |
52 | ||
53 | void OPENSSL_cpuid_setup(void) | |
54 | { | |
55 | char *e; | |
56 | ||
57 | sigfillset(&all_masked); | |
58 | sigdelset(&all_masked,SIGSEGV); | |
59 | sigdelset(&all_masked,SIGILL); | |
d741cf22 AP |
60 | sigdelset(&all_masked,SIGBUS); |
61 | sigdelset(&all_masked,SIGFPE); | |
b4b48a10 AP |
62 | |
63 | if ((e=getenv("OPENSSL_ppccap"))) | |
64 | { | |
65 | OPENSSL_ppccap_P=strtoul(e,NULL,0); | |
66 | return; | |
67 | } | |
68 | ||
69 | if (sizeof(size_t)==4) | |
70 | { | |
71 | struct sigaction ill_oact,ill_act; | |
72 | sigset_t oset; | |
73 | ||
74 | memset(&ill_act,0,sizeof(ill_act)); | |
75 | ill_act.sa_handler = ill_handler; | |
d741cf22 | 76 | ill_act.sa_mask = all_masked; |
b4b48a10 AP |
77 | sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); |
78 | sigaction (SIGILL,&ill_act,&ill_oact); | |
79 | if (sigsetjmp(ill_jmp,0) == 0) | |
80 | { | |
81 | OPENSSL_ppc64_probe(); | |
82 | OPENSSL_ppccap_P |= PPC_FPU64; | |
83 | } | |
84 | else | |
85 | { | |
86 | OPENSSL_ppccap_P &= ~PPC_FPU64; | |
87 | } | |
88 | sigaction (SIGILL,&ill_oact,NULL); | |
89 | sigprocmask(SIG_SETMASK,&oset,NULL); | |
90 | } | |
91 | } |