]>
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> | |
fd054957 | 6 | #include <unistd.h> |
78c3e205 AP |
7 | #ifdef __linux |
8 | #include <sys/utsname.h> | |
9 | #endif | |
9f7b2c76 | 10 | #include <crypto.h> |
b4b48a10 AP |
11 | #include <openssl/bn.h> |
12 | ||
13 | #define PPC_FPU64 (1<<0) | |
6415dd7b | 14 | #define PPC_ALTIVEC (1<<1) |
b4b48a10 AP |
15 | |
16 | static int OPENSSL_ppccap_P = 0; | |
17 | ||
18 | static sigset_t all_masked; | |
19 | ||
d741cf22 | 20 | #ifdef OPENSSL_BN_ASM_MONT |
b4b48a10 AP |
21 | 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) |
22 | { | |
23 | 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); | |
24 | 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); | |
25 | ||
26 | if (sizeof(size_t)==4) | |
27 | { | |
28 | #if (defined(__APPLE__) && defined(__MACH__)) | |
2e75ed33 | 29 | if (num>=8 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64)) |
b4b48a10 AP |
30 | return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); |
31 | #else | |
32 | /* boundary of 32 was experimentally determined on | |
33 | Linux 2.6.22, might have to be adjusted on AIX... */ | |
70b76d39 | 34 | if (num>=32 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64)) |
b4b48a10 AP |
35 | { |
36 | sigset_t oset; | |
37 | int ret; | |
38 | ||
39 | sigprocmask(SIG_SETMASK,&all_masked,&oset); | |
40 | ret=bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); | |
41 | sigprocmask(SIG_SETMASK,&oset,NULL); | |
42 | ||
43 | return ret; | |
44 | } | |
45 | #endif | |
46 | } | |
47 | else if ((OPENSSL_ppccap_P&PPC_FPU64)) | |
6415dd7b | 48 | /* this is a "must" on POWER6, but run-time detection |
b4b48a10 AP |
49 | * is not implemented yet... */ |
50 | return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); | |
51 | ||
52 | return bn_mul_mont_int(rp,ap,bp,np,n0,num); | |
53 | } | |
d741cf22 | 54 | #endif |
b4b48a10 AP |
55 | |
56 | static sigjmp_buf ill_jmp; | |
57 | static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } | |
58 | ||
70b76d39 | 59 | void OPENSSL_ppc64_probe(void); |
fd054957 | 60 | void OPENSSL_altivec_probe(void); |
70b76d39 | 61 | |
b4b48a10 AP |
62 | void OPENSSL_cpuid_setup(void) |
63 | { | |
64 | char *e; | |
6415dd7b AP |
65 | struct sigaction ill_oact,ill_act; |
66 | sigset_t oset; | |
67 | static int trigger=0; | |
b4b48a10 | 68 | |
6415dd7b AP |
69 | if (trigger) return; |
70 | trigger=1; | |
71 | ||
b4b48a10 | 72 | sigfillset(&all_masked); |
b4b48a10 | 73 | sigdelset(&all_masked,SIGILL); |
78a533cb | 74 | sigdelset(&all_masked,SIGTRAP); |
80dfadfd | 75 | #ifdef SIGEMT |
78a533cb | 76 | sigdelset(&all_masked,SIGEMT); |
80dfadfd | 77 | #endif |
d741cf22 | 78 | sigdelset(&all_masked,SIGFPE); |
78a533cb AP |
79 | sigdelset(&all_masked,SIGBUS); |
80 | sigdelset(&all_masked,SIGSEGV); | |
b4b48a10 AP |
81 | |
82 | if ((e=getenv("OPENSSL_ppccap"))) | |
83 | { | |
84 | OPENSSL_ppccap_P=strtoul(e,NULL,0); | |
85 | return; | |
86 | } | |
87 | ||
6415dd7b AP |
88 | OPENSSL_ppccap_P = 0; |
89 | ||
fd054957 AP |
90 | #if defined(_AIX) |
91 | if (sizeof(size_t)==4 | |
92 | # if defined(_SC_AIX_KERNEL_BITMODE) | |
93 | && sysconf(_SC_AIX_KERNEL_BITMODE)!=64 | |
94 | # endif | |
95 | ) | |
96 | return; | |
97 | #endif | |
98 | ||
6415dd7b AP |
99 | memset(&ill_act,0,sizeof(ill_act)); |
100 | ill_act.sa_handler = ill_handler; | |
101 | ill_act.sa_mask = all_masked; | |
102 | ||
103 | sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset); | |
104 | sigaction(SIGILL,&ill_act,&ill_oact); | |
105 | ||
b4b48a10 AP |
106 | if (sizeof(size_t)==4) |
107 | { | |
78c3e205 AP |
108 | #ifdef __linux |
109 | struct utsname uts; | |
110 | if (uname(&uts)==0 && strcmp(uts.machine,"ppc64")==0) | |
111 | #endif | |
6415dd7b | 112 | if (sigsetjmp(ill_jmp,1) == 0) |
b4b48a10 AP |
113 | { |
114 | OPENSSL_ppc64_probe(); | |
115 | OPENSSL_ppccap_P |= PPC_FPU64; | |
116 | } | |
b4b48a10 | 117 | } |
6415dd7b AP |
118 | else |
119 | { | |
120 | /* | |
121 | * Wanted code detecting POWER6 CPU and setting PPC_FPU64 | |
122 | */ | |
123 | } | |
124 | ||
125 | if (sigsetjmp(ill_jmp,1) == 0) | |
126 | { | |
127 | OPENSSL_altivec_probe(); | |
128 | OPENSSL_ppccap_P |= PPC_ALTIVEC; | |
129 | } | |
130 | ||
131 | sigaction (SIGILL,&ill_oact,NULL); | |
132 | sigprocmask(SIG_SETMASK,&oset,NULL); | |
b4b48a10 | 133 | } |