perlasm/ppc-xlate.pl: add new instructions and clean up.
authorAndy Polyakov <appro@openssl.org>
Sun, 27 May 2018 12:03:00 +0000 (14:03 +0200)
committerAndy Polyakov <appro@openssl.org>
Wed, 30 May 2018 20:51:58 +0000 (22:51 +0200)
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6363)

crypto/perlasm/ppc-xlate.pl

index ba2842fb8240f1874ae7078018433b48960822aa..1a22f7a4d2949fba77e4a7a6d28958b8d1ed768e 100755 (executable)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -217,6 +217,7 @@ my $stvdx_u = sub { vsxmem_op(@_, 716); };  # stxsdx
 my $lvx_4w     = sub { vsxmem_op(@_, 780); };  # lxvw4x
 my $stvx_4w    = sub { vsxmem_op(@_, 908); };  # stxvw4x
 my $lvx_splt   = sub { vsxmem_op(@_, 332); };  # lxvdsx
+# VSX instruction[s] masqueraded as made-up AltiVec/VMX
 my $vpermdi    = sub {                         # xxpermdi
     my ($f, $vrt, $vra, $vrb, $dm) = @_;
     $dm = oct($dm) if ($dm =~ /^0/);
@@ -228,6 +229,10 @@ sub vcrypto_op {
     my ($f, $vrt, $vra, $vrb, $op) = @_;
     "  .long   ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op;
 }
+sub vfour {
+    my ($f, $vrt, $vra, $vrb, $vrc, $op) = @_;
+    "  .long   ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($vrc<<6)|$op;
+};
 my $vcipher    = sub { vcrypto_op(@_, 1288); };
 my $vcipherlast        = sub { vcrypto_op(@_, 1289); };
 my $vncipher   = sub { vcrypto_op(@_, 1352); };
@@ -239,7 +244,7 @@ my $vpmsumb = sub { vcrypto_op(@_, 1032); };
 my $vpmsumd    = sub { vcrypto_op(@_, 1224); };
 my $vpmsubh    = sub { vcrypto_op(@_, 1096); };
 my $vpmsumw    = sub { vcrypto_op(@_, 1160); };
-# These are not really crypto, but one can use vcrypto_op
+# These are not really crypto, but vcrypto_op template works
 my $vaddudm    = sub { vcrypto_op(@_, 192);  };
 my $vadduqm    = sub { vcrypto_op(@_, 256);  };
 my $vmuleuw    = sub { vcrypto_op(@_, 648);  };
@@ -247,21 +252,29 @@ my $vmulouw       = sub { vcrypto_op(@_, 136);  };
 my $vrld       = sub { vcrypto_op(@_, 196);  };
 my $vsld       = sub { vcrypto_op(@_, 1476); };
 my $vsrd       = sub { vcrypto_op(@_, 1732); };
+my $vsubudm    = sub { vcrypto_op(@_, 1216); };
+my $vaddcuq    = sub { vcrypto_op(@_, 320);  };
+my $vaddeuqm   = sub { vfour(@_,60); };
+my $vaddecuq   = sub { vfour(@_,61); };
 
 my $mtsle      = sub {
     my ($f, $arg) = @_;
     "  .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;
+# VSX instructions masqueraded as AltiVec/VMX
+my $mtvrd      = sub {
+    my ($f, $vrt, $ra) = @_;
+    "  .long   ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|(179<<1)|1;
 };
-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 $mtvrwz     = sub {
+    my ($f, $vrt, $ra) = @_;
+    "  .long   ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|(243<<1)|1;
 };
+
+# PowerISA 3.0 stuff
+my $maddhdu    = sub { vfour(@_,49); };
+my $maddld     = sub { vfour(@_,51); };
 my $darn = sub {
     my ($f, $rt, $l) = @_;
     "  .long   ".sprintf "0x%X",(31<<26)|($rt<<21)|($l<<16)|(755<<1);
@@ -270,16 +283,20 @@ my $iseleq = sub {
     my ($f, $rt, $ra, $rb) = @_;
     "  .long   ".sprintf "0x%X",(31<<26)|($rt<<21)|($ra<<16)|($rb<<11)|(2<<6)|30;
 };
+# VSX instruction[s] masqueraded as made-up AltiVec/VMX
+my $vspltib    = sub {                         # xxspltib
+    my ($f, $vrt, $imm8) = @_;
+    $imm8 = oct($imm8) if ($imm8 =~ /^0/);
+    $imm8 &= 0xff;
+    "  .long   ".sprintf "0x%X",(60<<26)|($vrt<<21)|($imm8<<11)|(360<<1)|1;
+};
 
 # PowerISA 3.0B stuff
 my $addex = sub {
     my ($f, $rt, $ra, $rb, $cy) = @_;  # only cy==0 is specified in 3.0B
     "  .long   ".sprintf "0x%X",(31<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($cy<<9)|(170<<1);
 };
-my $vmsumudm = sub {
-    my ($f, $vrt, $vra, $vrb, $vrc) = @_;
-    "  .long   ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($vrc<<6)|35;
-};
+my $vmsumudm   = sub { vfour(@_,35); };
 
 while($line=<>) {