push(@INC,"perlasm","../../perlasm");
require "x86asm.pl";
&asm_init($ARGV[0],"sha512-sse2.pl",$ARGV[$
$K512="esi"; $W512_SZ=8*(16+16+8); $Widx="edx"; $data="edi"; $A="mm0"; $E="mm1"; $Aoff=256+0; $Boff=256+8;
$Coff=256+16;
$Doff=256+24;
$Eoff=256+32;
$Foff=256+40;
$Goff=256+48;
$Hoff=256+56;
sub SHA2_ROUND()
{ local ($kidx,$widx)=@_;
&movq ("mm4",&QWP($Foff,$W512)); &movq ("mm5",&QWP($Goff,$W512)); &movq ("mm6",&QWP($Hoff,$W512));
&movq ("mm2",$E); &movq ("mm3",$E); &psrlq ("mm2",14);
&psllq ("mm3",23);
&movq ("mm7","mm2"); &pxor ("mm7","mm3");
&psrlq ("mm2",4);
&psllq ("mm3",23);
&pxor ("mm7","mm2");
&pxor ("mm7","mm3");
&psrlq ("mm2",23);
&psllq ("mm3",4);
&pxor ("mm7","mm2");
&pxor ("mm7","mm3");
&movq (&QWP($Foff,$W512),$E); &movq (&QWP($Goff,$W512),"mm4"); &movq (&QWP($Hoff,$W512),"mm5");
&pxor ("mm4","mm5"); &pand ("mm4",$E); &pxor ("mm4","mm5"); &paddq ("mm7","mm4");
&movq ("mm2",&QWP($Boff,$W512)); &movq ("mm3",&QWP($Coff,$W512)); &movq ($E,&QWP($Doff,$W512));
&paddq ("mm7","mm6"); &paddq ("mm7",&QWP(0,$K512,$kidx,8)); &paddq ("mm7",&QWP(0,$W512,$widx,8)); &paddq ($E,"mm7");
&movq ("mm4",$A); &movq ("mm5",$A); &psrlq ("mm4",28);
&psllq ("mm5",25);
&movq ("mm6","mm4"); &pxor ("mm6","mm5");
&psrlq ("mm4",6);
&psllq ("mm5",5);
&pxor ("mm6","mm4");
&pxor ("mm6","mm5");
&psrlq ("mm4",5);
&psllq ("mm5",6);
&pxor ("mm6","mm4");
&pxor ("mm6","mm5");
&movq (&QWP($Boff,$W512),$A); &movq (&QWP($Coff,$W512),"mm2"); &movq (&QWP($Doff,$W512),"mm3");
&movq ("mm4",$A); &por ($A,"mm3"); &pand ("mm4","mm3"); &pand ($A,"mm2"); &por ("mm4",$A); &paddq ("mm6","mm4");
&movq ($A,"mm7"); &paddq ($A,"mm6"); }
$func="sha512_block_sse2";
&function_begin_B($func);
if (0) { &picmeup("eax","OPENSSL_ia32cap");
&bt (&DWP(0,"eax"),26);
&jnc ("SHA512_Transform");
}
&push ("ebp");
&mov ("ebp","esp");
&push ("ebx");
&push ("esi");
&push ("edi");
&mov ($Widx,&DWP(8,"ebp")); &mov ($data,&DWP(12,"ebp")); &call (&label("pic_point")); &set_label("pic_point");
&blindpop($K512);
&lea ($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
$W512 = "esp"; &sub ($W512,$W512_SZ);
&and ($W512,-16);
&movdqu ("xmm0",&QWP(0,$Widx));
&movdqu ("xmm1",&QWP(16,$Widx));
&movdqu ("xmm2",&QWP(32,$Widx));
&movdqu ("xmm3",&QWP(48,$Widx));
&align(8);
&set_label("_chunk_loop");
&movdqa (&QWP($Aoff,$W512),"xmm0"); &movdqa (&QWP($Coff,$W512),"xmm1"); &movdqa (&QWP($Eoff,$W512),"xmm2"); &movdqa (&QWP($Goff,$W512),"xmm3");
&xor ($Widx,$Widx);
&movdq2q($A,"xmm0"); &movdq2q($E,"xmm2");
&mov ("eax",&DWP(0,$data,$Widx,8));
&mov ("ebx",&DWP(4,$data,$Widx,8));
&bswap ("eax");
&bswap ("ebx");
&mov (&DWP(0,$W512,$Widx,8),"ebx"); &mov (&DWP(4,$W512,$Widx,8),"eax");
&mov (&DWP(128+0,$W512,$Widx,8),"ebx"); &mov (&DWP(128+4,$W512,$Widx,8),"eax");
&align(8);
&set_label("_1st_loop"); &mov ("eax",&DWP(0+8,$data,$Widx,8));
&mov ("ebx",&DWP(4+8,$data,$Widx,8));
&bswap ("eax");
&bswap ("ebx");
&mov (&DWP(0+8,$W512,$Widx,8),"ebx"); &mov (&DWP(4+8,$W512,$Widx,8),"eax");
&mov (&DWP(128+0+8,$W512,$Widx,8),"ebx"); &mov (&DWP(128+4+8,$W512,$Widx,8),"eax");
&set_label("_1st_looplet");
&SHA2_ROUND($Widx,$Widx); &inc($Widx);
&cmp ($Widx,15)
&jl (&label("_1st_loop"));
&je (&label("_1st_looplet"));
$Kidx = "ebx"; &mov ($Kidx,$Widx);
&align(8);
&set_label("_2nd_loop"); &and($Widx,0xf);
&movdqu ("xmm0",&QWP(8*1,$W512,$Widx,8)); &movdqa ("xmm2","xmm0"); &movdqa ("xmm3","xmm0"); &psrlq ("xmm2",1);
&psllq ("xmm3",56);
&movdqa ("xmm0","xmm2");
&pxor ("xmm0","xmm3");
&psrlq ("xmm2",6);
&psllq ("xmm3",7);
&pxor ("xmm0","xmm2");
&pxor ("xmm0","xmm3");
&psrlq ("xmm2",1);
&pxor ("xmm0","xmm2");
&movdqa ("xmm1",&QWP(8*14,$W512,$Widx,8)); &movdqa ("xmm4","xmm1"); &movdqa ("xmm5","xmm1"); &psrlq ("xmm4",6);
&psllq ("xmm5",3);
&movdqa ("xmm1","xmm4");
&pxor ("xmm1","xmm5");
&psrlq ("xmm4",13);
&psllq ("xmm5",42);
&pxor ("xmm1","xmm4");
&pxor ("xmm1","xmm5");
&psrlq ("xmm4",42);
&pxor ("xmm1","xmm4");
&movdqu ("xmm6",&QWP(8*9,$W512,$Widx,8));
&paddq ("xmm0","xmm1"); &paddq ("xmm0","xmm6"); &paddq ("xmm0",&QWP(0,$W512,$Widx,8));
&movdqa (&QWP(0,$W512,$Widx,8),"xmm0"); &movdqa (&QWP(16*8,$W512,$Widx,8),"xmm0");
&SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx);
&SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx);
&cmp ($Kidx,80);
&jl (&label("_2nd_loop"));
&mov ($Widx,&DWP(8,"ebp")); &movq (&QWP($Aoff,$W512),$A); &movq (&QWP($Eoff,$W512),$E); &movdqu ("xmm0",&QWP(0,$Widx));
&movdqu ("xmm1",&QWP(16,$Widx));
&movdqu ("xmm2",&QWP(32,$Widx));
&movdqu ("xmm3",&QWP(48,$Widx));
&paddq ("xmm0",&QWP($Aoff,$W512)); &paddq ("xmm1",&QWP($Coff,$W512));
&paddq ("xmm2",&QWP($Eoff,$W512));
&paddq ("xmm3",&QWP($Goff,$W512));
&movdqu (&QWP(0,$Widx),"xmm0");
&movdqu (&QWP(16,$Widx),"xmm1");
&movdqu (&QWP(32,$Widx),"xmm2");
&movdqu (&QWP(48,$Widx),"xmm3");
&add ($data,16*8); &dec (&DWP(16,"ebp")); &jnz (&label("_chunk_loop"));
&emms (); &mov ("edi",&DWP(-12,"ebp"));
&mov ("esi",&DWP(-8,"ebp"));
&mov ("ebx",&DWP(-4,"ebp"));
&leave ();
&ret ();
&align(64);
&set_label("K512"); &data_word(0xd728ae22,0x428a2f98); &data_word(0x23ef65cd,0x71374491); &data_word(0xec4d3b2f,0xb5c0fbcf); &data_word(0x8189dbbc,0xe9b5dba5); &data_word(0xf348b538,0x3956c25b); &data_word(0xb605d019,0x59f111f1); &data_word(0xaf194f9b,0x923f82a4); &data_word(0xda6d8118,0xab1c5ed5); &data_word(0xa3030242,0xd807aa98); &data_word(0x45706fbe,0x12835b01); &data_word(0x4ee4b28c,0x243185be); &data_word(0xd5ffb4e2,0x550c7dc3); &data_word(0xf27b896f,0x72be5d74); &data_word(0x3b1696b1,0x80deb1fe); &data_word(0x25c71235,0x9bdc06a7); &data_word(0xcf692694,0xc19bf174); &data_word(0x9ef14ad2,0xe49b69c1); &data_word(0x384f25e3,0xefbe4786); &data_word(0x8b8cd5b5,0x0fc19dc6); &data_word(0x77ac9c65,0x240ca1cc); &data_word(0x592b0275,0x2de92c6f); &data_word(0x6ea6e483,0x4a7484aa); &data_word(0xbd41fbd4,0x5cb0a9dc); &data_word(0x831153b5,0x76f988da); &data_word(0xee66dfab,0x983e5152); &data_word(0x2db43210,0xa831c66d); &data_word(0x98fb213f,0xb00327c8); &data_word(0xbeef0ee4,0xbf597fc7); &data_word(0x3da88fc2,0xc6e00bf3); &data_word(0x930aa725,0xd5a79147); &data_word(0xe003826f,0x06ca6351); &data_word(0x0a0e6e70,0x14292967); &data_word(0x46d22ffc,0x27b70a85); &data_word(0x5c26c926,0x2e1b2138); &data_word(0x5ac42aed,0x4d2c6dfc); &data_word(0x9d95b3df,0x53380d13); &data_word(0x8baf63de,0x650a7354); &data_word(0x3c77b2a8,0x766a0abb); &data_word(0x47edaee6,0x81c2c92e); &data_word(0x1482353b,0x92722c85); &data_word(0x4cf10364,0xa2bfe8a1); &data_word(0xbc423001,0xa81a664b); &data_word(0xd0f89791,0xc24b8b70); &data_word(0x0654be30,0xc76c51a3); &data_word(0xd6ef5218,0xd192e819); &data_word(0x5565a910,0xd6990624); &data_word(0x5771202a,0xf40e3585); &data_word(0x32bbd1b8,0x106aa070); &data_word(0xb8d2d0c8,0x19a4c116); &data_word(0x5141ab53,0x1e376c08); &data_word(0xdf8eeb99,0x2748774c); &data_word(0xe19b48a8,0x34b0bcb5); &data_word(0xc5c95a63,0x391c0cb3); &data_word(0xe3418acb,0x4ed8aa4a); &data_word(0x7763e373,0x5b9cca4f); &data_word(0xd6b2b8a3,0x682e6ff3); &data_word(0x5defb2fc,0x748f82ee); &data_word(0x43172f60,0x78a5636f); &data_word(0xa1f0ab72,0x84c87814); &data_word(0x1a6439ec,0x8cc70208); &data_word(0x23631e28,0x90befffa); &data_word(0xde82bde9,0xa4506ceb); &data_word(0xb2c67915,0xbef9a3f7); &data_word(0xe372532b,0xc67178f2); &data_word(0xea26619c,0xca273ece); &data_word(0x21c0c207,0xd186b8c7); &data_word(0xcde0eb1e,0xeada7dd6); &data_word(0xee6ed178,0xf57d4f7f); &data_word(0x72176fba,0x06f067aa); &data_word(0xa2c898a6,0x0a637dc5); &data_word(0xbef90dae,0x113f9804); &data_word(0x131c471b,0x1b710b35); &data_word(0x23047d84,0x28db77f5); &data_word(0x40c72493,0x32caab7b); &data_word(0x15c9bebc,0x3c9ebe0a); &data_word(0x9c100d4c,0x431d67c4); &data_word(0xcb3e42b6,0x4cc5d4be); &data_word(0xfc657e2a,0x597f299c); &data_word(0x3ad6faec,0x5fcb6fab); &data_word(0x4a475817,0x6c44198c);
&function_end_B($func);
&asm_finish();