diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl index 0f46cf06bcb859f50f140443bd1711e91886c768..bc79b4626c4d6b0dfa5a530a02163c2e966cdd9f 100755 --- a/crypto/perlasm/ppc-xlate.pl +++ b/crypto/perlasm/ppc-xlate.pl @@ -207,6 +207,21 @@ my $mtsle = sub { " .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2); }; +# PowerISA 3.0 stuff +my $maddhdu = sub { + my ($f, $rt, $ra, $rb, $rc) = @_; + " .long ".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|49; +}; +my $maddld = sub { + my ($f, $rt, $ra, $rb, $rc) = @_; + " .long ".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|51; +}; + +my $darn = sub { + my ($f, $rt, $l) = @_; + " .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($l<<16)|(755<<1); +}; + while($line=<>) { $line =~ s|[#!;].*$||; # get rid of asm-style comments... diff --git a/crypto/ppc_arch.h b/crypto/ppc_arch.h index c0b4f1846bbd1110cb6c510f7fe642f267e4f494..a27fb728df6e27130d985daebb8aaacc50329856 100644 --- a/crypto/ppc_arch.h +++ b/crypto/ppc_arch.h @@ -12,5 +12,6 @@ extern unsigned int OPENSSL_ppccap_P; # define PPC_ALTIVEC (1<<1) # define PPC_CRYPTO207 (1<<2) # define PPC_FPU (1<<3) +# define PPC_MADD300 (1<<4) #endif diff --git a/crypto/ppccap.c b/crypto/ppccap.c index 76cfdbde8b7ab3f192008dd4af5fb720aeca8c14..2c98daf5b4df785d88269b8519dd9cbcc2942e18 100644 --- a/crypto/ppccap.c +++ b/crypto/ppccap.c @@ -151,6 +151,7 @@ static unsigned long (*getauxval) (unsigned long) = NULL; #define HWCAP2 26 /* AT_HWCAP2 */ #define HWCAP_VEC_CRYPTO (1U << 25) +#define HWCAP_ARCH_3_00 (1U << 23) # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) @@ -208,6 +209,9 @@ void OPENSSL_cpuid_setup(void) if (__power_set(0xffffffffU<<16)) /* POWER8 and later */ OPENSSL_ppccap_P |= PPC_CRYPTO207; + if (__power_set(0xffffffffU<<17)) /* POWER9 and later */ + OPENSSL_ppccap_P |= PPC_MADD300; + return; # endif #endif @@ -236,6 +240,10 @@ void OPENSSL_cpuid_setup(void) OPENSSL_ppccap_P |= PPC_CRYPTO207; } + if (hwcap & HWCAP_ARCH_3_00) { + OPENSSL_ppccap_P |= PPC_MADD300; + } + return; } @@ -285,6 +293,11 @@ void OPENSSL_cpuid_setup(void) } } + if (sigsetjmp(ill_jmp, 1) == 0) { + OPENSSL_madd300_probe(); + OPENSSL_ppccap_P |= PPC_MADD300; + } + sigaction(SIGILL, &ill_oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); } diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl index 4c2530d147ae9aa61c15a6a94e77b02909de482c..9de1355b2f8f0d4a15bdc0e386bc89fd3b96b4c6 100755 --- a/crypto/ppccpuid.pl +++ b/crypto/ppccpuid.pl @@ -60,6 +60,16 @@ $code=<<___; .byte 0,12,0x14,0,0,0,0,0 .size .OPENSSL_crypto207_probe,.-.OPENSSL_crypto207_probe +.globl .OPENSSL_madd300_probe +.align 4 +.OPENSSL_madd300_probe: + xor r0,r0,r0 + maddld r3,r0,r0,r0 + maddhdu r3,r0,r0,r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + .globl .OPENSSL_wipe_cpu .align 4 .OPENSSL_wipe_cpu: