diff options
author | Andy Polyakov <appro@openssl.org> | 2015-12-01 12:21:08 +0100 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2015-12-02 10:53:33 +0100 |
commit | 2238e0e45d03ec9ba15e9547f7739cc6987a8f57 (patch) | |
tree | a95ed836ee80e626eb82c8901d7921f6e16e2ad0 /crypto/sparcv9cap.c | |
parent | 81f3d6323dcda6a18b06c718600d6a4739e83263 (diff) | |
download | openssl-2238e0e45d03ec9ba15e9547f7739cc6987a8f57.tar.gz |
crypto/sparcv9cap.c: add SIGILL-free feature detection for Solaris.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/sparcv9cap.c')
-rw-r--r-- | crypto/sparcv9cap.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/crypto/sparcv9cap.c b/crypto/sparcv9cap.c index 1731ef65f1..2058640377 100644 --- a/crypto/sparcv9cap.c +++ b/crypto/sparcv9cap.c @@ -115,6 +115,17 @@ static void common_handler(int sig) siglongjmp(common_jmp, sig); } +#if defined(__sun) && defined(__SVR4) +# if defined(__GNUC__) && __GNUC__>=2 +extern unsigned int getisax(unsigned int vec[], unsigned int sz) __attribute__ ((weak)); +# elif defined(__SUNPRO_C) +#pragma weak getisax +extern unsigned int getisax(unsigned int vec[], unsigned int sz); +# else +static unsigned int (*getisax) (unsigned int vec[], unsigned int sz) = NULL; +# endif +#endif + void OPENSSL_cpuid_setup(void) { char *e; @@ -133,6 +144,42 @@ void OPENSSL_cpuid_setup(void) return; } +#if defined(__sun) && defined(__SVR4) + if (getisax != NULL) { + unsigned int vec[1]; + + if (getisax (vec,1)) { + if (vec[0]&0x0020) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1; + if (vec[0]&0x0040) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2; + if (vec[0]&0x0080) OPENSSL_sparcv9cap_P[0] |= SPARCV9_BLK; + if (vec[0]&0x0100) OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD; + if (vec[0]&0x0400) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3; + + /* reconstruct %cfr copy */ + OPENSSL_sparcv9cap_P[1] = (vec[0]>>17)&0x3ff; + OPENSSL_sparcv9cap_P[1] |= (OPENSSL_sparcv9cap_P[1]&CFR_MONTMUL)<<1; + if (vec[0]&0x20000000) OPENSSL_sparcv9cap_P[1] |= CFR_CRC32C; + + /* Some heuristics */ + /* all known VIS2-capable CPUs have unprivileged tick counter */ + if (OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS2) + OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED; + + OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU; + + /* detect UltraSPARC-Tx, see sparccpud.S for details... */ + if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS1) && + _sparcv9_vis1_instrument() >= 12) + OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU); + } + + if (sizeof(size_t) == 8) + OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK; + + return; + } +#endif + /* Initial value, fits UltraSPARC-I&II... */ OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED; |