1289848Sjkim#!/usr/bin/env perl 2289848Sjkim 3289848Sjkim############################################################################## 4289848Sjkim# # 5289848Sjkim# Copyright 2014 Intel Corporation # 6289848Sjkim# # 7289848Sjkim# Licensed under the Apache License, Version 2.0 (the "License"); # 8289848Sjkim# you may not use this file except in compliance with the License. # 9289848Sjkim# You may obtain a copy of the License at # 10289848Sjkim# # 11289848Sjkim# http://www.apache.org/licenses/LICENSE-2.0 # 12289848Sjkim# # 13289848Sjkim# Unless required by applicable law or agreed to in writing, software # 14289848Sjkim# distributed under the License is distributed on an "AS IS" BASIS, # 15289848Sjkim# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 16289848Sjkim# See the License for the specific language governing permissions and # 17289848Sjkim# limitations under the License. # 18289848Sjkim# # 19289848Sjkim############################################################################## 20289848Sjkim# # 21289848Sjkim# Developers and authors: # 22289848Sjkim# Shay Gueron (1, 2), and Vlad Krasnov (1) # 23289848Sjkim# (1) Intel Corporation, Israel Development Center # 24289848Sjkim# (2) University of Haifa # 25289848Sjkim# Reference: # 26289848Sjkim# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with# 27289848Sjkim# 256 Bit Primes" # 28289848Sjkim# # 29289848Sjkim############################################################################## 30289848Sjkim 31289848Sjkim# Further optimization by <appro@openssl.org>: 32289848Sjkim# 33289848Sjkim# this/original with/without -DECP_NISTZ256_ASM(*) 34289848Sjkim# Opteron +12-49% +110-150% 35289848Sjkim# Bulldozer +14-45% +175-210% 36289848Sjkim# P4 +18-46% n/a :-( 37289848Sjkim# Westmere +12-34% +80-87% 38289848Sjkim# Sandy Bridge +9-35% +110-120% 39289848Sjkim# Ivy Bridge +9-35% +110-125% 40289848Sjkim# Haswell +8-37% +140-160% 41289848Sjkim# Broadwell +18-58% +145-210% 42289848Sjkim# Atom +15-50% +130-180% 43289848Sjkim# VIA Nano +43-160% +300-480% 44289848Sjkim# 45289848Sjkim# (*) "without -DECP_NISTZ256_ASM" refers to build with 46289848Sjkim# "enable-ec_nistp_64_gcc_128"; 47289848Sjkim# 48289848Sjkim# Ranges denote minimum and maximum improvement coefficients depending 49289848Sjkim# on benchmark. Lower coefficients are for ECDSA sign, relatively fastest 50289848Sjkim# server-side operation. Keep in mind that +100% means 2x improvement. 51289848Sjkim 52289848Sjkim$flavour = shift; 53289848Sjkim$output = shift; 54289848Sjkimif ($flavour =~ /\./) { $output = $flavour; undef $flavour; } 55289848Sjkim 56289848Sjkim$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); 57289848Sjkim 58289848Sjkim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 59289848Sjkim( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 60289848Sjkim( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 61289848Sjkimdie "can't locate x86_64-xlate.pl"; 62289848Sjkim 63289848Sjkimopen OUT,"| \"$^X\" $xlate $flavour $output"; 64289848Sjkim*STDOUT=*OUT; 65289848Sjkim 66289848Sjkimif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` 67289848Sjkim =~ /GNU assembler version ([2-9]\.[0-9]+)/) { 68289848Sjkim $avx = ($1>=2.19) + ($1>=2.22); 69289848Sjkim $addx = ($1>=2.23); 70289848Sjkim} 71289848Sjkim 72289848Sjkimif (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && 73289848Sjkim `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) { 74289848Sjkim $avx = ($1>=2.09) + ($1>=2.10); 75289848Sjkim $addx = ($1>=2.10); 76289848Sjkim} 77289848Sjkim 78289848Sjkimif (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && 79289848Sjkim `ml64 2>&1` =~ /Version ([0-9]+)\./) { 80289848Sjkim $avx = ($1>=10) + ($1>=11); 81289848Sjkim $addx = ($1>=12); 82289848Sjkim} 83289848Sjkim 84295009Sjkimif (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) { 85289848Sjkim my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 86289848Sjkim $avx = ($ver>=3.0) + ($ver>=3.01); 87289848Sjkim $addx = ($ver>=3.03); 88289848Sjkim} 89289848Sjkim 90289848Sjkim$code.=<<___; 91289848Sjkim.text 92289848Sjkim.extern OPENSSL_ia32cap_P 93289848Sjkim 94289848Sjkim# The polynomial 95289848Sjkim.align 64 96289848Sjkim.Lpoly: 97289848Sjkim.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 98289848Sjkim 99289848Sjkim# 2^512 mod P precomputed for NIST P256 polynomial 100289848Sjkim.LRR: 101289848Sjkim.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd 102289848Sjkim 103289848Sjkim.LOne: 104289848Sjkim.long 1,1,1,1,1,1,1,1 105289848Sjkim.LTwo: 106289848Sjkim.long 2,2,2,2,2,2,2,2 107289848Sjkim.LThree: 108289848Sjkim.long 3,3,3,3,3,3,3,3 109289848Sjkim.LONE_mont: 110289848Sjkim.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe 111289848Sjkim___ 112289848Sjkim 113289848Sjkim{ 114289848Sjkim################################################################################ 115289848Sjkim# void ecp_nistz256_mul_by_2(uint64_t res[4], uint64_t a[4]); 116289848Sjkim 117289848Sjkimmy ($a0,$a1,$a2,$a3)=map("%r$_",(8..11)); 118289848Sjkimmy ($t0,$t1,$t2,$t3,$t4)=("%rax","%rdx","%rcx","%r12","%r13"); 119289848Sjkimmy ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx"); 120289848Sjkim 121289848Sjkim$code.=<<___; 122289848Sjkim 123289848Sjkim.globl ecp_nistz256_mul_by_2 124289848Sjkim.type ecp_nistz256_mul_by_2,\@function,2 125289848Sjkim.align 64 126289848Sjkimecp_nistz256_mul_by_2: 127289848Sjkim push %r12 128289848Sjkim push %r13 129289848Sjkim 130289848Sjkim mov 8*0($a_ptr), $a0 131306195Sjkim xor $t4,$t4 132289848Sjkim mov 8*1($a_ptr), $a1 133289848Sjkim add $a0, $a0 # a0:a3+a0:a3 134289848Sjkim mov 8*2($a_ptr), $a2 135289848Sjkim adc $a1, $a1 136289848Sjkim mov 8*3($a_ptr), $a3 137289848Sjkim lea .Lpoly(%rip), $a_ptr 138289848Sjkim mov $a0, $t0 139289848Sjkim adc $a2, $a2 140289848Sjkim adc $a3, $a3 141289848Sjkim mov $a1, $t1 142306195Sjkim adc \$0, $t4 143289848Sjkim 144289848Sjkim sub 8*0($a_ptr), $a0 145289848Sjkim mov $a2, $t2 146289848Sjkim sbb 8*1($a_ptr), $a1 147289848Sjkim sbb 8*2($a_ptr), $a2 148289848Sjkim mov $a3, $t3 149289848Sjkim sbb 8*3($a_ptr), $a3 150306195Sjkim sbb \$0, $t4 151289848Sjkim 152306195Sjkim cmovc $t0, $a0 153306195Sjkim cmovc $t1, $a1 154289848Sjkim mov $a0, 8*0($r_ptr) 155306195Sjkim cmovc $t2, $a2 156289848Sjkim mov $a1, 8*1($r_ptr) 157306195Sjkim cmovc $t3, $a3 158289848Sjkim mov $a2, 8*2($r_ptr) 159289848Sjkim mov $a3, 8*3($r_ptr) 160289848Sjkim 161289848Sjkim pop %r13 162289848Sjkim pop %r12 163289848Sjkim ret 164289848Sjkim.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 165289848Sjkim 166289848Sjkim################################################################################ 167289848Sjkim# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]); 168289848Sjkim.globl ecp_nistz256_div_by_2 169289848Sjkim.type ecp_nistz256_div_by_2,\@function,2 170289848Sjkim.align 32 171289848Sjkimecp_nistz256_div_by_2: 172289848Sjkim push %r12 173289848Sjkim push %r13 174289848Sjkim 175289848Sjkim mov 8*0($a_ptr), $a0 176289848Sjkim mov 8*1($a_ptr), $a1 177289848Sjkim mov 8*2($a_ptr), $a2 178289848Sjkim mov $a0, $t0 179289848Sjkim mov 8*3($a_ptr), $a3 180289848Sjkim lea .Lpoly(%rip), $a_ptr 181289848Sjkim 182289848Sjkim mov $a1, $t1 183289848Sjkim xor $t4, $t4 184289848Sjkim add 8*0($a_ptr), $a0 185289848Sjkim mov $a2, $t2 186289848Sjkim adc 8*1($a_ptr), $a1 187289848Sjkim adc 8*2($a_ptr), $a2 188289848Sjkim mov $a3, $t3 189289848Sjkim adc 8*3($a_ptr), $a3 190289848Sjkim adc \$0, $t4 191289848Sjkim xor $a_ptr, $a_ptr # borrow $a_ptr 192289848Sjkim test \$1, $t0 193289848Sjkim 194289848Sjkim cmovz $t0, $a0 195289848Sjkim cmovz $t1, $a1 196289848Sjkim cmovz $t2, $a2 197289848Sjkim cmovz $t3, $a3 198289848Sjkim cmovz $a_ptr, $t4 199289848Sjkim 200289848Sjkim mov $a1, $t0 # a0:a3>>1 201289848Sjkim shr \$1, $a0 202289848Sjkim shl \$63, $t0 203289848Sjkim mov $a2, $t1 204289848Sjkim shr \$1, $a1 205289848Sjkim or $t0, $a0 206289848Sjkim shl \$63, $t1 207289848Sjkim mov $a3, $t2 208289848Sjkim shr \$1, $a2 209289848Sjkim or $t1, $a1 210289848Sjkim shl \$63, $t2 211289848Sjkim shr \$1, $a3 212289848Sjkim shl \$63, $t4 213289848Sjkim or $t2, $a2 214289848Sjkim or $t4, $a3 215289848Sjkim 216289848Sjkim mov $a0, 8*0($r_ptr) 217289848Sjkim mov $a1, 8*1($r_ptr) 218289848Sjkim mov $a2, 8*2($r_ptr) 219289848Sjkim mov $a3, 8*3($r_ptr) 220289848Sjkim 221289848Sjkim pop %r13 222289848Sjkim pop %r12 223289848Sjkim ret 224289848Sjkim.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 225289848Sjkim 226289848Sjkim################################################################################ 227289848Sjkim# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]); 228289848Sjkim.globl ecp_nistz256_mul_by_3 229289848Sjkim.type ecp_nistz256_mul_by_3,\@function,2 230289848Sjkim.align 32 231289848Sjkimecp_nistz256_mul_by_3: 232289848Sjkim push %r12 233289848Sjkim push %r13 234289848Sjkim 235289848Sjkim mov 8*0($a_ptr), $a0 236289848Sjkim xor $t4, $t4 237289848Sjkim mov 8*1($a_ptr), $a1 238289848Sjkim add $a0, $a0 # a0:a3+a0:a3 239289848Sjkim mov 8*2($a_ptr), $a2 240289848Sjkim adc $a1, $a1 241289848Sjkim mov 8*3($a_ptr), $a3 242289848Sjkim mov $a0, $t0 243289848Sjkim adc $a2, $a2 244289848Sjkim adc $a3, $a3 245289848Sjkim mov $a1, $t1 246289848Sjkim adc \$0, $t4 247289848Sjkim 248289848Sjkim sub \$-1, $a0 249289848Sjkim mov $a2, $t2 250289848Sjkim sbb .Lpoly+8*1(%rip), $a1 251289848Sjkim sbb \$0, $a2 252289848Sjkim mov $a3, $t3 253289848Sjkim sbb .Lpoly+8*3(%rip), $a3 254306195Sjkim sbb \$0, $t4 255289848Sjkim 256306195Sjkim cmovc $t0, $a0 257306195Sjkim cmovc $t1, $a1 258306195Sjkim cmovc $t2, $a2 259306195Sjkim cmovc $t3, $a3 260289848Sjkim 261289848Sjkim xor $t4, $t4 262289848Sjkim add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3] 263289848Sjkim adc 8*1($a_ptr), $a1 264289848Sjkim mov $a0, $t0 265289848Sjkim adc 8*2($a_ptr), $a2 266289848Sjkim adc 8*3($a_ptr), $a3 267289848Sjkim mov $a1, $t1 268289848Sjkim adc \$0, $t4 269289848Sjkim 270289848Sjkim sub \$-1, $a0 271289848Sjkim mov $a2, $t2 272289848Sjkim sbb .Lpoly+8*1(%rip), $a1 273289848Sjkim sbb \$0, $a2 274289848Sjkim mov $a3, $t3 275289848Sjkim sbb .Lpoly+8*3(%rip), $a3 276306195Sjkim sbb \$0, $t4 277289848Sjkim 278306195Sjkim cmovc $t0, $a0 279306195Sjkim cmovc $t1, $a1 280289848Sjkim mov $a0, 8*0($r_ptr) 281306195Sjkim cmovc $t2, $a2 282289848Sjkim mov $a1, 8*1($r_ptr) 283306195Sjkim cmovc $t3, $a3 284289848Sjkim mov $a2, 8*2($r_ptr) 285289848Sjkim mov $a3, 8*3($r_ptr) 286289848Sjkim 287289848Sjkim pop %r13 288289848Sjkim pop %r12 289289848Sjkim ret 290289848Sjkim.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 291289848Sjkim 292289848Sjkim################################################################################ 293289848Sjkim# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]); 294289848Sjkim.globl ecp_nistz256_add 295289848Sjkim.type ecp_nistz256_add,\@function,3 296289848Sjkim.align 32 297289848Sjkimecp_nistz256_add: 298289848Sjkim push %r12 299289848Sjkim push %r13 300289848Sjkim 301289848Sjkim mov 8*0($a_ptr), $a0 302289848Sjkim xor $t4, $t4 303289848Sjkim mov 8*1($a_ptr), $a1 304289848Sjkim mov 8*2($a_ptr), $a2 305289848Sjkim mov 8*3($a_ptr), $a3 306289848Sjkim lea .Lpoly(%rip), $a_ptr 307289848Sjkim 308289848Sjkim add 8*0($b_ptr), $a0 309289848Sjkim adc 8*1($b_ptr), $a1 310289848Sjkim mov $a0, $t0 311289848Sjkim adc 8*2($b_ptr), $a2 312289848Sjkim adc 8*3($b_ptr), $a3 313289848Sjkim mov $a1, $t1 314289848Sjkim adc \$0, $t4 315289848Sjkim 316289848Sjkim sub 8*0($a_ptr), $a0 317289848Sjkim mov $a2, $t2 318289848Sjkim sbb 8*1($a_ptr), $a1 319289848Sjkim sbb 8*2($a_ptr), $a2 320289848Sjkim mov $a3, $t3 321289848Sjkim sbb 8*3($a_ptr), $a3 322306195Sjkim sbb \$0, $t4 323289848Sjkim 324306195Sjkim cmovc $t0, $a0 325306195Sjkim cmovc $t1, $a1 326289848Sjkim mov $a0, 8*0($r_ptr) 327306195Sjkim cmovc $t2, $a2 328289848Sjkim mov $a1, 8*1($r_ptr) 329306195Sjkim cmovc $t3, $a3 330289848Sjkim mov $a2, 8*2($r_ptr) 331289848Sjkim mov $a3, 8*3($r_ptr) 332289848Sjkim 333289848Sjkim pop %r13 334289848Sjkim pop %r12 335289848Sjkim ret 336289848Sjkim.size ecp_nistz256_add,.-ecp_nistz256_add 337289848Sjkim 338289848Sjkim################################################################################ 339289848Sjkim# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]); 340289848Sjkim.globl ecp_nistz256_sub 341289848Sjkim.type ecp_nistz256_sub,\@function,3 342289848Sjkim.align 32 343289848Sjkimecp_nistz256_sub: 344289848Sjkim push %r12 345289848Sjkim push %r13 346289848Sjkim 347289848Sjkim mov 8*0($a_ptr), $a0 348289848Sjkim xor $t4, $t4 349289848Sjkim mov 8*1($a_ptr), $a1 350289848Sjkim mov 8*2($a_ptr), $a2 351289848Sjkim mov 8*3($a_ptr), $a3 352289848Sjkim lea .Lpoly(%rip), $a_ptr 353289848Sjkim 354289848Sjkim sub 8*0($b_ptr), $a0 355289848Sjkim sbb 8*1($b_ptr), $a1 356289848Sjkim mov $a0, $t0 357289848Sjkim sbb 8*2($b_ptr), $a2 358289848Sjkim sbb 8*3($b_ptr), $a3 359289848Sjkim mov $a1, $t1 360289848Sjkim sbb \$0, $t4 361289848Sjkim 362289848Sjkim add 8*0($a_ptr), $a0 363289848Sjkim mov $a2, $t2 364289848Sjkim adc 8*1($a_ptr), $a1 365289848Sjkim adc 8*2($a_ptr), $a2 366289848Sjkim mov $a3, $t3 367289848Sjkim adc 8*3($a_ptr), $a3 368289848Sjkim test $t4, $t4 369289848Sjkim 370289848Sjkim cmovz $t0, $a0 371289848Sjkim cmovz $t1, $a1 372289848Sjkim mov $a0, 8*0($r_ptr) 373289848Sjkim cmovz $t2, $a2 374289848Sjkim mov $a1, 8*1($r_ptr) 375289848Sjkim cmovz $t3, $a3 376289848Sjkim mov $a2, 8*2($r_ptr) 377289848Sjkim mov $a3, 8*3($r_ptr) 378289848Sjkim 379289848Sjkim pop %r13 380289848Sjkim pop %r12 381289848Sjkim ret 382289848Sjkim.size ecp_nistz256_sub,.-ecp_nistz256_sub 383289848Sjkim 384289848Sjkim################################################################################ 385289848Sjkim# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]); 386289848Sjkim.globl ecp_nistz256_neg 387289848Sjkim.type ecp_nistz256_neg,\@function,2 388289848Sjkim.align 32 389289848Sjkimecp_nistz256_neg: 390289848Sjkim push %r12 391289848Sjkim push %r13 392289848Sjkim 393289848Sjkim xor $a0, $a0 394289848Sjkim xor $a1, $a1 395289848Sjkim xor $a2, $a2 396289848Sjkim xor $a3, $a3 397289848Sjkim xor $t4, $t4 398289848Sjkim 399289848Sjkim sub 8*0($a_ptr), $a0 400289848Sjkim sbb 8*1($a_ptr), $a1 401289848Sjkim sbb 8*2($a_ptr), $a2 402289848Sjkim mov $a0, $t0 403289848Sjkim sbb 8*3($a_ptr), $a3 404289848Sjkim lea .Lpoly(%rip), $a_ptr 405289848Sjkim mov $a1, $t1 406289848Sjkim sbb \$0, $t4 407289848Sjkim 408289848Sjkim add 8*0($a_ptr), $a0 409289848Sjkim mov $a2, $t2 410289848Sjkim adc 8*1($a_ptr), $a1 411289848Sjkim adc 8*2($a_ptr), $a2 412289848Sjkim mov $a3, $t3 413289848Sjkim adc 8*3($a_ptr), $a3 414289848Sjkim test $t4, $t4 415289848Sjkim 416289848Sjkim cmovz $t0, $a0 417289848Sjkim cmovz $t1, $a1 418289848Sjkim mov $a0, 8*0($r_ptr) 419289848Sjkim cmovz $t2, $a2 420289848Sjkim mov $a1, 8*1($r_ptr) 421289848Sjkim cmovz $t3, $a3 422289848Sjkim mov $a2, 8*2($r_ptr) 423289848Sjkim mov $a3, 8*3($r_ptr) 424289848Sjkim 425289848Sjkim pop %r13 426289848Sjkim pop %r12 427289848Sjkim ret 428289848Sjkim.size ecp_nistz256_neg,.-ecp_nistz256_neg 429289848Sjkim___ 430289848Sjkim} 431289848Sjkim{ 432289848Sjkimmy ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx"); 433289848Sjkimmy ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15)); 434289848Sjkimmy ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax"); 435289848Sjkimmy ($poly1,$poly3)=($acc6,$acc7); 436289848Sjkim 437289848Sjkim$code.=<<___; 438289848Sjkim################################################################################ 439289848Sjkim# void ecp_nistz256_to_mont( 440289848Sjkim# uint64_t res[4], 441289848Sjkim# uint64_t in[4]); 442289848Sjkim.globl ecp_nistz256_to_mont 443289848Sjkim.type ecp_nistz256_to_mont,\@function,2 444289848Sjkim.align 32 445289848Sjkimecp_nistz256_to_mont: 446289848Sjkim___ 447289848Sjkim$code.=<<___ if ($addx); 448289848Sjkim mov \$0x80100, %ecx 449289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 450289848Sjkim___ 451289848Sjkim$code.=<<___; 452289848Sjkim lea .LRR(%rip), $b_org 453289848Sjkim jmp .Lmul_mont 454289848Sjkim.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont 455289848Sjkim 456289848Sjkim################################################################################ 457289848Sjkim# void ecp_nistz256_mul_mont( 458289848Sjkim# uint64_t res[4], 459289848Sjkim# uint64_t a[4], 460289848Sjkim# uint64_t b[4]); 461289848Sjkim 462289848Sjkim.globl ecp_nistz256_mul_mont 463289848Sjkim.type ecp_nistz256_mul_mont,\@function,3 464289848Sjkim.align 32 465289848Sjkimecp_nistz256_mul_mont: 466289848Sjkim___ 467289848Sjkim$code.=<<___ if ($addx); 468289848Sjkim mov \$0x80100, %ecx 469289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 470289848Sjkim___ 471289848Sjkim$code.=<<___; 472289848Sjkim.Lmul_mont: 473289848Sjkim push %rbp 474289848Sjkim push %rbx 475289848Sjkim push %r12 476289848Sjkim push %r13 477289848Sjkim push %r14 478289848Sjkim push %r15 479289848Sjkim___ 480289848Sjkim$code.=<<___ if ($addx); 481289848Sjkim cmp \$0x80100, %ecx 482289848Sjkim je .Lmul_montx 483289848Sjkim___ 484289848Sjkim$code.=<<___; 485289848Sjkim mov $b_org, $b_ptr 486289848Sjkim mov 8*0($b_org), %rax 487289848Sjkim mov 8*0($a_ptr), $acc1 488289848Sjkim mov 8*1($a_ptr), $acc2 489289848Sjkim mov 8*2($a_ptr), $acc3 490289848Sjkim mov 8*3($a_ptr), $acc4 491289848Sjkim 492289848Sjkim call __ecp_nistz256_mul_montq 493289848Sjkim___ 494289848Sjkim$code.=<<___ if ($addx); 495289848Sjkim jmp .Lmul_mont_done 496289848Sjkim 497289848Sjkim.align 32 498289848Sjkim.Lmul_montx: 499289848Sjkim mov $b_org, $b_ptr 500289848Sjkim mov 8*0($b_org), %rdx 501289848Sjkim mov 8*0($a_ptr), $acc1 502289848Sjkim mov 8*1($a_ptr), $acc2 503289848Sjkim mov 8*2($a_ptr), $acc3 504289848Sjkim mov 8*3($a_ptr), $acc4 505289848Sjkim lea -128($a_ptr), $a_ptr # control u-op density 506289848Sjkim 507289848Sjkim call __ecp_nistz256_mul_montx 508289848Sjkim___ 509289848Sjkim$code.=<<___; 510289848Sjkim.Lmul_mont_done: 511289848Sjkim pop %r15 512289848Sjkim pop %r14 513289848Sjkim pop %r13 514289848Sjkim pop %r12 515289848Sjkim pop %rbx 516289848Sjkim pop %rbp 517289848Sjkim ret 518289848Sjkim.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont 519289848Sjkim 520289848Sjkim.type __ecp_nistz256_mul_montq,\@abi-omnipotent 521289848Sjkim.align 32 522289848Sjkim__ecp_nistz256_mul_montq: 523289848Sjkim ######################################################################## 524289848Sjkim # Multiply a by b[0] 525289848Sjkim mov %rax, $t1 526289848Sjkim mulq $acc1 527289848Sjkim mov .Lpoly+8*1(%rip),$poly1 528289848Sjkim mov %rax, $acc0 529289848Sjkim mov $t1, %rax 530289848Sjkim mov %rdx, $acc1 531289848Sjkim 532289848Sjkim mulq $acc2 533289848Sjkim mov .Lpoly+8*3(%rip),$poly3 534289848Sjkim add %rax, $acc1 535289848Sjkim mov $t1, %rax 536289848Sjkim adc \$0, %rdx 537289848Sjkim mov %rdx, $acc2 538289848Sjkim 539289848Sjkim mulq $acc3 540289848Sjkim add %rax, $acc2 541289848Sjkim mov $t1, %rax 542289848Sjkim adc \$0, %rdx 543289848Sjkim mov %rdx, $acc3 544289848Sjkim 545289848Sjkim mulq $acc4 546289848Sjkim add %rax, $acc3 547289848Sjkim mov $acc0, %rax 548289848Sjkim adc \$0, %rdx 549289848Sjkim xor $acc5, $acc5 550289848Sjkim mov %rdx, $acc4 551289848Sjkim 552289848Sjkim ######################################################################## 553289848Sjkim # First reduction step 554289848Sjkim # Basically now we want to multiply acc[0] by p256, 555289848Sjkim # and add the result to the acc. 556289848Sjkim # Due to the special form of p256 we do some optimizations 557289848Sjkim # 558289848Sjkim # acc[0] x p256[0..1] = acc[0] x 2^96 - acc[0] 559289848Sjkim # then we add acc[0] and get acc[0] x 2^96 560289848Sjkim 561289848Sjkim mov $acc0, $t1 562289848Sjkim shl \$32, $acc0 563289848Sjkim mulq $poly3 564289848Sjkim shr \$32, $t1 565289848Sjkim add $acc0, $acc1 # +=acc[0]<<96 566289848Sjkim adc $t1, $acc2 567289848Sjkim adc %rax, $acc3 568289848Sjkim mov 8*1($b_ptr), %rax 569289848Sjkim adc %rdx, $acc4 570289848Sjkim adc \$0, $acc5 571289848Sjkim xor $acc0, $acc0 572289848Sjkim 573289848Sjkim ######################################################################## 574289848Sjkim # Multiply by b[1] 575289848Sjkim mov %rax, $t1 576289848Sjkim mulq 8*0($a_ptr) 577289848Sjkim add %rax, $acc1 578289848Sjkim mov $t1, %rax 579289848Sjkim adc \$0, %rdx 580289848Sjkim mov %rdx, $t0 581289848Sjkim 582289848Sjkim mulq 8*1($a_ptr) 583289848Sjkim add $t0, $acc2 584289848Sjkim adc \$0, %rdx 585289848Sjkim add %rax, $acc2 586289848Sjkim mov $t1, %rax 587289848Sjkim adc \$0, %rdx 588289848Sjkim mov %rdx, $t0 589289848Sjkim 590289848Sjkim mulq 8*2($a_ptr) 591289848Sjkim add $t0, $acc3 592289848Sjkim adc \$0, %rdx 593289848Sjkim add %rax, $acc3 594289848Sjkim mov $t1, %rax 595289848Sjkim adc \$0, %rdx 596289848Sjkim mov %rdx, $t0 597289848Sjkim 598289848Sjkim mulq 8*3($a_ptr) 599289848Sjkim add $t0, $acc4 600289848Sjkim adc \$0, %rdx 601289848Sjkim add %rax, $acc4 602289848Sjkim mov $acc1, %rax 603289848Sjkim adc %rdx, $acc5 604289848Sjkim adc \$0, $acc0 605289848Sjkim 606289848Sjkim ######################################################################## 607289848Sjkim # Second reduction step 608289848Sjkim mov $acc1, $t1 609289848Sjkim shl \$32, $acc1 610289848Sjkim mulq $poly3 611289848Sjkim shr \$32, $t1 612289848Sjkim add $acc1, $acc2 613289848Sjkim adc $t1, $acc3 614289848Sjkim adc %rax, $acc4 615289848Sjkim mov 8*2($b_ptr), %rax 616289848Sjkim adc %rdx, $acc5 617289848Sjkim adc \$0, $acc0 618289848Sjkim xor $acc1, $acc1 619289848Sjkim 620289848Sjkim ######################################################################## 621289848Sjkim # Multiply by b[2] 622289848Sjkim mov %rax, $t1 623289848Sjkim mulq 8*0($a_ptr) 624289848Sjkim add %rax, $acc2 625289848Sjkim mov $t1, %rax 626289848Sjkim adc \$0, %rdx 627289848Sjkim mov %rdx, $t0 628289848Sjkim 629289848Sjkim mulq 8*1($a_ptr) 630289848Sjkim add $t0, $acc3 631289848Sjkim adc \$0, %rdx 632289848Sjkim add %rax, $acc3 633289848Sjkim mov $t1, %rax 634289848Sjkim adc \$0, %rdx 635289848Sjkim mov %rdx, $t0 636289848Sjkim 637289848Sjkim mulq 8*2($a_ptr) 638289848Sjkim add $t0, $acc4 639289848Sjkim adc \$0, %rdx 640289848Sjkim add %rax, $acc4 641289848Sjkim mov $t1, %rax 642289848Sjkim adc \$0, %rdx 643289848Sjkim mov %rdx, $t0 644289848Sjkim 645289848Sjkim mulq 8*3($a_ptr) 646289848Sjkim add $t0, $acc5 647289848Sjkim adc \$0, %rdx 648289848Sjkim add %rax, $acc5 649289848Sjkim mov $acc2, %rax 650289848Sjkim adc %rdx, $acc0 651289848Sjkim adc \$0, $acc1 652289848Sjkim 653289848Sjkim ######################################################################## 654289848Sjkim # Third reduction step 655289848Sjkim mov $acc2, $t1 656289848Sjkim shl \$32, $acc2 657289848Sjkim mulq $poly3 658289848Sjkim shr \$32, $t1 659289848Sjkim add $acc2, $acc3 660289848Sjkim adc $t1, $acc4 661289848Sjkim adc %rax, $acc5 662289848Sjkim mov 8*3($b_ptr), %rax 663289848Sjkim adc %rdx, $acc0 664289848Sjkim adc \$0, $acc1 665289848Sjkim xor $acc2, $acc2 666289848Sjkim 667289848Sjkim ######################################################################## 668289848Sjkim # Multiply by b[3] 669289848Sjkim mov %rax, $t1 670289848Sjkim mulq 8*0($a_ptr) 671289848Sjkim add %rax, $acc3 672289848Sjkim mov $t1, %rax 673289848Sjkim adc \$0, %rdx 674289848Sjkim mov %rdx, $t0 675289848Sjkim 676289848Sjkim mulq 8*1($a_ptr) 677289848Sjkim add $t0, $acc4 678289848Sjkim adc \$0, %rdx 679289848Sjkim add %rax, $acc4 680289848Sjkim mov $t1, %rax 681289848Sjkim adc \$0, %rdx 682289848Sjkim mov %rdx, $t0 683289848Sjkim 684289848Sjkim mulq 8*2($a_ptr) 685289848Sjkim add $t0, $acc5 686289848Sjkim adc \$0, %rdx 687289848Sjkim add %rax, $acc5 688289848Sjkim mov $t1, %rax 689289848Sjkim adc \$0, %rdx 690289848Sjkim mov %rdx, $t0 691289848Sjkim 692289848Sjkim mulq 8*3($a_ptr) 693289848Sjkim add $t0, $acc0 694289848Sjkim adc \$0, %rdx 695289848Sjkim add %rax, $acc0 696289848Sjkim mov $acc3, %rax 697289848Sjkim adc %rdx, $acc1 698289848Sjkim adc \$0, $acc2 699289848Sjkim 700289848Sjkim ######################################################################## 701289848Sjkim # Final reduction step 702289848Sjkim mov $acc3, $t1 703289848Sjkim shl \$32, $acc3 704289848Sjkim mulq $poly3 705289848Sjkim shr \$32, $t1 706289848Sjkim add $acc3, $acc4 707289848Sjkim adc $t1, $acc5 708289848Sjkim mov $acc4, $t0 709289848Sjkim adc %rax, $acc0 710289848Sjkim adc %rdx, $acc1 711289848Sjkim mov $acc5, $t1 712289848Sjkim adc \$0, $acc2 713289848Sjkim 714289848Sjkim ######################################################################## 715289848Sjkim # Branch-less conditional subtraction of P 716289848Sjkim sub \$-1, $acc4 # .Lpoly[0] 717289848Sjkim mov $acc0, $t2 718289848Sjkim sbb $poly1, $acc5 # .Lpoly[1] 719289848Sjkim sbb \$0, $acc0 # .Lpoly[2] 720289848Sjkim mov $acc1, $t3 721289848Sjkim sbb $poly3, $acc1 # .Lpoly[3] 722289848Sjkim sbb \$0, $acc2 723289848Sjkim 724289848Sjkim cmovc $t0, $acc4 725289848Sjkim cmovc $t1, $acc5 726289848Sjkim mov $acc4, 8*0($r_ptr) 727289848Sjkim cmovc $t2, $acc0 728289848Sjkim mov $acc5, 8*1($r_ptr) 729289848Sjkim cmovc $t3, $acc1 730289848Sjkim mov $acc0, 8*2($r_ptr) 731289848Sjkim mov $acc1, 8*3($r_ptr) 732289848Sjkim 733289848Sjkim ret 734289848Sjkim.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq 735289848Sjkim 736289848Sjkim################################################################################ 737289848Sjkim# void ecp_nistz256_sqr_mont( 738289848Sjkim# uint64_t res[4], 739289848Sjkim# uint64_t a[4]); 740289848Sjkim 741289848Sjkim# we optimize the square according to S.Gueron and V.Krasnov, 742289848Sjkim# "Speeding up Big-Number Squaring" 743289848Sjkim.globl ecp_nistz256_sqr_mont 744289848Sjkim.type ecp_nistz256_sqr_mont,\@function,2 745289848Sjkim.align 32 746289848Sjkimecp_nistz256_sqr_mont: 747289848Sjkim___ 748289848Sjkim$code.=<<___ if ($addx); 749289848Sjkim mov \$0x80100, %ecx 750289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 751289848Sjkim___ 752289848Sjkim$code.=<<___; 753289848Sjkim push %rbp 754289848Sjkim push %rbx 755289848Sjkim push %r12 756289848Sjkim push %r13 757289848Sjkim push %r14 758289848Sjkim push %r15 759289848Sjkim___ 760289848Sjkim$code.=<<___ if ($addx); 761289848Sjkim cmp \$0x80100, %ecx 762289848Sjkim je .Lsqr_montx 763289848Sjkim___ 764289848Sjkim$code.=<<___; 765289848Sjkim mov 8*0($a_ptr), %rax 766289848Sjkim mov 8*1($a_ptr), $acc6 767289848Sjkim mov 8*2($a_ptr), $acc7 768289848Sjkim mov 8*3($a_ptr), $acc0 769289848Sjkim 770289848Sjkim call __ecp_nistz256_sqr_montq 771289848Sjkim___ 772289848Sjkim$code.=<<___ if ($addx); 773289848Sjkim jmp .Lsqr_mont_done 774289848Sjkim 775289848Sjkim.align 32 776289848Sjkim.Lsqr_montx: 777289848Sjkim mov 8*0($a_ptr), %rdx 778289848Sjkim mov 8*1($a_ptr), $acc6 779289848Sjkim mov 8*2($a_ptr), $acc7 780289848Sjkim mov 8*3($a_ptr), $acc0 781289848Sjkim lea -128($a_ptr), $a_ptr # control u-op density 782289848Sjkim 783289848Sjkim call __ecp_nistz256_sqr_montx 784289848Sjkim___ 785289848Sjkim$code.=<<___; 786289848Sjkim.Lsqr_mont_done: 787289848Sjkim pop %r15 788289848Sjkim pop %r14 789289848Sjkim pop %r13 790289848Sjkim pop %r12 791289848Sjkim pop %rbx 792289848Sjkim pop %rbp 793289848Sjkim ret 794289848Sjkim.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont 795289848Sjkim 796289848Sjkim.type __ecp_nistz256_sqr_montq,\@abi-omnipotent 797289848Sjkim.align 32 798289848Sjkim__ecp_nistz256_sqr_montq: 799289848Sjkim mov %rax, $acc5 800289848Sjkim mulq $acc6 # a[1]*a[0] 801289848Sjkim mov %rax, $acc1 802289848Sjkim mov $acc7, %rax 803289848Sjkim mov %rdx, $acc2 804289848Sjkim 805289848Sjkim mulq $acc5 # a[0]*a[2] 806289848Sjkim add %rax, $acc2 807289848Sjkim mov $acc0, %rax 808289848Sjkim adc \$0, %rdx 809289848Sjkim mov %rdx, $acc3 810289848Sjkim 811289848Sjkim mulq $acc5 # a[0]*a[3] 812289848Sjkim add %rax, $acc3 813289848Sjkim mov $acc7, %rax 814289848Sjkim adc \$0, %rdx 815289848Sjkim mov %rdx, $acc4 816289848Sjkim 817289848Sjkim ################################# 818289848Sjkim mulq $acc6 # a[1]*a[2] 819289848Sjkim add %rax, $acc3 820289848Sjkim mov $acc0, %rax 821289848Sjkim adc \$0, %rdx 822289848Sjkim mov %rdx, $t1 823289848Sjkim 824289848Sjkim mulq $acc6 # a[1]*a[3] 825289848Sjkim add %rax, $acc4 826289848Sjkim mov $acc0, %rax 827289848Sjkim adc \$0, %rdx 828289848Sjkim add $t1, $acc4 829289848Sjkim mov %rdx, $acc5 830289848Sjkim adc \$0, $acc5 831289848Sjkim 832289848Sjkim ################################# 833289848Sjkim mulq $acc7 # a[2]*a[3] 834289848Sjkim xor $acc7, $acc7 835289848Sjkim add %rax, $acc5 836289848Sjkim mov 8*0($a_ptr), %rax 837289848Sjkim mov %rdx, $acc6 838289848Sjkim adc \$0, $acc6 839289848Sjkim 840289848Sjkim add $acc1, $acc1 # acc1:6<<1 841289848Sjkim adc $acc2, $acc2 842289848Sjkim adc $acc3, $acc3 843289848Sjkim adc $acc4, $acc4 844289848Sjkim adc $acc5, $acc5 845289848Sjkim adc $acc6, $acc6 846289848Sjkim adc \$0, $acc7 847289848Sjkim 848289848Sjkim mulq %rax 849289848Sjkim mov %rax, $acc0 850289848Sjkim mov 8*1($a_ptr), %rax 851289848Sjkim mov %rdx, $t0 852289848Sjkim 853289848Sjkim mulq %rax 854289848Sjkim add $t0, $acc1 855289848Sjkim adc %rax, $acc2 856289848Sjkim mov 8*2($a_ptr), %rax 857289848Sjkim adc \$0, %rdx 858289848Sjkim mov %rdx, $t0 859289848Sjkim 860289848Sjkim mulq %rax 861289848Sjkim add $t0, $acc3 862289848Sjkim adc %rax, $acc4 863289848Sjkim mov 8*3($a_ptr), %rax 864289848Sjkim adc \$0, %rdx 865289848Sjkim mov %rdx, $t0 866289848Sjkim 867289848Sjkim mulq %rax 868289848Sjkim add $t0, $acc5 869289848Sjkim adc %rax, $acc6 870289848Sjkim mov $acc0, %rax 871289848Sjkim adc %rdx, $acc7 872289848Sjkim 873289848Sjkim mov .Lpoly+8*1(%rip), $a_ptr 874289848Sjkim mov .Lpoly+8*3(%rip), $t1 875289848Sjkim 876289848Sjkim ########################################## 877289848Sjkim # Now the reduction 878289848Sjkim # First iteration 879289848Sjkim mov $acc0, $t0 880289848Sjkim shl \$32, $acc0 881289848Sjkim mulq $t1 882289848Sjkim shr \$32, $t0 883289848Sjkim add $acc0, $acc1 # +=acc[0]<<96 884289848Sjkim adc $t0, $acc2 885289848Sjkim adc %rax, $acc3 886289848Sjkim mov $acc1, %rax 887289848Sjkim adc \$0, %rdx 888289848Sjkim 889289848Sjkim ########################################## 890289848Sjkim # Second iteration 891289848Sjkim mov $acc1, $t0 892289848Sjkim shl \$32, $acc1 893289848Sjkim mov %rdx, $acc0 894289848Sjkim mulq $t1 895289848Sjkim shr \$32, $t0 896289848Sjkim add $acc1, $acc2 897289848Sjkim adc $t0, $acc3 898289848Sjkim adc %rax, $acc0 899289848Sjkim mov $acc2, %rax 900289848Sjkim adc \$0, %rdx 901289848Sjkim 902289848Sjkim ########################################## 903289848Sjkim # Third iteration 904289848Sjkim mov $acc2, $t0 905289848Sjkim shl \$32, $acc2 906289848Sjkim mov %rdx, $acc1 907289848Sjkim mulq $t1 908289848Sjkim shr \$32, $t0 909289848Sjkim add $acc2, $acc3 910289848Sjkim adc $t0, $acc0 911289848Sjkim adc %rax, $acc1 912289848Sjkim mov $acc3, %rax 913289848Sjkim adc \$0, %rdx 914289848Sjkim 915289848Sjkim ########################################### 916289848Sjkim # Last iteration 917289848Sjkim mov $acc3, $t0 918289848Sjkim shl \$32, $acc3 919289848Sjkim mov %rdx, $acc2 920289848Sjkim mulq $t1 921289848Sjkim shr \$32, $t0 922289848Sjkim add $acc3, $acc0 923289848Sjkim adc $t0, $acc1 924289848Sjkim adc %rax, $acc2 925289848Sjkim adc \$0, %rdx 926289848Sjkim xor $acc3, $acc3 927289848Sjkim 928289848Sjkim ############################################ 929289848Sjkim # Add the rest of the acc 930289848Sjkim add $acc0, $acc4 931289848Sjkim adc $acc1, $acc5 932289848Sjkim mov $acc4, $acc0 933289848Sjkim adc $acc2, $acc6 934289848Sjkim adc %rdx, $acc7 935289848Sjkim mov $acc5, $acc1 936289848Sjkim adc \$0, $acc3 937289848Sjkim 938289848Sjkim sub \$-1, $acc4 # .Lpoly[0] 939289848Sjkim mov $acc6, $acc2 940289848Sjkim sbb $a_ptr, $acc5 # .Lpoly[1] 941289848Sjkim sbb \$0, $acc6 # .Lpoly[2] 942289848Sjkim mov $acc7, $t0 943289848Sjkim sbb $t1, $acc7 # .Lpoly[3] 944289848Sjkim sbb \$0, $acc3 945289848Sjkim 946289848Sjkim cmovc $acc0, $acc4 947289848Sjkim cmovc $acc1, $acc5 948289848Sjkim mov $acc4, 8*0($r_ptr) 949289848Sjkim cmovc $acc2, $acc6 950289848Sjkim mov $acc5, 8*1($r_ptr) 951289848Sjkim cmovc $t0, $acc7 952289848Sjkim mov $acc6, 8*2($r_ptr) 953289848Sjkim mov $acc7, 8*3($r_ptr) 954289848Sjkim 955289848Sjkim ret 956289848Sjkim.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq 957289848Sjkim___ 958289848Sjkim 959289848Sjkimif ($addx) { 960289848Sjkim$code.=<<___; 961289848Sjkim.type __ecp_nistz256_mul_montx,\@abi-omnipotent 962289848Sjkim.align 32 963289848Sjkim__ecp_nistz256_mul_montx: 964289848Sjkim ######################################################################## 965289848Sjkim # Multiply by b[0] 966289848Sjkim mulx $acc1, $acc0, $acc1 967289848Sjkim mulx $acc2, $t0, $acc2 968289848Sjkim mov \$32, $poly1 969289848Sjkim xor $acc5, $acc5 # cf=0 970289848Sjkim mulx $acc3, $t1, $acc3 971289848Sjkim mov .Lpoly+8*3(%rip), $poly3 972289848Sjkim adc $t0, $acc1 973289848Sjkim mulx $acc4, $t0, $acc4 974289848Sjkim mov $acc0, %rdx 975289848Sjkim adc $t1, $acc2 976289848Sjkim shlx $poly1,$acc0,$t1 977289848Sjkim adc $t0, $acc3 978289848Sjkim shrx $poly1,$acc0,$t0 979289848Sjkim adc \$0, $acc4 980289848Sjkim 981289848Sjkim ######################################################################## 982289848Sjkim # First reduction step 983289848Sjkim add $t1, $acc1 984289848Sjkim adc $t0, $acc2 985289848Sjkim 986289848Sjkim mulx $poly3, $t0, $t1 987289848Sjkim mov 8*1($b_ptr), %rdx 988289848Sjkim adc $t0, $acc3 989289848Sjkim adc $t1, $acc4 990289848Sjkim adc \$0, $acc5 991289848Sjkim xor $acc0, $acc0 # $acc0=0,cf=0,of=0 992289848Sjkim 993289848Sjkim ######################################################################## 994289848Sjkim # Multiply by b[1] 995289848Sjkim mulx 8*0+128($a_ptr), $t0, $t1 996289848Sjkim adcx $t0, $acc1 997289848Sjkim adox $t1, $acc2 998289848Sjkim 999289848Sjkim mulx 8*1+128($a_ptr), $t0, $t1 1000289848Sjkim adcx $t0, $acc2 1001289848Sjkim adox $t1, $acc3 1002289848Sjkim 1003289848Sjkim mulx 8*2+128($a_ptr), $t0, $t1 1004289848Sjkim adcx $t0, $acc3 1005289848Sjkim adox $t1, $acc4 1006289848Sjkim 1007289848Sjkim mulx 8*3+128($a_ptr), $t0, $t1 1008289848Sjkim mov $acc1, %rdx 1009289848Sjkim adcx $t0, $acc4 1010289848Sjkim shlx $poly1, $acc1, $t0 1011289848Sjkim adox $t1, $acc5 1012289848Sjkim shrx $poly1, $acc1, $t1 1013289848Sjkim 1014289848Sjkim adcx $acc0, $acc5 1015289848Sjkim adox $acc0, $acc0 1016289848Sjkim adc \$0, $acc0 1017289848Sjkim 1018289848Sjkim ######################################################################## 1019289848Sjkim # Second reduction step 1020289848Sjkim add $t0, $acc2 1021289848Sjkim adc $t1, $acc3 1022289848Sjkim 1023289848Sjkim mulx $poly3, $t0, $t1 1024289848Sjkim mov 8*2($b_ptr), %rdx 1025289848Sjkim adc $t0, $acc4 1026289848Sjkim adc $t1, $acc5 1027289848Sjkim adc \$0, $acc0 1028289848Sjkim xor $acc1 ,$acc1 # $acc1=0,cf=0,of=0 1029289848Sjkim 1030289848Sjkim ######################################################################## 1031289848Sjkim # Multiply by b[2] 1032289848Sjkim mulx 8*0+128($a_ptr), $t0, $t1 1033289848Sjkim adcx $t0, $acc2 1034289848Sjkim adox $t1, $acc3 1035289848Sjkim 1036289848Sjkim mulx 8*1+128($a_ptr), $t0, $t1 1037289848Sjkim adcx $t0, $acc3 1038289848Sjkim adox $t1, $acc4 1039289848Sjkim 1040289848Sjkim mulx 8*2+128($a_ptr), $t0, $t1 1041289848Sjkim adcx $t0, $acc4 1042289848Sjkim adox $t1, $acc5 1043289848Sjkim 1044289848Sjkim mulx 8*3+128($a_ptr), $t0, $t1 1045289848Sjkim mov $acc2, %rdx 1046289848Sjkim adcx $t0, $acc5 1047289848Sjkim shlx $poly1, $acc2, $t0 1048289848Sjkim adox $t1, $acc0 1049289848Sjkim shrx $poly1, $acc2, $t1 1050289848Sjkim 1051289848Sjkim adcx $acc1, $acc0 1052289848Sjkim adox $acc1, $acc1 1053289848Sjkim adc \$0, $acc1 1054289848Sjkim 1055289848Sjkim ######################################################################## 1056289848Sjkim # Third reduction step 1057289848Sjkim add $t0, $acc3 1058289848Sjkim adc $t1, $acc4 1059289848Sjkim 1060289848Sjkim mulx $poly3, $t0, $t1 1061289848Sjkim mov 8*3($b_ptr), %rdx 1062289848Sjkim adc $t0, $acc5 1063289848Sjkim adc $t1, $acc0 1064289848Sjkim adc \$0, $acc1 1065289848Sjkim xor $acc2, $acc2 # $acc2=0,cf=0,of=0 1066289848Sjkim 1067289848Sjkim ######################################################################## 1068289848Sjkim # Multiply by b[3] 1069289848Sjkim mulx 8*0+128($a_ptr), $t0, $t1 1070289848Sjkim adcx $t0, $acc3 1071289848Sjkim adox $t1, $acc4 1072289848Sjkim 1073289848Sjkim mulx 8*1+128($a_ptr), $t0, $t1 1074289848Sjkim adcx $t0, $acc4 1075289848Sjkim adox $t1, $acc5 1076289848Sjkim 1077289848Sjkim mulx 8*2+128($a_ptr), $t0, $t1 1078289848Sjkim adcx $t0, $acc5 1079289848Sjkim adox $t1, $acc0 1080289848Sjkim 1081289848Sjkim mulx 8*3+128($a_ptr), $t0, $t1 1082289848Sjkim mov $acc3, %rdx 1083289848Sjkim adcx $t0, $acc0 1084289848Sjkim shlx $poly1, $acc3, $t0 1085289848Sjkim adox $t1, $acc1 1086289848Sjkim shrx $poly1, $acc3, $t1 1087289848Sjkim 1088289848Sjkim adcx $acc2, $acc1 1089289848Sjkim adox $acc2, $acc2 1090289848Sjkim adc \$0, $acc2 1091289848Sjkim 1092289848Sjkim ######################################################################## 1093289848Sjkim # Fourth reduction step 1094289848Sjkim add $t0, $acc4 1095289848Sjkim adc $t1, $acc5 1096289848Sjkim 1097289848Sjkim mulx $poly3, $t0, $t1 1098289848Sjkim mov $acc4, $t2 1099289848Sjkim mov .Lpoly+8*1(%rip), $poly1 1100289848Sjkim adc $t0, $acc0 1101289848Sjkim mov $acc5, $t3 1102289848Sjkim adc $t1, $acc1 1103289848Sjkim adc \$0, $acc2 1104289848Sjkim 1105289848Sjkim ######################################################################## 1106289848Sjkim # Branch-less conditional subtraction of P 1107289848Sjkim xor %eax, %eax 1108289848Sjkim mov $acc0, $t0 1109289848Sjkim sbb \$-1, $acc4 # .Lpoly[0] 1110289848Sjkim sbb $poly1, $acc5 # .Lpoly[1] 1111289848Sjkim sbb \$0, $acc0 # .Lpoly[2] 1112289848Sjkim mov $acc1, $t1 1113289848Sjkim sbb $poly3, $acc1 # .Lpoly[3] 1114289848Sjkim sbb \$0, $acc2 1115289848Sjkim 1116289848Sjkim cmovc $t2, $acc4 1117289848Sjkim cmovc $t3, $acc5 1118289848Sjkim mov $acc4, 8*0($r_ptr) 1119289848Sjkim cmovc $t0, $acc0 1120289848Sjkim mov $acc5, 8*1($r_ptr) 1121289848Sjkim cmovc $t1, $acc1 1122289848Sjkim mov $acc0, 8*2($r_ptr) 1123289848Sjkim mov $acc1, 8*3($r_ptr) 1124289848Sjkim 1125289848Sjkim ret 1126289848Sjkim.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx 1127289848Sjkim 1128289848Sjkim.type __ecp_nistz256_sqr_montx,\@abi-omnipotent 1129289848Sjkim.align 32 1130289848Sjkim__ecp_nistz256_sqr_montx: 1131289848Sjkim mulx $acc6, $acc1, $acc2 # a[0]*a[1] 1132289848Sjkim mulx $acc7, $t0, $acc3 # a[0]*a[2] 1133289848Sjkim xor %eax, %eax 1134289848Sjkim adc $t0, $acc2 1135289848Sjkim mulx $acc0, $t1, $acc4 # a[0]*a[3] 1136289848Sjkim mov $acc6, %rdx 1137289848Sjkim adc $t1, $acc3 1138289848Sjkim adc \$0, $acc4 1139289848Sjkim xor $acc5, $acc5 # $acc5=0,cf=0,of=0 1140289848Sjkim 1141289848Sjkim ################################# 1142289848Sjkim mulx $acc7, $t0, $t1 # a[1]*a[2] 1143289848Sjkim adcx $t0, $acc3 1144289848Sjkim adox $t1, $acc4 1145289848Sjkim 1146289848Sjkim mulx $acc0, $t0, $t1 # a[1]*a[3] 1147289848Sjkim mov $acc7, %rdx 1148289848Sjkim adcx $t0, $acc4 1149289848Sjkim adox $t1, $acc5 1150289848Sjkim adc \$0, $acc5 1151289848Sjkim 1152289848Sjkim ################################# 1153289848Sjkim mulx $acc0, $t0, $acc6 # a[2]*a[3] 1154289848Sjkim mov 8*0+128($a_ptr), %rdx 1155289848Sjkim xor $acc7, $acc7 # $acc7=0,cf=0,of=0 1156289848Sjkim adcx $acc1, $acc1 # acc1:6<<1 1157289848Sjkim adox $t0, $acc5 1158289848Sjkim adcx $acc2, $acc2 1159289848Sjkim adox $acc7, $acc6 # of=0 1160289848Sjkim 1161289848Sjkim mulx %rdx, $acc0, $t1 1162289848Sjkim mov 8*1+128($a_ptr), %rdx 1163289848Sjkim adcx $acc3, $acc3 1164289848Sjkim adox $t1, $acc1 1165289848Sjkim adcx $acc4, $acc4 1166289848Sjkim mulx %rdx, $t0, $t4 1167289848Sjkim mov 8*2+128($a_ptr), %rdx 1168289848Sjkim adcx $acc5, $acc5 1169289848Sjkim adox $t0, $acc2 1170289848Sjkim adcx $acc6, $acc6 1171289848Sjkim .byte 0x67 1172289848Sjkim mulx %rdx, $t0, $t1 1173289848Sjkim mov 8*3+128($a_ptr), %rdx 1174289848Sjkim adox $t4, $acc3 1175289848Sjkim adcx $acc7, $acc7 1176289848Sjkim adox $t0, $acc4 1177289848Sjkim mov \$32, $a_ptr 1178289848Sjkim adox $t1, $acc5 1179289848Sjkim .byte 0x67,0x67 1180289848Sjkim mulx %rdx, $t0, $t4 1181325337Sjkim mov .Lpoly+8*3(%rip), %rdx 1182289848Sjkim adox $t0, $acc6 1183289848Sjkim shlx $a_ptr, $acc0, $t0 1184289848Sjkim adox $t4, $acc7 1185289848Sjkim shrx $a_ptr, $acc0, $t4 1186325337Sjkim mov %rdx,$t1 1187289848Sjkim 1188289848Sjkim # reduction step 1 1189289848Sjkim add $t0, $acc1 1190289848Sjkim adc $t4, $acc2 1191289848Sjkim 1192325337Sjkim mulx $acc0, $t0, $acc0 1193289848Sjkim adc $t0, $acc3 1194289848Sjkim shlx $a_ptr, $acc1, $t0 1195289848Sjkim adc \$0, $acc0 1196289848Sjkim shrx $a_ptr, $acc1, $t4 1197289848Sjkim 1198289848Sjkim # reduction step 2 1199289848Sjkim add $t0, $acc2 1200289848Sjkim adc $t4, $acc3 1201289848Sjkim 1202325337Sjkim mulx $acc1, $t0, $acc1 1203289848Sjkim adc $t0, $acc0 1204289848Sjkim shlx $a_ptr, $acc2, $t0 1205289848Sjkim adc \$0, $acc1 1206289848Sjkim shrx $a_ptr, $acc2, $t4 1207289848Sjkim 1208289848Sjkim # reduction step 3 1209289848Sjkim add $t0, $acc3 1210289848Sjkim adc $t4, $acc0 1211289848Sjkim 1212325337Sjkim mulx $acc2, $t0, $acc2 1213289848Sjkim adc $t0, $acc1 1214289848Sjkim shlx $a_ptr, $acc3, $t0 1215289848Sjkim adc \$0, $acc2 1216289848Sjkim shrx $a_ptr, $acc3, $t4 1217289848Sjkim 1218289848Sjkim # reduction step 4 1219289848Sjkim add $t0, $acc0 1220289848Sjkim adc $t4, $acc1 1221289848Sjkim 1222325337Sjkim mulx $acc3, $t0, $acc3 1223289848Sjkim adc $t0, $acc2 1224289848Sjkim adc \$0, $acc3 1225289848Sjkim 1226325337Sjkim xor $t3, $t3 1227325337Sjkim add $acc0, $acc4 # accumulate upper half 1228289848Sjkim mov .Lpoly+8*1(%rip), $a_ptr 1229289848Sjkim adc $acc1, $acc5 1230289848Sjkim mov $acc4, $acc0 1231289848Sjkim adc $acc2, $acc6 1232289848Sjkim adc $acc3, $acc7 1233289848Sjkim mov $acc5, $acc1 1234289848Sjkim adc \$0, $t3 1235289848Sjkim 1236325337Sjkim sub \$-1, $acc4 # .Lpoly[0] 1237289848Sjkim mov $acc6, $acc2 1238289848Sjkim sbb $a_ptr, $acc5 # .Lpoly[1] 1239289848Sjkim sbb \$0, $acc6 # .Lpoly[2] 1240289848Sjkim mov $acc7, $acc3 1241289848Sjkim sbb $t1, $acc7 # .Lpoly[3] 1242289848Sjkim sbb \$0, $t3 1243289848Sjkim 1244289848Sjkim cmovc $acc0, $acc4 1245289848Sjkim cmovc $acc1, $acc5 1246289848Sjkim mov $acc4, 8*0($r_ptr) 1247289848Sjkim cmovc $acc2, $acc6 1248289848Sjkim mov $acc5, 8*1($r_ptr) 1249289848Sjkim cmovc $acc3, $acc7 1250289848Sjkim mov $acc6, 8*2($r_ptr) 1251289848Sjkim mov $acc7, 8*3($r_ptr) 1252289848Sjkim 1253289848Sjkim ret 1254289848Sjkim.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx 1255289848Sjkim___ 1256289848Sjkim} 1257289848Sjkim} 1258289848Sjkim{ 1259289848Sjkimmy ($r_ptr,$in_ptr)=("%rdi","%rsi"); 1260289848Sjkimmy ($acc0,$acc1,$acc2,$acc3)=map("%r$_",(8..11)); 1261289848Sjkimmy ($t0,$t1,$t2)=("%rcx","%r12","%r13"); 1262289848Sjkim 1263289848Sjkim$code.=<<___; 1264289848Sjkim################################################################################ 1265289848Sjkim# void ecp_nistz256_from_mont( 1266289848Sjkim# uint64_t res[4], 1267289848Sjkim# uint64_t in[4]); 1268289848Sjkim# This one performs Montgomery multiplication by 1, so we only need the reduction 1269289848Sjkim 1270289848Sjkim.globl ecp_nistz256_from_mont 1271289848Sjkim.type ecp_nistz256_from_mont,\@function,2 1272289848Sjkim.align 32 1273289848Sjkimecp_nistz256_from_mont: 1274289848Sjkim push %r12 1275289848Sjkim push %r13 1276289848Sjkim 1277289848Sjkim mov 8*0($in_ptr), %rax 1278289848Sjkim mov .Lpoly+8*3(%rip), $t2 1279289848Sjkim mov 8*1($in_ptr), $acc1 1280289848Sjkim mov 8*2($in_ptr), $acc2 1281289848Sjkim mov 8*3($in_ptr), $acc3 1282289848Sjkim mov %rax, $acc0 1283289848Sjkim mov .Lpoly+8*1(%rip), $t1 1284289848Sjkim 1285289848Sjkim ######################################### 1286289848Sjkim # First iteration 1287289848Sjkim mov %rax, $t0 1288289848Sjkim shl \$32, $acc0 1289289848Sjkim mulq $t2 1290289848Sjkim shr \$32, $t0 1291289848Sjkim add $acc0, $acc1 1292289848Sjkim adc $t0, $acc2 1293289848Sjkim adc %rax, $acc3 1294289848Sjkim mov $acc1, %rax 1295289848Sjkim adc \$0, %rdx 1296289848Sjkim 1297289848Sjkim ######################################### 1298289848Sjkim # Second iteration 1299289848Sjkim mov $acc1, $t0 1300289848Sjkim shl \$32, $acc1 1301289848Sjkim mov %rdx, $acc0 1302289848Sjkim mulq $t2 1303289848Sjkim shr \$32, $t0 1304289848Sjkim add $acc1, $acc2 1305289848Sjkim adc $t0, $acc3 1306289848Sjkim adc %rax, $acc0 1307289848Sjkim mov $acc2, %rax 1308289848Sjkim adc \$0, %rdx 1309289848Sjkim 1310289848Sjkim ########################################## 1311289848Sjkim # Third iteration 1312289848Sjkim mov $acc2, $t0 1313289848Sjkim shl \$32, $acc2 1314289848Sjkim mov %rdx, $acc1 1315289848Sjkim mulq $t2 1316289848Sjkim shr \$32, $t0 1317289848Sjkim add $acc2, $acc3 1318289848Sjkim adc $t0, $acc0 1319289848Sjkim adc %rax, $acc1 1320289848Sjkim mov $acc3, %rax 1321289848Sjkim adc \$0, %rdx 1322289848Sjkim 1323289848Sjkim ########################################### 1324289848Sjkim # Last iteration 1325289848Sjkim mov $acc3, $t0 1326289848Sjkim shl \$32, $acc3 1327289848Sjkim mov %rdx, $acc2 1328289848Sjkim mulq $t2 1329289848Sjkim shr \$32, $t0 1330289848Sjkim add $acc3, $acc0 1331289848Sjkim adc $t0, $acc1 1332289848Sjkim mov $acc0, $t0 1333289848Sjkim adc %rax, $acc2 1334289848Sjkim mov $acc1, $in_ptr 1335289848Sjkim adc \$0, %rdx 1336289848Sjkim 1337289848Sjkim ########################################### 1338289848Sjkim # Branch-less conditional subtraction 1339289848Sjkim sub \$-1, $acc0 1340289848Sjkim mov $acc2, %rax 1341289848Sjkim sbb $t1, $acc1 1342289848Sjkim sbb \$0, $acc2 1343289848Sjkim mov %rdx, $acc3 1344289848Sjkim sbb $t2, %rdx 1345289848Sjkim sbb $t2, $t2 1346289848Sjkim 1347289848Sjkim cmovnz $t0, $acc0 1348289848Sjkim cmovnz $in_ptr, $acc1 1349289848Sjkim mov $acc0, 8*0($r_ptr) 1350289848Sjkim cmovnz %rax, $acc2 1351289848Sjkim mov $acc1, 8*1($r_ptr) 1352289848Sjkim cmovz %rdx, $acc3 1353289848Sjkim mov $acc2, 8*2($r_ptr) 1354289848Sjkim mov $acc3, 8*3($r_ptr) 1355289848Sjkim 1356289848Sjkim pop %r13 1357289848Sjkim pop %r12 1358289848Sjkim ret 1359289848Sjkim.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont 1360289848Sjkim___ 1361289848Sjkim} 1362289848Sjkim{ 1363289848Sjkimmy ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx"); 1364289848Sjkimmy ($ONE,$INDEX,$Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("%xmm$_",(0..7)); 1365289848Sjkimmy ($M0,$T0a,$T0b,$T0c,$T0d,$T0e,$T0f,$TMP0)=map("%xmm$_",(8..15)); 1366289848Sjkimmy ($M1,$T2a,$T2b,$TMP2,$M2,$T2a,$T2b,$TMP2)=map("%xmm$_",(8..15)); 1367289848Sjkim 1368289848Sjkim$code.=<<___; 1369289848Sjkim################################################################################ 1370289848Sjkim# void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); 1371289848Sjkim.globl ecp_nistz256_select_w5 1372289848Sjkim.type ecp_nistz256_select_w5,\@abi-omnipotent 1373289848Sjkim.align 32 1374289848Sjkimecp_nistz256_select_w5: 1375289848Sjkim___ 1376289848Sjkim$code.=<<___ if ($avx>1); 1377289848Sjkim mov OPENSSL_ia32cap_P+8(%rip), %eax 1378289848Sjkim test \$`1<<5`, %eax 1379289848Sjkim jnz .Lavx2_select_w5 1380289848Sjkim___ 1381289848Sjkim$code.=<<___ if ($win64); 1382289848Sjkim lea -0x88(%rsp), %rax 1383289848Sjkim.LSEH_begin_ecp_nistz256_select_w5: 1384289848Sjkim .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp 1385289848Sjkim .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax) 1386289848Sjkim .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax) 1387289848Sjkim .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax) 1388289848Sjkim .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax) 1389289848Sjkim .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax) 1390289848Sjkim .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax) 1391289848Sjkim .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax) 1392289848Sjkim .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax) 1393289848Sjkim .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax) 1394289848Sjkim .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax) 1395289848Sjkim___ 1396289848Sjkim$code.=<<___; 1397289848Sjkim movdqa .LOne(%rip), $ONE 1398289848Sjkim movd $index, $INDEX 1399289848Sjkim 1400289848Sjkim pxor $Ra, $Ra 1401289848Sjkim pxor $Rb, $Rb 1402289848Sjkim pxor $Rc, $Rc 1403289848Sjkim pxor $Rd, $Rd 1404289848Sjkim pxor $Re, $Re 1405289848Sjkim pxor $Rf, $Rf 1406289848Sjkim 1407289848Sjkim movdqa $ONE, $M0 1408289848Sjkim pshufd \$0, $INDEX, $INDEX 1409289848Sjkim 1410289848Sjkim mov \$16, %rax 1411289848Sjkim.Lselect_loop_sse_w5: 1412289848Sjkim 1413289848Sjkim movdqa $M0, $TMP0 1414289848Sjkim paddd $ONE, $M0 1415289848Sjkim pcmpeqd $INDEX, $TMP0 1416289848Sjkim 1417289848Sjkim movdqa 16*0($in_t), $T0a 1418289848Sjkim movdqa 16*1($in_t), $T0b 1419289848Sjkim movdqa 16*2($in_t), $T0c 1420289848Sjkim movdqa 16*3($in_t), $T0d 1421289848Sjkim movdqa 16*4($in_t), $T0e 1422289848Sjkim movdqa 16*5($in_t), $T0f 1423289848Sjkim lea 16*6($in_t), $in_t 1424289848Sjkim 1425289848Sjkim pand $TMP0, $T0a 1426289848Sjkim pand $TMP0, $T0b 1427289848Sjkim por $T0a, $Ra 1428289848Sjkim pand $TMP0, $T0c 1429289848Sjkim por $T0b, $Rb 1430289848Sjkim pand $TMP0, $T0d 1431289848Sjkim por $T0c, $Rc 1432289848Sjkim pand $TMP0, $T0e 1433289848Sjkim por $T0d, $Rd 1434289848Sjkim pand $TMP0, $T0f 1435289848Sjkim por $T0e, $Re 1436289848Sjkim por $T0f, $Rf 1437289848Sjkim 1438289848Sjkim dec %rax 1439289848Sjkim jnz .Lselect_loop_sse_w5 1440289848Sjkim 1441289848Sjkim movdqu $Ra, 16*0($val) 1442289848Sjkim movdqu $Rb, 16*1($val) 1443289848Sjkim movdqu $Rc, 16*2($val) 1444289848Sjkim movdqu $Rd, 16*3($val) 1445289848Sjkim movdqu $Re, 16*4($val) 1446289848Sjkim movdqu $Rf, 16*5($val) 1447289848Sjkim___ 1448289848Sjkim$code.=<<___ if ($win64); 1449289848Sjkim movaps (%rsp), %xmm6 1450289848Sjkim movaps 0x10(%rsp), %xmm7 1451289848Sjkim movaps 0x20(%rsp), %xmm8 1452289848Sjkim movaps 0x30(%rsp), %xmm9 1453289848Sjkim movaps 0x40(%rsp), %xmm10 1454289848Sjkim movaps 0x50(%rsp), %xmm11 1455289848Sjkim movaps 0x60(%rsp), %xmm12 1456289848Sjkim movaps 0x70(%rsp), %xmm13 1457289848Sjkim movaps 0x80(%rsp), %xmm14 1458289848Sjkim movaps 0x90(%rsp), %xmm15 1459289848Sjkim lea 0xa8(%rsp), %rsp 1460289848Sjkim.LSEH_end_ecp_nistz256_select_w5: 1461289848Sjkim___ 1462289848Sjkim$code.=<<___; 1463289848Sjkim ret 1464289848Sjkim.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5 1465289848Sjkim 1466289848Sjkim################################################################################ 1467289848Sjkim# void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); 1468289848Sjkim.globl ecp_nistz256_select_w7 1469289848Sjkim.type ecp_nistz256_select_w7,\@abi-omnipotent 1470289848Sjkim.align 32 1471289848Sjkimecp_nistz256_select_w7: 1472289848Sjkim___ 1473289848Sjkim$code.=<<___ if ($avx>1); 1474289848Sjkim mov OPENSSL_ia32cap_P+8(%rip), %eax 1475289848Sjkim test \$`1<<5`, %eax 1476289848Sjkim jnz .Lavx2_select_w7 1477289848Sjkim___ 1478289848Sjkim$code.=<<___ if ($win64); 1479289848Sjkim lea -0x88(%rsp), %rax 1480289848Sjkim.LSEH_begin_ecp_nistz256_select_w7: 1481289848Sjkim .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp 1482289848Sjkim .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax) 1483289848Sjkim .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax) 1484289848Sjkim .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax) 1485289848Sjkim .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax) 1486289848Sjkim .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax) 1487289848Sjkim .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax) 1488289848Sjkim .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax) 1489289848Sjkim .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax) 1490289848Sjkim .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax) 1491289848Sjkim .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax) 1492289848Sjkim___ 1493289848Sjkim$code.=<<___; 1494289848Sjkim movdqa .LOne(%rip), $M0 1495289848Sjkim movd $index, $INDEX 1496289848Sjkim 1497289848Sjkim pxor $Ra, $Ra 1498289848Sjkim pxor $Rb, $Rb 1499289848Sjkim pxor $Rc, $Rc 1500289848Sjkim pxor $Rd, $Rd 1501289848Sjkim 1502289848Sjkim movdqa $M0, $ONE 1503289848Sjkim pshufd \$0, $INDEX, $INDEX 1504289848Sjkim mov \$64, %rax 1505289848Sjkim 1506289848Sjkim.Lselect_loop_sse_w7: 1507289848Sjkim movdqa $M0, $TMP0 1508289848Sjkim paddd $ONE, $M0 1509289848Sjkim movdqa 16*0($in_t), $T0a 1510289848Sjkim movdqa 16*1($in_t), $T0b 1511289848Sjkim pcmpeqd $INDEX, $TMP0 1512289848Sjkim movdqa 16*2($in_t), $T0c 1513289848Sjkim movdqa 16*3($in_t), $T0d 1514289848Sjkim lea 16*4($in_t), $in_t 1515289848Sjkim 1516289848Sjkim pand $TMP0, $T0a 1517289848Sjkim pand $TMP0, $T0b 1518289848Sjkim por $T0a, $Ra 1519289848Sjkim pand $TMP0, $T0c 1520289848Sjkim por $T0b, $Rb 1521289848Sjkim pand $TMP0, $T0d 1522289848Sjkim por $T0c, $Rc 1523289848Sjkim prefetcht0 255($in_t) 1524289848Sjkim por $T0d, $Rd 1525289848Sjkim 1526289848Sjkim dec %rax 1527289848Sjkim jnz .Lselect_loop_sse_w7 1528289848Sjkim 1529289848Sjkim movdqu $Ra, 16*0($val) 1530289848Sjkim movdqu $Rb, 16*1($val) 1531289848Sjkim movdqu $Rc, 16*2($val) 1532289848Sjkim movdqu $Rd, 16*3($val) 1533289848Sjkim___ 1534289848Sjkim$code.=<<___ if ($win64); 1535289848Sjkim movaps (%rsp), %xmm6 1536289848Sjkim movaps 0x10(%rsp), %xmm7 1537289848Sjkim movaps 0x20(%rsp), %xmm8 1538289848Sjkim movaps 0x30(%rsp), %xmm9 1539289848Sjkim movaps 0x40(%rsp), %xmm10 1540289848Sjkim movaps 0x50(%rsp), %xmm11 1541289848Sjkim movaps 0x60(%rsp), %xmm12 1542289848Sjkim movaps 0x70(%rsp), %xmm13 1543289848Sjkim movaps 0x80(%rsp), %xmm14 1544289848Sjkim movaps 0x90(%rsp), %xmm15 1545289848Sjkim lea 0xa8(%rsp), %rsp 1546289848Sjkim.LSEH_end_ecp_nistz256_select_w7: 1547289848Sjkim___ 1548289848Sjkim$code.=<<___; 1549289848Sjkim ret 1550289848Sjkim.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 1551289848Sjkim___ 1552289848Sjkim} 1553289848Sjkimif ($avx>1) { 1554289848Sjkimmy ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx"); 1555289848Sjkimmy ($TWO,$INDEX,$Ra,$Rb,$Rc)=map("%ymm$_",(0..4)); 1556289848Sjkimmy ($M0,$T0a,$T0b,$T0c,$TMP0)=map("%ymm$_",(5..9)); 1557289848Sjkimmy ($M1,$T1a,$T1b,$T1c,$TMP1)=map("%ymm$_",(10..14)); 1558289848Sjkim 1559289848Sjkim$code.=<<___; 1560289848Sjkim################################################################################ 1561289848Sjkim# void ecp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, int index); 1562289848Sjkim.type ecp_nistz256_avx2_select_w5,\@abi-omnipotent 1563289848Sjkim.align 32 1564289848Sjkimecp_nistz256_avx2_select_w5: 1565289848Sjkim.Lavx2_select_w5: 1566289848Sjkim vzeroupper 1567289848Sjkim___ 1568289848Sjkim$code.=<<___ if ($win64); 1569289848Sjkim lea -0x88(%rsp), %rax 1570289848Sjkim.LSEH_begin_ecp_nistz256_avx2_select_w5: 1571289848Sjkim .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp 1572289848Sjkim .byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax) 1573289848Sjkim .byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax) 1574289848Sjkim .byte 0xc5,0x78,0x29,0x40,0x00 #vmovaps %xmm8, 8(%rax) 1575289848Sjkim .byte 0xc5,0x78,0x29,0x48,0x10 #vmovaps %xmm9, 0x10(%rax) 1576289848Sjkim .byte 0xc5,0x78,0x29,0x50,0x20 #vmovaps %xmm10, 0x20(%rax) 1577289848Sjkim .byte 0xc5,0x78,0x29,0x58,0x30 #vmovaps %xmm11, 0x30(%rax) 1578289848Sjkim .byte 0xc5,0x78,0x29,0x60,0x40 #vmovaps %xmm12, 0x40(%rax) 1579289848Sjkim .byte 0xc5,0x78,0x29,0x68,0x50 #vmovaps %xmm13, 0x50(%rax) 1580289848Sjkim .byte 0xc5,0x78,0x29,0x70,0x60 #vmovaps %xmm14, 0x60(%rax) 1581289848Sjkim .byte 0xc5,0x78,0x29,0x78,0x70 #vmovaps %xmm15, 0x70(%rax) 1582289848Sjkim___ 1583289848Sjkim$code.=<<___; 1584289848Sjkim vmovdqa .LTwo(%rip), $TWO 1585289848Sjkim 1586289848Sjkim vpxor $Ra, $Ra, $Ra 1587289848Sjkim vpxor $Rb, $Rb, $Rb 1588289848Sjkim vpxor $Rc, $Rc, $Rc 1589289848Sjkim 1590289848Sjkim vmovdqa .LOne(%rip), $M0 1591289848Sjkim vmovdqa .LTwo(%rip), $M1 1592289848Sjkim 1593289848Sjkim vmovd $index, %xmm1 1594289848Sjkim vpermd $INDEX, $Ra, $INDEX 1595289848Sjkim 1596289848Sjkim mov \$8, %rax 1597289848Sjkim.Lselect_loop_avx2_w5: 1598289848Sjkim 1599289848Sjkim vmovdqa 32*0($in_t), $T0a 1600289848Sjkim vmovdqa 32*1($in_t), $T0b 1601289848Sjkim vmovdqa 32*2($in_t), $T0c 1602289848Sjkim 1603289848Sjkim vmovdqa 32*3($in_t), $T1a 1604289848Sjkim vmovdqa 32*4($in_t), $T1b 1605289848Sjkim vmovdqa 32*5($in_t), $T1c 1606289848Sjkim 1607289848Sjkim vpcmpeqd $INDEX, $M0, $TMP0 1608289848Sjkim vpcmpeqd $INDEX, $M1, $TMP1 1609289848Sjkim 1610289848Sjkim vpaddd $TWO, $M0, $M0 1611289848Sjkim vpaddd $TWO, $M1, $M1 1612289848Sjkim lea 32*6($in_t), $in_t 1613289848Sjkim 1614289848Sjkim vpand $TMP0, $T0a, $T0a 1615289848Sjkim vpand $TMP0, $T0b, $T0b 1616289848Sjkim vpand $TMP0, $T0c, $T0c 1617289848Sjkim vpand $TMP1, $T1a, $T1a 1618289848Sjkim vpand $TMP1, $T1b, $T1b 1619289848Sjkim vpand $TMP1, $T1c, $T1c 1620289848Sjkim 1621289848Sjkim vpxor $T0a, $Ra, $Ra 1622289848Sjkim vpxor $T0b, $Rb, $Rb 1623289848Sjkim vpxor $T0c, $Rc, $Rc 1624289848Sjkim vpxor $T1a, $Ra, $Ra 1625289848Sjkim vpxor $T1b, $Rb, $Rb 1626289848Sjkim vpxor $T1c, $Rc, $Rc 1627289848Sjkim 1628289848Sjkim dec %rax 1629289848Sjkim jnz .Lselect_loop_avx2_w5 1630289848Sjkim 1631289848Sjkim vmovdqu $Ra, 32*0($val) 1632289848Sjkim vmovdqu $Rb, 32*1($val) 1633289848Sjkim vmovdqu $Rc, 32*2($val) 1634289848Sjkim vzeroupper 1635289848Sjkim___ 1636289848Sjkim$code.=<<___ if ($win64); 1637289848Sjkim movaps (%rsp), %xmm6 1638289848Sjkim movaps 0x10(%rsp), %xmm7 1639289848Sjkim movaps 0x20(%rsp), %xmm8 1640289848Sjkim movaps 0x30(%rsp), %xmm9 1641289848Sjkim movaps 0x40(%rsp), %xmm10 1642289848Sjkim movaps 0x50(%rsp), %xmm11 1643289848Sjkim movaps 0x60(%rsp), %xmm12 1644289848Sjkim movaps 0x70(%rsp), %xmm13 1645289848Sjkim movaps 0x80(%rsp), %xmm14 1646289848Sjkim movaps 0x90(%rsp), %xmm15 1647289848Sjkim lea 0xa8(%rsp), %rsp 1648289848Sjkim.LSEH_end_ecp_nistz256_avx2_select_w5: 1649289848Sjkim___ 1650289848Sjkim$code.=<<___; 1651289848Sjkim ret 1652289848Sjkim.size ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5 1653289848Sjkim___ 1654289848Sjkim} 1655289848Sjkimif ($avx>1) { 1656289848Sjkimmy ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx"); 1657289848Sjkimmy ($THREE,$INDEX,$Ra,$Rb)=map("%ymm$_",(0..3)); 1658289848Sjkimmy ($M0,$T0a,$T0b,$TMP0)=map("%ymm$_",(4..7)); 1659289848Sjkimmy ($M1,$T1a,$T1b,$TMP1)=map("%ymm$_",(8..11)); 1660289848Sjkimmy ($M2,$T2a,$T2b,$TMP2)=map("%ymm$_",(12..15)); 1661289848Sjkim 1662289848Sjkim$code.=<<___; 1663289848Sjkim 1664289848Sjkim################################################################################ 1665289848Sjkim# void ecp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, int index); 1666289848Sjkim.globl ecp_nistz256_avx2_select_w7 1667289848Sjkim.type ecp_nistz256_avx2_select_w7,\@abi-omnipotent 1668289848Sjkim.align 32 1669289848Sjkimecp_nistz256_avx2_select_w7: 1670289848Sjkim.Lavx2_select_w7: 1671289848Sjkim vzeroupper 1672289848Sjkim___ 1673289848Sjkim$code.=<<___ if ($win64); 1674289848Sjkim lea -0x88(%rsp), %rax 1675289848Sjkim.LSEH_begin_ecp_nistz256_avx2_select_w7: 1676289848Sjkim .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp 1677289848Sjkim .byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax) 1678289848Sjkim .byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax) 1679289848Sjkim .byte 0xc5,0x78,0x29,0x40,0x00 #vmovaps %xmm8, 8(%rax) 1680289848Sjkim .byte 0xc5,0x78,0x29,0x48,0x10 #vmovaps %xmm9, 0x10(%rax) 1681289848Sjkim .byte 0xc5,0x78,0x29,0x50,0x20 #vmovaps %xmm10, 0x20(%rax) 1682289848Sjkim .byte 0xc5,0x78,0x29,0x58,0x30 #vmovaps %xmm11, 0x30(%rax) 1683289848Sjkim .byte 0xc5,0x78,0x29,0x60,0x40 #vmovaps %xmm12, 0x40(%rax) 1684289848Sjkim .byte 0xc5,0x78,0x29,0x68,0x50 #vmovaps %xmm13, 0x50(%rax) 1685289848Sjkim .byte 0xc5,0x78,0x29,0x70,0x60 #vmovaps %xmm14, 0x60(%rax) 1686289848Sjkim .byte 0xc5,0x78,0x29,0x78,0x70 #vmovaps %xmm15, 0x70(%rax) 1687289848Sjkim___ 1688289848Sjkim$code.=<<___; 1689289848Sjkim vmovdqa .LThree(%rip), $THREE 1690289848Sjkim 1691289848Sjkim vpxor $Ra, $Ra, $Ra 1692289848Sjkim vpxor $Rb, $Rb, $Rb 1693289848Sjkim 1694289848Sjkim vmovdqa .LOne(%rip), $M0 1695289848Sjkim vmovdqa .LTwo(%rip), $M1 1696289848Sjkim vmovdqa .LThree(%rip), $M2 1697289848Sjkim 1698289848Sjkim vmovd $index, %xmm1 1699289848Sjkim vpermd $INDEX, $Ra, $INDEX 1700289848Sjkim # Skip index = 0, because it is implicitly the point at infinity 1701289848Sjkim 1702289848Sjkim mov \$21, %rax 1703289848Sjkim.Lselect_loop_avx2_w7: 1704289848Sjkim 1705289848Sjkim vmovdqa 32*0($in_t), $T0a 1706289848Sjkim vmovdqa 32*1($in_t), $T0b 1707289848Sjkim 1708289848Sjkim vmovdqa 32*2($in_t), $T1a 1709289848Sjkim vmovdqa 32*3($in_t), $T1b 1710289848Sjkim 1711289848Sjkim vmovdqa 32*4($in_t), $T2a 1712289848Sjkim vmovdqa 32*5($in_t), $T2b 1713289848Sjkim 1714289848Sjkim vpcmpeqd $INDEX, $M0, $TMP0 1715289848Sjkim vpcmpeqd $INDEX, $M1, $TMP1 1716289848Sjkim vpcmpeqd $INDEX, $M2, $TMP2 1717289848Sjkim 1718289848Sjkim vpaddd $THREE, $M0, $M0 1719289848Sjkim vpaddd $THREE, $M1, $M1 1720289848Sjkim vpaddd $THREE, $M2, $M2 1721289848Sjkim lea 32*6($in_t), $in_t 1722289848Sjkim 1723289848Sjkim vpand $TMP0, $T0a, $T0a 1724289848Sjkim vpand $TMP0, $T0b, $T0b 1725289848Sjkim vpand $TMP1, $T1a, $T1a 1726289848Sjkim vpand $TMP1, $T1b, $T1b 1727289848Sjkim vpand $TMP2, $T2a, $T2a 1728289848Sjkim vpand $TMP2, $T2b, $T2b 1729289848Sjkim 1730289848Sjkim vpxor $T0a, $Ra, $Ra 1731289848Sjkim vpxor $T0b, $Rb, $Rb 1732289848Sjkim vpxor $T1a, $Ra, $Ra 1733289848Sjkim vpxor $T1b, $Rb, $Rb 1734289848Sjkim vpxor $T2a, $Ra, $Ra 1735289848Sjkim vpxor $T2b, $Rb, $Rb 1736289848Sjkim 1737289848Sjkim dec %rax 1738289848Sjkim jnz .Lselect_loop_avx2_w7 1739289848Sjkim 1740289848Sjkim 1741289848Sjkim vmovdqa 32*0($in_t), $T0a 1742289848Sjkim vmovdqa 32*1($in_t), $T0b 1743289848Sjkim 1744289848Sjkim vpcmpeqd $INDEX, $M0, $TMP0 1745289848Sjkim 1746289848Sjkim vpand $TMP0, $T0a, $T0a 1747289848Sjkim vpand $TMP0, $T0b, $T0b 1748289848Sjkim 1749289848Sjkim vpxor $T0a, $Ra, $Ra 1750289848Sjkim vpxor $T0b, $Rb, $Rb 1751289848Sjkim 1752289848Sjkim vmovdqu $Ra, 32*0($val) 1753289848Sjkim vmovdqu $Rb, 32*1($val) 1754289848Sjkim vzeroupper 1755289848Sjkim___ 1756289848Sjkim$code.=<<___ if ($win64); 1757289848Sjkim movaps (%rsp), %xmm6 1758289848Sjkim movaps 0x10(%rsp), %xmm7 1759289848Sjkim movaps 0x20(%rsp), %xmm8 1760289848Sjkim movaps 0x30(%rsp), %xmm9 1761289848Sjkim movaps 0x40(%rsp), %xmm10 1762289848Sjkim movaps 0x50(%rsp), %xmm11 1763289848Sjkim movaps 0x60(%rsp), %xmm12 1764289848Sjkim movaps 0x70(%rsp), %xmm13 1765289848Sjkim movaps 0x80(%rsp), %xmm14 1766289848Sjkim movaps 0x90(%rsp), %xmm15 1767289848Sjkim lea 0xa8(%rsp), %rsp 1768289848Sjkim.LSEH_end_ecp_nistz256_avx2_select_w7: 1769289848Sjkim___ 1770289848Sjkim$code.=<<___; 1771289848Sjkim ret 1772289848Sjkim.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7 1773289848Sjkim___ 1774289848Sjkim} else { 1775289848Sjkim$code.=<<___; 1776289848Sjkim.globl ecp_nistz256_avx2_select_w7 1777289848Sjkim.type ecp_nistz256_avx2_select_w7,\@function,3 1778289848Sjkim.align 32 1779289848Sjkimecp_nistz256_avx2_select_w7: 1780289848Sjkim .byte 0x0f,0x0b # ud2 1781289848Sjkim ret 1782289848Sjkim.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7 1783289848Sjkim___ 1784289848Sjkim} 1785289848Sjkim{{{ 1786289848Sjkim######################################################################## 1787289848Sjkim# This block implements higher level point_double, point_add and 1788289848Sjkim# point_add_affine. The key to performance in this case is to allow 1789289848Sjkim# out-of-order execution logic to overlap computations from next step 1790289848Sjkim# with tail processing from current step. By using tailored calling 1791289848Sjkim# sequence we minimize inter-step overhead to give processor better 1792289848Sjkim# shot at overlapping operations... 1793289848Sjkim# 1794289848Sjkim# You will notice that input data is copied to stack. Trouble is that 1795289848Sjkim# there are no registers to spare for holding original pointers and 1796289848Sjkim# reloading them, pointers, would create undesired dependencies on 1797289848Sjkim# effective addresses calculation paths. In other words it's too done 1798289848Sjkim# to favour out-of-order execution logic. 1799289848Sjkim# <appro@openssl.org> 1800289848Sjkim 1801289848Sjkimmy ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx"); 1802289848Sjkimmy ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15)); 1803289848Sjkimmy ($t0,$t1,$t2,$t3,$t4)=("%rax","%rbp","%rcx",$acc4,$acc4); 1804289848Sjkimmy ($poly1,$poly3)=($acc6,$acc7); 1805289848Sjkim 1806289848Sjkimsub load_for_mul () { 1807289848Sjkimmy ($a,$b,$src0) = @_; 1808289848Sjkimmy $bias = $src0 eq "%rax" ? 0 : -128; 1809289848Sjkim 1810289848Sjkim" mov $b, $src0 1811289848Sjkim lea $b, $b_ptr 1812289848Sjkim mov 8*0+$a, $acc1 1813289848Sjkim mov 8*1+$a, $acc2 1814289848Sjkim lea $bias+$a, $a_ptr 1815289848Sjkim mov 8*2+$a, $acc3 1816289848Sjkim mov 8*3+$a, $acc4" 1817289848Sjkim} 1818289848Sjkim 1819289848Sjkimsub load_for_sqr () { 1820289848Sjkimmy ($a,$src0) = @_; 1821289848Sjkimmy $bias = $src0 eq "%rax" ? 0 : -128; 1822289848Sjkim 1823289848Sjkim" mov 8*0+$a, $src0 1824289848Sjkim mov 8*1+$a, $acc6 1825289848Sjkim lea $bias+$a, $a_ptr 1826289848Sjkim mov 8*2+$a, $acc7 1827289848Sjkim mov 8*3+$a, $acc0" 1828289848Sjkim} 1829289848Sjkim 1830289848Sjkim { 1831289848Sjkim######################################################################## 1832289848Sjkim# operate in 4-5-0-1 "name space" that matches multiplication output 1833289848Sjkim# 1834289848Sjkimmy ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3); 1835289848Sjkim 1836289848Sjkim$code.=<<___; 1837289848Sjkim.type __ecp_nistz256_add_toq,\@abi-omnipotent 1838289848Sjkim.align 32 1839289848Sjkim__ecp_nistz256_add_toq: 1840306195Sjkim xor $t4,$t4 1841289848Sjkim add 8*0($b_ptr), $a0 1842289848Sjkim adc 8*1($b_ptr), $a1 1843289848Sjkim mov $a0, $t0 1844289848Sjkim adc 8*2($b_ptr), $a2 1845289848Sjkim adc 8*3($b_ptr), $a3 1846289848Sjkim mov $a1, $t1 1847306195Sjkim adc \$0, $t4 1848289848Sjkim 1849289848Sjkim sub \$-1, $a0 1850289848Sjkim mov $a2, $t2 1851289848Sjkim sbb $poly1, $a1 1852289848Sjkim sbb \$0, $a2 1853289848Sjkim mov $a3, $t3 1854289848Sjkim sbb $poly3, $a3 1855306195Sjkim sbb \$0, $t4 1856289848Sjkim 1857306195Sjkim cmovc $t0, $a0 1858306195Sjkim cmovc $t1, $a1 1859289848Sjkim mov $a0, 8*0($r_ptr) 1860306195Sjkim cmovc $t2, $a2 1861289848Sjkim mov $a1, 8*1($r_ptr) 1862306195Sjkim cmovc $t3, $a3 1863289848Sjkim mov $a2, 8*2($r_ptr) 1864289848Sjkim mov $a3, 8*3($r_ptr) 1865289848Sjkim 1866289848Sjkim ret 1867289848Sjkim.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq 1868289848Sjkim 1869289848Sjkim.type __ecp_nistz256_sub_fromq,\@abi-omnipotent 1870289848Sjkim.align 32 1871289848Sjkim__ecp_nistz256_sub_fromq: 1872289848Sjkim sub 8*0($b_ptr), $a0 1873289848Sjkim sbb 8*1($b_ptr), $a1 1874289848Sjkim mov $a0, $t0 1875289848Sjkim sbb 8*2($b_ptr), $a2 1876289848Sjkim sbb 8*3($b_ptr), $a3 1877289848Sjkim mov $a1, $t1 1878289848Sjkim sbb $t4, $t4 1879289848Sjkim 1880289848Sjkim add \$-1, $a0 1881289848Sjkim mov $a2, $t2 1882289848Sjkim adc $poly1, $a1 1883289848Sjkim adc \$0, $a2 1884289848Sjkim mov $a3, $t3 1885289848Sjkim adc $poly3, $a3 1886289848Sjkim test $t4, $t4 1887289848Sjkim 1888289848Sjkim cmovz $t0, $a0 1889289848Sjkim cmovz $t1, $a1 1890289848Sjkim mov $a0, 8*0($r_ptr) 1891289848Sjkim cmovz $t2, $a2 1892289848Sjkim mov $a1, 8*1($r_ptr) 1893289848Sjkim cmovz $t3, $a3 1894289848Sjkim mov $a2, 8*2($r_ptr) 1895289848Sjkim mov $a3, 8*3($r_ptr) 1896289848Sjkim 1897289848Sjkim ret 1898289848Sjkim.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq 1899289848Sjkim 1900289848Sjkim.type __ecp_nistz256_subq,\@abi-omnipotent 1901289848Sjkim.align 32 1902289848Sjkim__ecp_nistz256_subq: 1903289848Sjkim sub $a0, $t0 1904289848Sjkim sbb $a1, $t1 1905289848Sjkim mov $t0, $a0 1906289848Sjkim sbb $a2, $t2 1907289848Sjkim sbb $a3, $t3 1908289848Sjkim mov $t1, $a1 1909289848Sjkim sbb $t4, $t4 1910289848Sjkim 1911289848Sjkim add \$-1, $t0 1912289848Sjkim mov $t2, $a2 1913289848Sjkim adc $poly1, $t1 1914289848Sjkim adc \$0, $t2 1915289848Sjkim mov $t3, $a3 1916289848Sjkim adc $poly3, $t3 1917289848Sjkim test $t4, $t4 1918289848Sjkim 1919289848Sjkim cmovnz $t0, $a0 1920289848Sjkim cmovnz $t1, $a1 1921289848Sjkim cmovnz $t2, $a2 1922289848Sjkim cmovnz $t3, $a3 1923289848Sjkim 1924289848Sjkim ret 1925289848Sjkim.size __ecp_nistz256_subq,.-__ecp_nistz256_subq 1926289848Sjkim 1927289848Sjkim.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent 1928289848Sjkim.align 32 1929289848Sjkim__ecp_nistz256_mul_by_2q: 1930306195Sjkim xor $t4, $t4 1931289848Sjkim add $a0, $a0 # a0:a3+a0:a3 1932289848Sjkim adc $a1, $a1 1933289848Sjkim mov $a0, $t0 1934289848Sjkim adc $a2, $a2 1935289848Sjkim adc $a3, $a3 1936289848Sjkim mov $a1, $t1 1937306195Sjkim adc \$0, $t4 1938289848Sjkim 1939289848Sjkim sub \$-1, $a0 1940289848Sjkim mov $a2, $t2 1941289848Sjkim sbb $poly1, $a1 1942289848Sjkim sbb \$0, $a2 1943289848Sjkim mov $a3, $t3 1944289848Sjkim sbb $poly3, $a3 1945306195Sjkim sbb \$0, $t4 1946289848Sjkim 1947306195Sjkim cmovc $t0, $a0 1948306195Sjkim cmovc $t1, $a1 1949289848Sjkim mov $a0, 8*0($r_ptr) 1950306195Sjkim cmovc $t2, $a2 1951289848Sjkim mov $a1, 8*1($r_ptr) 1952306195Sjkim cmovc $t3, $a3 1953289848Sjkim mov $a2, 8*2($r_ptr) 1954289848Sjkim mov $a3, 8*3($r_ptr) 1955289848Sjkim 1956289848Sjkim ret 1957289848Sjkim.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q 1958289848Sjkim___ 1959289848Sjkim } 1960289848Sjkimsub gen_double () { 1961289848Sjkim my $x = shift; 1962289848Sjkim my ($src0,$sfx,$bias); 1963289848Sjkim my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4)); 1964289848Sjkim 1965289848Sjkim if ($x ne "x") { 1966289848Sjkim $src0 = "%rax"; 1967289848Sjkim $sfx = ""; 1968289848Sjkim $bias = 0; 1969289848Sjkim 1970289848Sjkim$code.=<<___; 1971289848Sjkim.globl ecp_nistz256_point_double 1972289848Sjkim.type ecp_nistz256_point_double,\@function,2 1973289848Sjkim.align 32 1974289848Sjkimecp_nistz256_point_double: 1975289848Sjkim___ 1976289848Sjkim$code.=<<___ if ($addx); 1977289848Sjkim mov \$0x80100, %ecx 1978289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 1979289848Sjkim cmp \$0x80100, %ecx 1980289848Sjkim je .Lpoint_doublex 1981289848Sjkim___ 1982289848Sjkim } else { 1983289848Sjkim $src0 = "%rdx"; 1984289848Sjkim $sfx = "x"; 1985289848Sjkim $bias = 128; 1986289848Sjkim 1987289848Sjkim$code.=<<___; 1988289848Sjkim.type ecp_nistz256_point_doublex,\@function,2 1989289848Sjkim.align 32 1990289848Sjkimecp_nistz256_point_doublex: 1991289848Sjkim.Lpoint_doublex: 1992289848Sjkim___ 1993289848Sjkim } 1994289848Sjkim$code.=<<___; 1995289848Sjkim push %rbp 1996289848Sjkim push %rbx 1997289848Sjkim push %r12 1998289848Sjkim push %r13 1999289848Sjkim push %r14 2000289848Sjkim push %r15 2001289848Sjkim sub \$32*5+8, %rsp 2002289848Sjkim 2003296279Sjkim.Lpoint_double_shortcut$x: 2004289848Sjkim movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr.x 2005289848Sjkim mov $a_ptr, $b_ptr # backup copy 2006289848Sjkim movdqu 0x10($a_ptr), %xmm1 2007289848Sjkim mov 0x20+8*0($a_ptr), $acc4 # load in_y in "5-4-0-1" order 2008289848Sjkim mov 0x20+8*1($a_ptr), $acc5 2009289848Sjkim mov 0x20+8*2($a_ptr), $acc0 2010289848Sjkim mov 0x20+8*3($a_ptr), $acc1 2011289848Sjkim mov .Lpoly+8*1(%rip), $poly1 2012289848Sjkim mov .Lpoly+8*3(%rip), $poly3 2013289848Sjkim movdqa %xmm0, $in_x(%rsp) 2014289848Sjkim movdqa %xmm1, $in_x+0x10(%rsp) 2015289848Sjkim lea 0x20($r_ptr), $acc2 2016289848Sjkim lea 0x40($r_ptr), $acc3 2017289848Sjkim movq $r_ptr, %xmm0 2018289848Sjkim movq $acc2, %xmm1 2019289848Sjkim movq $acc3, %xmm2 2020289848Sjkim 2021289848Sjkim lea $S(%rsp), $r_ptr 2022289848Sjkim call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(S, in_y); 2023289848Sjkim 2024289848Sjkim mov 0x40+8*0($a_ptr), $src0 2025289848Sjkim mov 0x40+8*1($a_ptr), $acc6 2026289848Sjkim mov 0x40+8*2($a_ptr), $acc7 2027289848Sjkim mov 0x40+8*3($a_ptr), $acc0 2028289848Sjkim lea 0x40-$bias($a_ptr), $a_ptr 2029289848Sjkim lea $Zsqr(%rsp), $r_ptr 2030289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Zsqr, in_z); 2031289848Sjkim 2032289848Sjkim `&load_for_sqr("$S(%rsp)", "$src0")` 2033289848Sjkim lea $S(%rsp), $r_ptr 2034289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(S, S); 2035289848Sjkim 2036289848Sjkim mov 0x20($b_ptr), $src0 # $b_ptr is still valid 2037289848Sjkim mov 0x40+8*0($b_ptr), $acc1 2038289848Sjkim mov 0x40+8*1($b_ptr), $acc2 2039289848Sjkim mov 0x40+8*2($b_ptr), $acc3 2040289848Sjkim mov 0x40+8*3($b_ptr), $acc4 2041289848Sjkim lea 0x40-$bias($b_ptr), $a_ptr 2042289848Sjkim lea 0x20($b_ptr), $b_ptr 2043289848Sjkim movq %xmm2, $r_ptr 2044289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, in_z, in_y); 2045289848Sjkim call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(res_z, res_z); 2046289848Sjkim 2047289848Sjkim mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order 2048289848Sjkim mov $in_x+8*1(%rsp), $acc5 2049289848Sjkim lea $Zsqr(%rsp), $b_ptr 2050289848Sjkim mov $in_x+8*2(%rsp), $acc0 2051289848Sjkim mov $in_x+8*3(%rsp), $acc1 2052289848Sjkim lea $M(%rsp), $r_ptr 2053289848Sjkim call __ecp_nistz256_add_to$x # p256_add(M, in_x, Zsqr); 2054289848Sjkim 2055289848Sjkim mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order 2056289848Sjkim mov $in_x+8*1(%rsp), $acc5 2057289848Sjkim lea $Zsqr(%rsp), $b_ptr 2058289848Sjkim mov $in_x+8*2(%rsp), $acc0 2059289848Sjkim mov $in_x+8*3(%rsp), $acc1 2060289848Sjkim lea $Zsqr(%rsp), $r_ptr 2061289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(Zsqr, in_x, Zsqr); 2062289848Sjkim 2063289848Sjkim `&load_for_sqr("$S(%rsp)", "$src0")` 2064289848Sjkim movq %xmm1, $r_ptr 2065289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_y, S); 2066289848Sjkim___ 2067289848Sjkim{ 2068289848Sjkim######## ecp_nistz256_div_by_2(res_y, res_y); ########################## 2069289848Sjkim# operate in 4-5-6-7 "name space" that matches squaring output 2070289848Sjkim# 2071289848Sjkimmy ($poly1,$poly3)=($a_ptr,$t1); 2072289848Sjkimmy ($a0,$a1,$a2,$a3,$t3,$t4,$t1)=($acc4,$acc5,$acc6,$acc7,$acc0,$acc1,$acc2); 2073289848Sjkim 2074289848Sjkim$code.=<<___; 2075289848Sjkim xor $t4, $t4 2076289848Sjkim mov $a0, $t0 2077289848Sjkim add \$-1, $a0 2078289848Sjkim mov $a1, $t1 2079289848Sjkim adc $poly1, $a1 2080289848Sjkim mov $a2, $t2 2081289848Sjkim adc \$0, $a2 2082289848Sjkim mov $a3, $t3 2083289848Sjkim adc $poly3, $a3 2084289848Sjkim adc \$0, $t4 2085289848Sjkim xor $a_ptr, $a_ptr # borrow $a_ptr 2086289848Sjkim test \$1, $t0 2087289848Sjkim 2088289848Sjkim cmovz $t0, $a0 2089289848Sjkim cmovz $t1, $a1 2090289848Sjkim cmovz $t2, $a2 2091289848Sjkim cmovz $t3, $a3 2092289848Sjkim cmovz $a_ptr, $t4 2093289848Sjkim 2094289848Sjkim mov $a1, $t0 # a0:a3>>1 2095289848Sjkim shr \$1, $a0 2096289848Sjkim shl \$63, $t0 2097289848Sjkim mov $a2, $t1 2098289848Sjkim shr \$1, $a1 2099289848Sjkim or $t0, $a0 2100289848Sjkim shl \$63, $t1 2101289848Sjkim mov $a3, $t2 2102289848Sjkim shr \$1, $a2 2103289848Sjkim or $t1, $a1 2104289848Sjkim shl \$63, $t2 2105289848Sjkim mov $a0, 8*0($r_ptr) 2106289848Sjkim shr \$1, $a3 2107289848Sjkim mov $a1, 8*1($r_ptr) 2108289848Sjkim shl \$63, $t4 2109289848Sjkim or $t2, $a2 2110289848Sjkim or $t4, $a3 2111289848Sjkim mov $a2, 8*2($r_ptr) 2112289848Sjkim mov $a3, 8*3($r_ptr) 2113289848Sjkim___ 2114289848Sjkim} 2115289848Sjkim$code.=<<___; 2116289848Sjkim `&load_for_mul("$M(%rsp)", "$Zsqr(%rsp)", "$src0")` 2117289848Sjkim lea $M(%rsp), $r_ptr 2118289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(M, M, Zsqr); 2119289848Sjkim 2120289848Sjkim lea $tmp0(%rsp), $r_ptr 2121289848Sjkim call __ecp_nistz256_mul_by_2$x 2122289848Sjkim 2123289848Sjkim lea $M(%rsp), $b_ptr 2124289848Sjkim lea $M(%rsp), $r_ptr 2125289848Sjkim call __ecp_nistz256_add_to$x # p256_mul_by_3(M, M); 2126289848Sjkim 2127289848Sjkim `&load_for_mul("$S(%rsp)", "$in_x(%rsp)", "$src0")` 2128289848Sjkim lea $S(%rsp), $r_ptr 2129289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, in_x); 2130289848Sjkim 2131289848Sjkim lea $tmp0(%rsp), $r_ptr 2132289848Sjkim call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(tmp0, S); 2133289848Sjkim 2134289848Sjkim `&load_for_sqr("$M(%rsp)", "$src0")` 2135289848Sjkim movq %xmm0, $r_ptr 2136289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_x, M); 2137289848Sjkim 2138289848Sjkim lea $tmp0(%rsp), $b_ptr 2139289848Sjkim mov $acc6, $acc0 # harmonize sqr output and sub input 2140289848Sjkim mov $acc7, $acc1 2141289848Sjkim mov $a_ptr, $poly1 2142289848Sjkim mov $t1, $poly3 2143289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, tmp0); 2144289848Sjkim 2145289848Sjkim mov $S+8*0(%rsp), $t0 2146289848Sjkim mov $S+8*1(%rsp), $t1 2147289848Sjkim mov $S+8*2(%rsp), $t2 2148289848Sjkim mov $S+8*3(%rsp), $acc2 # "4-5-0-1" order 2149289848Sjkim lea $S(%rsp), $r_ptr 2150289848Sjkim call __ecp_nistz256_sub$x # p256_sub(S, S, res_x); 2151289848Sjkim 2152289848Sjkim mov $M(%rsp), $src0 2153289848Sjkim lea $M(%rsp), $b_ptr 2154289848Sjkim mov $acc4, $acc6 # harmonize sub output and mul input 2155289848Sjkim xor %ecx, %ecx 2156289848Sjkim mov $acc4, $S+8*0(%rsp) # have to save:-( 2157289848Sjkim mov $acc5, $acc2 2158289848Sjkim mov $acc5, $S+8*1(%rsp) 2159289848Sjkim cmovz $acc0, $acc3 2160289848Sjkim mov $acc0, $S+8*2(%rsp) 2161289848Sjkim lea $S-$bias(%rsp), $a_ptr 2162289848Sjkim cmovz $acc1, $acc4 2163289848Sjkim mov $acc1, $S+8*3(%rsp) 2164289848Sjkim mov $acc6, $acc1 2165289848Sjkim lea $S(%rsp), $r_ptr 2166289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, M); 2167289848Sjkim 2168289848Sjkim movq %xmm1, $b_ptr 2169289848Sjkim movq %xmm1, $r_ptr 2170289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_y, S, res_y); 2171289848Sjkim 2172289848Sjkim add \$32*5+8, %rsp 2173289848Sjkim pop %r15 2174289848Sjkim pop %r14 2175289848Sjkim pop %r13 2176289848Sjkim pop %r12 2177289848Sjkim pop %rbx 2178289848Sjkim pop %rbp 2179289848Sjkim ret 2180289848Sjkim.size ecp_nistz256_point_double$sfx,.-ecp_nistz256_point_double$sfx 2181289848Sjkim___ 2182289848Sjkim} 2183289848Sjkim&gen_double("q"); 2184289848Sjkim 2185289848Sjkimsub gen_add () { 2186289848Sjkim my $x = shift; 2187289848Sjkim my ($src0,$sfx,$bias); 2188289848Sjkim my ($H,$Hsqr,$R,$Rsqr,$Hcub, 2189289848Sjkim $U1,$U2,$S1,$S2, 2190289848Sjkim $res_x,$res_y,$res_z, 2191289848Sjkim $in1_x,$in1_y,$in1_z, 2192289848Sjkim $in2_x,$in2_y,$in2_z)=map(32*$_,(0..17)); 2193289848Sjkim my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); 2194289848Sjkim 2195289848Sjkim if ($x ne "x") { 2196289848Sjkim $src0 = "%rax"; 2197289848Sjkim $sfx = ""; 2198289848Sjkim $bias = 0; 2199289848Sjkim 2200289848Sjkim$code.=<<___; 2201289848Sjkim.globl ecp_nistz256_point_add 2202289848Sjkim.type ecp_nistz256_point_add,\@function,3 2203289848Sjkim.align 32 2204289848Sjkimecp_nistz256_point_add: 2205289848Sjkim___ 2206289848Sjkim$code.=<<___ if ($addx); 2207289848Sjkim mov \$0x80100, %ecx 2208289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 2209289848Sjkim cmp \$0x80100, %ecx 2210289848Sjkim je .Lpoint_addx 2211289848Sjkim___ 2212289848Sjkim } else { 2213289848Sjkim $src0 = "%rdx"; 2214289848Sjkim $sfx = "x"; 2215289848Sjkim $bias = 128; 2216289848Sjkim 2217289848Sjkim$code.=<<___; 2218289848Sjkim.type ecp_nistz256_point_addx,\@function,3 2219289848Sjkim.align 32 2220289848Sjkimecp_nistz256_point_addx: 2221289848Sjkim.Lpoint_addx: 2222289848Sjkim___ 2223289848Sjkim } 2224289848Sjkim$code.=<<___; 2225289848Sjkim push %rbp 2226289848Sjkim push %rbx 2227289848Sjkim push %r12 2228289848Sjkim push %r13 2229289848Sjkim push %r14 2230289848Sjkim push %r15 2231289848Sjkim sub \$32*18+8, %rsp 2232289848Sjkim 2233289848Sjkim movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr 2234289848Sjkim movdqu 0x10($a_ptr), %xmm1 2235289848Sjkim movdqu 0x20($a_ptr), %xmm2 2236289848Sjkim movdqu 0x30($a_ptr), %xmm3 2237289848Sjkim movdqu 0x40($a_ptr), %xmm4 2238289848Sjkim movdqu 0x50($a_ptr), %xmm5 2239289848Sjkim mov $a_ptr, $b_ptr # reassign 2240289848Sjkim mov $b_org, $a_ptr # reassign 2241289848Sjkim movdqa %xmm0, $in1_x(%rsp) 2242289848Sjkim movdqa %xmm1, $in1_x+0x10(%rsp) 2243289848Sjkim movdqa %xmm2, $in1_y(%rsp) 2244289848Sjkim movdqa %xmm3, $in1_y+0x10(%rsp) 2245289848Sjkim movdqa %xmm4, $in1_z(%rsp) 2246289848Sjkim movdqa %xmm5, $in1_z+0x10(%rsp) 2247306195Sjkim por %xmm4, %xmm5 2248289848Sjkim 2249289848Sjkim movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$b_ptr 2250306195Sjkim pshufd \$0xb1, %xmm5, %xmm3 2251289848Sjkim movdqu 0x10($a_ptr), %xmm1 2252289848Sjkim movdqu 0x20($a_ptr), %xmm2 2253289848Sjkim por %xmm3, %xmm5 2254289848Sjkim movdqu 0x30($a_ptr), %xmm3 2255289848Sjkim mov 0x40+8*0($a_ptr), $src0 # load original in2_z 2256289848Sjkim mov 0x40+8*1($a_ptr), $acc6 2257289848Sjkim mov 0x40+8*2($a_ptr), $acc7 2258289848Sjkim mov 0x40+8*3($a_ptr), $acc0 2259289848Sjkim movdqa %xmm0, $in2_x(%rsp) 2260289848Sjkim pshufd \$0x1e, %xmm5, %xmm4 2261289848Sjkim movdqa %xmm1, $in2_x+0x10(%rsp) 2262306195Sjkim movdqu 0x40($a_ptr),%xmm0 # in2_z again 2263306195Sjkim movdqu 0x50($a_ptr),%xmm1 2264289848Sjkim movdqa %xmm2, $in2_y(%rsp) 2265289848Sjkim movdqa %xmm3, $in2_y+0x10(%rsp) 2266289848Sjkim por %xmm4, %xmm5 2267289848Sjkim pxor %xmm4, %xmm4 2268306195Sjkim por %xmm0, %xmm1 2269306195Sjkim movq $r_ptr, %xmm0 # save $r_ptr 2270289848Sjkim 2271289848Sjkim lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid 2272289848Sjkim mov $src0, $in2_z+8*0(%rsp) # make in2_z copy 2273289848Sjkim mov $acc6, $in2_z+8*1(%rsp) 2274289848Sjkim mov $acc7, $in2_z+8*2(%rsp) 2275289848Sjkim mov $acc0, $in2_z+8*3(%rsp) 2276289848Sjkim lea $Z2sqr(%rsp), $r_ptr # Z2^2 2277289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z2sqr, in2_z); 2278289848Sjkim 2279289848Sjkim pcmpeqd %xmm4, %xmm5 2280306195Sjkim pshufd \$0xb1, %xmm1, %xmm4 2281306195Sjkim por %xmm1, %xmm4 2282289848Sjkim pshufd \$0, %xmm5, %xmm5 # in1infty 2283289848Sjkim pshufd \$0x1e, %xmm4, %xmm3 2284289848Sjkim por %xmm3, %xmm4 2285289848Sjkim pxor %xmm3, %xmm3 2286289848Sjkim pcmpeqd %xmm3, %xmm4 2287289848Sjkim pshufd \$0, %xmm4, %xmm4 # in2infty 2288289848Sjkim mov 0x40+8*0($b_ptr), $src0 # load original in1_z 2289289848Sjkim mov 0x40+8*1($b_ptr), $acc6 2290289848Sjkim mov 0x40+8*2($b_ptr), $acc7 2291289848Sjkim mov 0x40+8*3($b_ptr), $acc0 2292296279Sjkim movq $b_ptr, %xmm1 2293289848Sjkim 2294289848Sjkim lea 0x40-$bias($b_ptr), $a_ptr 2295289848Sjkim lea $Z1sqr(%rsp), $r_ptr # Z1^2 2296289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z); 2297289848Sjkim 2298289848Sjkim `&load_for_mul("$Z2sqr(%rsp)", "$in2_z(%rsp)", "$src0")` 2299289848Sjkim lea $S1(%rsp), $r_ptr # S1 = Z2^3 2300289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, Z2sqr, in2_z); 2301289848Sjkim 2302289848Sjkim `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")` 2303289848Sjkim lea $S2(%rsp), $r_ptr # S2 = Z1^3 2304289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z); 2305289848Sjkim 2306289848Sjkim `&load_for_mul("$S1(%rsp)", "$in1_y(%rsp)", "$src0")` 2307289848Sjkim lea $S1(%rsp), $r_ptr # S1 = Y1*Z2^3 2308289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, S1, in1_y); 2309289848Sjkim 2310289848Sjkim `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")` 2311289848Sjkim lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3 2312289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y); 2313289848Sjkim 2314289848Sjkim lea $S1(%rsp), $b_ptr 2315289848Sjkim lea $R(%rsp), $r_ptr # R = S2 - S1 2316289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(R, S2, S1); 2317289848Sjkim 2318289848Sjkim or $acc5, $acc4 # see if result is zero 2319289848Sjkim movdqa %xmm4, %xmm2 2320289848Sjkim or $acc0, $acc4 2321289848Sjkim or $acc1, $acc4 2322289848Sjkim por %xmm5, %xmm2 # in1infty || in2infty 2323289848Sjkim movq $acc4, %xmm3 2324289848Sjkim 2325289848Sjkim `&load_for_mul("$Z2sqr(%rsp)", "$in1_x(%rsp)", "$src0")` 2326289848Sjkim lea $U1(%rsp), $r_ptr # U1 = X1*Z2^2 2327289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(U1, in1_x, Z2sqr); 2328289848Sjkim 2329289848Sjkim `&load_for_mul("$Z1sqr(%rsp)", "$in2_x(%rsp)", "$src0")` 2330289848Sjkim lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2 2331289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in2_x, Z1sqr); 2332289848Sjkim 2333289848Sjkim lea $U1(%rsp), $b_ptr 2334289848Sjkim lea $H(%rsp), $r_ptr # H = U2 - U1 2335289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(H, U2, U1); 2336289848Sjkim 2337289848Sjkim or $acc5, $acc4 # see if result is zero 2338289848Sjkim or $acc0, $acc4 2339289848Sjkim or $acc1, $acc4 2340289848Sjkim 2341289848Sjkim .byte 0x3e # predict taken 2342289848Sjkim jnz .Ladd_proceed$x # is_equal(U1,U2)? 2343289848Sjkim movq %xmm2, $acc0 2344289848Sjkim movq %xmm3, $acc1 2345289848Sjkim test $acc0, $acc0 2346289848Sjkim jnz .Ladd_proceed$x # (in1infty || in2infty)? 2347289848Sjkim test $acc1, $acc1 2348296279Sjkim jz .Ladd_double$x # is_equal(S1,S2)? 2349289848Sjkim 2350289848Sjkim movq %xmm0, $r_ptr # restore $r_ptr 2351289848Sjkim pxor %xmm0, %xmm0 2352289848Sjkim movdqu %xmm0, 0x00($r_ptr) 2353289848Sjkim movdqu %xmm0, 0x10($r_ptr) 2354289848Sjkim movdqu %xmm0, 0x20($r_ptr) 2355289848Sjkim movdqu %xmm0, 0x30($r_ptr) 2356289848Sjkim movdqu %xmm0, 0x40($r_ptr) 2357289848Sjkim movdqu %xmm0, 0x50($r_ptr) 2358289848Sjkim jmp .Ladd_done$x 2359289848Sjkim 2360289848Sjkim.align 32 2361296279Sjkim.Ladd_double$x: 2362296279Sjkim movq %xmm1, $a_ptr # restore $a_ptr 2363296279Sjkim movq %xmm0, $r_ptr # restore $r_ptr 2364296279Sjkim add \$`32*(18-5)`, %rsp # difference in frame sizes 2365296279Sjkim jmp .Lpoint_double_shortcut$x 2366296279Sjkim 2367296279Sjkim.align 32 2368289848Sjkim.Ladd_proceed$x: 2369289848Sjkim `&load_for_sqr("$R(%rsp)", "$src0")` 2370289848Sjkim lea $Rsqr(%rsp), $r_ptr # R^2 2371289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R); 2372289848Sjkim 2373289848Sjkim `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")` 2374289848Sjkim lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2 2375289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z); 2376289848Sjkim 2377289848Sjkim `&load_for_sqr("$H(%rsp)", "$src0")` 2378289848Sjkim lea $Hsqr(%rsp), $r_ptr # H^2 2379289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H); 2380289848Sjkim 2381289848Sjkim `&load_for_mul("$res_z(%rsp)", "$in2_z(%rsp)", "$src0")` 2382289848Sjkim lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2 2383289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, res_z, in2_z); 2384289848Sjkim 2385289848Sjkim `&load_for_mul("$Hsqr(%rsp)", "$H(%rsp)", "$src0")` 2386289848Sjkim lea $Hcub(%rsp), $r_ptr # H^3 2387289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H); 2388289848Sjkim 2389289848Sjkim `&load_for_mul("$Hsqr(%rsp)", "$U1(%rsp)", "$src0")` 2390289848Sjkim lea $U2(%rsp), $r_ptr # U1*H^2 2391289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, U1, Hsqr); 2392289848Sjkim___ 2393289848Sjkim{ 2394289848Sjkim####################################################################### 2395289848Sjkim# operate in 4-5-0-1 "name space" that matches multiplication output 2396289848Sjkim# 2397289848Sjkimmy ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3); 2398289848Sjkimmy ($poly1, $poly3)=($acc6,$acc7); 2399289848Sjkim 2400289848Sjkim$code.=<<___; 2401289848Sjkim #lea $U2(%rsp), $a_ptr 2402289848Sjkim #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2 2403289848Sjkim #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2); 2404289848Sjkim 2405306195Sjkim xor $t4, $t4 2406289848Sjkim add $acc0, $acc0 # a0:a3+a0:a3 2407289848Sjkim lea $Rsqr(%rsp), $a_ptr 2408289848Sjkim adc $acc1, $acc1 2409289848Sjkim mov $acc0, $t0 2410289848Sjkim adc $acc2, $acc2 2411289848Sjkim adc $acc3, $acc3 2412289848Sjkim mov $acc1, $t1 2413306195Sjkim adc \$0, $t4 2414289848Sjkim 2415289848Sjkim sub \$-1, $acc0 2416289848Sjkim mov $acc2, $t2 2417289848Sjkim sbb $poly1, $acc1 2418289848Sjkim sbb \$0, $acc2 2419289848Sjkim mov $acc3, $t3 2420289848Sjkim sbb $poly3, $acc3 2421306195Sjkim sbb \$0, $t4 2422289848Sjkim 2423306195Sjkim cmovc $t0, $acc0 2424289848Sjkim mov 8*0($a_ptr), $t0 2425306195Sjkim cmovc $t1, $acc1 2426289848Sjkim mov 8*1($a_ptr), $t1 2427306195Sjkim cmovc $t2, $acc2 2428289848Sjkim mov 8*2($a_ptr), $t2 2429306195Sjkim cmovc $t3, $acc3 2430289848Sjkim mov 8*3($a_ptr), $t3 2431289848Sjkim 2432289848Sjkim call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr); 2433289848Sjkim 2434289848Sjkim lea $Hcub(%rsp), $b_ptr 2435289848Sjkim lea $res_x(%rsp), $r_ptr 2436289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub); 2437289848Sjkim 2438289848Sjkim mov $U2+8*0(%rsp), $t0 2439289848Sjkim mov $U2+8*1(%rsp), $t1 2440289848Sjkim mov $U2+8*2(%rsp), $t2 2441289848Sjkim mov $U2+8*3(%rsp), $t3 2442289848Sjkim lea $res_y(%rsp), $r_ptr 2443289848Sjkim 2444289848Sjkim call __ecp_nistz256_sub$x # p256_sub(res_y, U2, res_x); 2445289848Sjkim 2446289848Sjkim mov $acc0, 8*0($r_ptr) # save the result, as 2447289848Sjkim mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't 2448289848Sjkim mov $acc2, 8*2($r_ptr) 2449289848Sjkim mov $acc3, 8*3($r_ptr) 2450289848Sjkim___ 2451289848Sjkim} 2452289848Sjkim$code.=<<___; 2453289848Sjkim `&load_for_mul("$S1(%rsp)", "$Hcub(%rsp)", "$src0")` 2454289848Sjkim lea $S2(%rsp), $r_ptr 2455289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S1, Hcub); 2456289848Sjkim 2457289848Sjkim `&load_for_mul("$R(%rsp)", "$res_y(%rsp)", "$src0")` 2458289848Sjkim lea $res_y(%rsp), $r_ptr 2459289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_y, R, res_y); 2460289848Sjkim 2461289848Sjkim lea $S2(%rsp), $b_ptr 2462289848Sjkim lea $res_y(%rsp), $r_ptr 2463289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_y, res_y, S2); 2464289848Sjkim 2465289848Sjkim movq %xmm0, $r_ptr # restore $r_ptr 2466289848Sjkim 2467289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_z, in2_z, in1infty); 2468289848Sjkim movdqa %xmm5, %xmm1 2469289848Sjkim pandn $res_z(%rsp), %xmm0 2470289848Sjkim movdqa %xmm5, %xmm2 2471289848Sjkim pandn $res_z+0x10(%rsp), %xmm1 2472289848Sjkim movdqa %xmm5, %xmm3 2473289848Sjkim pand $in2_z(%rsp), %xmm2 2474289848Sjkim pand $in2_z+0x10(%rsp), %xmm3 2475289848Sjkim por %xmm0, %xmm2 2476289848Sjkim por %xmm1, %xmm3 2477289848Sjkim 2478289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty); 2479289848Sjkim movdqa %xmm4, %xmm1 2480289848Sjkim pandn %xmm2, %xmm0 2481289848Sjkim movdqa %xmm4, %xmm2 2482289848Sjkim pandn %xmm3, %xmm1 2483289848Sjkim movdqa %xmm4, %xmm3 2484289848Sjkim pand $in1_z(%rsp), %xmm2 2485289848Sjkim pand $in1_z+0x10(%rsp), %xmm3 2486289848Sjkim por %xmm0, %xmm2 2487289848Sjkim por %xmm1, %xmm3 2488289848Sjkim movdqu %xmm2, 0x40($r_ptr) 2489289848Sjkim movdqu %xmm3, 0x50($r_ptr) 2490289848Sjkim 2491289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty); 2492289848Sjkim movdqa %xmm5, %xmm1 2493289848Sjkim pandn $res_x(%rsp), %xmm0 2494289848Sjkim movdqa %xmm5, %xmm2 2495289848Sjkim pandn $res_x+0x10(%rsp), %xmm1 2496289848Sjkim movdqa %xmm5, %xmm3 2497289848Sjkim pand $in2_x(%rsp), %xmm2 2498289848Sjkim pand $in2_x+0x10(%rsp), %xmm3 2499289848Sjkim por %xmm0, %xmm2 2500289848Sjkim por %xmm1, %xmm3 2501289848Sjkim 2502289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty); 2503289848Sjkim movdqa %xmm4, %xmm1 2504289848Sjkim pandn %xmm2, %xmm0 2505289848Sjkim movdqa %xmm4, %xmm2 2506289848Sjkim pandn %xmm3, %xmm1 2507289848Sjkim movdqa %xmm4, %xmm3 2508289848Sjkim pand $in1_x(%rsp), %xmm2 2509289848Sjkim pand $in1_x+0x10(%rsp), %xmm3 2510289848Sjkim por %xmm0, %xmm2 2511289848Sjkim por %xmm1, %xmm3 2512289848Sjkim movdqu %xmm2, 0x00($r_ptr) 2513289848Sjkim movdqu %xmm3, 0x10($r_ptr) 2514289848Sjkim 2515289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty); 2516289848Sjkim movdqa %xmm5, %xmm1 2517289848Sjkim pandn $res_y(%rsp), %xmm0 2518289848Sjkim movdqa %xmm5, %xmm2 2519289848Sjkim pandn $res_y+0x10(%rsp), %xmm1 2520289848Sjkim movdqa %xmm5, %xmm3 2521289848Sjkim pand $in2_y(%rsp), %xmm2 2522289848Sjkim pand $in2_y+0x10(%rsp), %xmm3 2523289848Sjkim por %xmm0, %xmm2 2524289848Sjkim por %xmm1, %xmm3 2525289848Sjkim 2526289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty); 2527289848Sjkim movdqa %xmm4, %xmm1 2528289848Sjkim pandn %xmm2, %xmm0 2529289848Sjkim movdqa %xmm4, %xmm2 2530289848Sjkim pandn %xmm3, %xmm1 2531289848Sjkim movdqa %xmm4, %xmm3 2532289848Sjkim pand $in1_y(%rsp), %xmm2 2533289848Sjkim pand $in1_y+0x10(%rsp), %xmm3 2534289848Sjkim por %xmm0, %xmm2 2535289848Sjkim por %xmm1, %xmm3 2536289848Sjkim movdqu %xmm2, 0x20($r_ptr) 2537289848Sjkim movdqu %xmm3, 0x30($r_ptr) 2538289848Sjkim 2539289848Sjkim.Ladd_done$x: 2540289848Sjkim add \$32*18+8, %rsp 2541289848Sjkim pop %r15 2542289848Sjkim pop %r14 2543289848Sjkim pop %r13 2544289848Sjkim pop %r12 2545289848Sjkim pop %rbx 2546289848Sjkim pop %rbp 2547289848Sjkim ret 2548289848Sjkim.size ecp_nistz256_point_add$sfx,.-ecp_nistz256_point_add$sfx 2549289848Sjkim___ 2550289848Sjkim} 2551289848Sjkim&gen_add("q"); 2552289848Sjkim 2553289848Sjkimsub gen_add_affine () { 2554289848Sjkim my $x = shift; 2555289848Sjkim my ($src0,$sfx,$bias); 2556289848Sjkim my ($U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr, 2557289848Sjkim $res_x,$res_y,$res_z, 2558289848Sjkim $in1_x,$in1_y,$in1_z, 2559289848Sjkim $in2_x,$in2_y)=map(32*$_,(0..14)); 2560289848Sjkim my $Z1sqr = $S2; 2561289848Sjkim 2562289848Sjkim if ($x ne "x") { 2563289848Sjkim $src0 = "%rax"; 2564289848Sjkim $sfx = ""; 2565289848Sjkim $bias = 0; 2566289848Sjkim 2567289848Sjkim$code.=<<___; 2568289848Sjkim.globl ecp_nistz256_point_add_affine 2569289848Sjkim.type ecp_nistz256_point_add_affine,\@function,3 2570289848Sjkim.align 32 2571289848Sjkimecp_nistz256_point_add_affine: 2572289848Sjkim___ 2573289848Sjkim$code.=<<___ if ($addx); 2574289848Sjkim mov \$0x80100, %ecx 2575289848Sjkim and OPENSSL_ia32cap_P+8(%rip), %ecx 2576289848Sjkim cmp \$0x80100, %ecx 2577289848Sjkim je .Lpoint_add_affinex 2578289848Sjkim___ 2579289848Sjkim } else { 2580289848Sjkim $src0 = "%rdx"; 2581289848Sjkim $sfx = "x"; 2582289848Sjkim $bias = 128; 2583289848Sjkim 2584289848Sjkim$code.=<<___; 2585289848Sjkim.type ecp_nistz256_point_add_affinex,\@function,3 2586289848Sjkim.align 32 2587289848Sjkimecp_nistz256_point_add_affinex: 2588289848Sjkim.Lpoint_add_affinex: 2589289848Sjkim___ 2590289848Sjkim } 2591289848Sjkim$code.=<<___; 2592289848Sjkim push %rbp 2593289848Sjkim push %rbx 2594289848Sjkim push %r12 2595289848Sjkim push %r13 2596289848Sjkim push %r14 2597289848Sjkim push %r15 2598289848Sjkim sub \$32*15+8, %rsp 2599289848Sjkim 2600289848Sjkim movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr 2601289848Sjkim mov $b_org, $b_ptr # reassign 2602289848Sjkim movdqu 0x10($a_ptr), %xmm1 2603289848Sjkim movdqu 0x20($a_ptr), %xmm2 2604289848Sjkim movdqu 0x30($a_ptr), %xmm3 2605289848Sjkim movdqu 0x40($a_ptr), %xmm4 2606289848Sjkim movdqu 0x50($a_ptr), %xmm5 2607289848Sjkim mov 0x40+8*0($a_ptr), $src0 # load original in1_z 2608289848Sjkim mov 0x40+8*1($a_ptr), $acc6 2609289848Sjkim mov 0x40+8*2($a_ptr), $acc7 2610289848Sjkim mov 0x40+8*3($a_ptr), $acc0 2611289848Sjkim movdqa %xmm0, $in1_x(%rsp) 2612289848Sjkim movdqa %xmm1, $in1_x+0x10(%rsp) 2613289848Sjkim movdqa %xmm2, $in1_y(%rsp) 2614289848Sjkim movdqa %xmm3, $in1_y+0x10(%rsp) 2615289848Sjkim movdqa %xmm4, $in1_z(%rsp) 2616289848Sjkim movdqa %xmm5, $in1_z+0x10(%rsp) 2617306195Sjkim por %xmm4, %xmm5 2618289848Sjkim 2619289848Sjkim movdqu 0x00($b_ptr), %xmm0 # copy *(P256_POINT_AFFINE *)$b_ptr 2620306195Sjkim pshufd \$0xb1, %xmm5, %xmm3 2621289848Sjkim movdqu 0x10($b_ptr), %xmm1 2622289848Sjkim movdqu 0x20($b_ptr), %xmm2 2623289848Sjkim por %xmm3, %xmm5 2624289848Sjkim movdqu 0x30($b_ptr), %xmm3 2625289848Sjkim movdqa %xmm0, $in2_x(%rsp) 2626289848Sjkim pshufd \$0x1e, %xmm5, %xmm4 2627289848Sjkim movdqa %xmm1, $in2_x+0x10(%rsp) 2628289848Sjkim por %xmm0, %xmm1 2629289848Sjkim movq $r_ptr, %xmm0 # save $r_ptr 2630289848Sjkim movdqa %xmm2, $in2_y(%rsp) 2631289848Sjkim movdqa %xmm3, $in2_y+0x10(%rsp) 2632289848Sjkim por %xmm2, %xmm3 2633289848Sjkim por %xmm4, %xmm5 2634289848Sjkim pxor %xmm4, %xmm4 2635289848Sjkim por %xmm1, %xmm3 2636289848Sjkim 2637289848Sjkim lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid 2638289848Sjkim lea $Z1sqr(%rsp), $r_ptr # Z1^2 2639289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z); 2640289848Sjkim 2641289848Sjkim pcmpeqd %xmm4, %xmm5 2642289848Sjkim pshufd \$0xb1, %xmm3, %xmm4 2643289848Sjkim mov 0x00($b_ptr), $src0 # $b_ptr is still valid 2644289848Sjkim #lea 0x00($b_ptr), $b_ptr 2645289848Sjkim mov $acc4, $acc1 # harmonize sqr output and mul input 2646289848Sjkim por %xmm3, %xmm4 2647289848Sjkim pshufd \$0, %xmm5, %xmm5 # in1infty 2648289848Sjkim pshufd \$0x1e, %xmm4, %xmm3 2649289848Sjkim mov $acc5, $acc2 2650289848Sjkim por %xmm3, %xmm4 2651289848Sjkim pxor %xmm3, %xmm3 2652289848Sjkim mov $acc6, $acc3 2653289848Sjkim pcmpeqd %xmm3, %xmm4 2654289848Sjkim pshufd \$0, %xmm4, %xmm4 # in2infty 2655289848Sjkim 2656289848Sjkim lea $Z1sqr-$bias(%rsp), $a_ptr 2657289848Sjkim mov $acc7, $acc4 2658289848Sjkim lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2 2659289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, Z1sqr, in2_x); 2660289848Sjkim 2661289848Sjkim lea $in1_x(%rsp), $b_ptr 2662289848Sjkim lea $H(%rsp), $r_ptr # H = U2 - U1 2663289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(H, U2, in1_x); 2664289848Sjkim 2665289848Sjkim `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")` 2666289848Sjkim lea $S2(%rsp), $r_ptr # S2 = Z1^3 2667289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z); 2668289848Sjkim 2669289848Sjkim `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")` 2670289848Sjkim lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2 2671289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z); 2672289848Sjkim 2673289848Sjkim `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")` 2674289848Sjkim lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3 2675289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y); 2676289848Sjkim 2677289848Sjkim lea $in1_y(%rsp), $b_ptr 2678289848Sjkim lea $R(%rsp), $r_ptr # R = S2 - S1 2679289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(R, S2, in1_y); 2680289848Sjkim 2681289848Sjkim `&load_for_sqr("$H(%rsp)", "$src0")` 2682289848Sjkim lea $Hsqr(%rsp), $r_ptr # H^2 2683289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H); 2684289848Sjkim 2685289848Sjkim `&load_for_sqr("$R(%rsp)", "$src0")` 2686289848Sjkim lea $Rsqr(%rsp), $r_ptr # R^2 2687289848Sjkim call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R); 2688289848Sjkim 2689289848Sjkim `&load_for_mul("$H(%rsp)", "$Hsqr(%rsp)", "$src0")` 2690289848Sjkim lea $Hcub(%rsp), $r_ptr # H^3 2691289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H); 2692289848Sjkim 2693289848Sjkim `&load_for_mul("$Hsqr(%rsp)", "$in1_x(%rsp)", "$src0")` 2694289848Sjkim lea $U2(%rsp), $r_ptr # U1*H^2 2695289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in1_x, Hsqr); 2696289848Sjkim___ 2697289848Sjkim{ 2698289848Sjkim####################################################################### 2699289848Sjkim# operate in 4-5-0-1 "name space" that matches multiplication output 2700289848Sjkim# 2701289848Sjkimmy ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3); 2702289848Sjkimmy ($poly1, $poly3)=($acc6,$acc7); 2703289848Sjkim 2704289848Sjkim$code.=<<___; 2705289848Sjkim #lea $U2(%rsp), $a_ptr 2706289848Sjkim #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2 2707289848Sjkim #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2); 2708289848Sjkim 2709306195Sjkim xor $t4, $t4 2710289848Sjkim add $acc0, $acc0 # a0:a3+a0:a3 2711289848Sjkim lea $Rsqr(%rsp), $a_ptr 2712289848Sjkim adc $acc1, $acc1 2713289848Sjkim mov $acc0, $t0 2714289848Sjkim adc $acc2, $acc2 2715289848Sjkim adc $acc3, $acc3 2716289848Sjkim mov $acc1, $t1 2717306195Sjkim adc \$0, $t4 2718289848Sjkim 2719289848Sjkim sub \$-1, $acc0 2720289848Sjkim mov $acc2, $t2 2721289848Sjkim sbb $poly1, $acc1 2722289848Sjkim sbb \$0, $acc2 2723289848Sjkim mov $acc3, $t3 2724289848Sjkim sbb $poly3, $acc3 2725306195Sjkim sbb \$0, $t4 2726289848Sjkim 2727306195Sjkim cmovc $t0, $acc0 2728289848Sjkim mov 8*0($a_ptr), $t0 2729306195Sjkim cmovc $t1, $acc1 2730289848Sjkim mov 8*1($a_ptr), $t1 2731306195Sjkim cmovc $t2, $acc2 2732289848Sjkim mov 8*2($a_ptr), $t2 2733306195Sjkim cmovc $t3, $acc3 2734289848Sjkim mov 8*3($a_ptr), $t3 2735289848Sjkim 2736289848Sjkim call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr); 2737289848Sjkim 2738289848Sjkim lea $Hcub(%rsp), $b_ptr 2739289848Sjkim lea $res_x(%rsp), $r_ptr 2740289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub); 2741289848Sjkim 2742289848Sjkim mov $U2+8*0(%rsp), $t0 2743289848Sjkim mov $U2+8*1(%rsp), $t1 2744289848Sjkim mov $U2+8*2(%rsp), $t2 2745289848Sjkim mov $U2+8*3(%rsp), $t3 2746289848Sjkim lea $H(%rsp), $r_ptr 2747289848Sjkim 2748289848Sjkim call __ecp_nistz256_sub$x # p256_sub(H, U2, res_x); 2749289848Sjkim 2750289848Sjkim mov $acc0, 8*0($r_ptr) # save the result, as 2751289848Sjkim mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't 2752289848Sjkim mov $acc2, 8*2($r_ptr) 2753289848Sjkim mov $acc3, 8*3($r_ptr) 2754289848Sjkim___ 2755289848Sjkim} 2756289848Sjkim$code.=<<___; 2757289848Sjkim `&load_for_mul("$Hcub(%rsp)", "$in1_y(%rsp)", "$src0")` 2758289848Sjkim lea $S2(%rsp), $r_ptr 2759289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Hcub, in1_y); 2760289848Sjkim 2761289848Sjkim `&load_for_mul("$H(%rsp)", "$R(%rsp)", "$src0")` 2762289848Sjkim lea $H(%rsp), $r_ptr 2763289848Sjkim call __ecp_nistz256_mul_mont$x # p256_mul_mont(H, H, R); 2764289848Sjkim 2765289848Sjkim lea $S2(%rsp), $b_ptr 2766289848Sjkim lea $res_y(%rsp), $r_ptr 2767289848Sjkim call __ecp_nistz256_sub_from$x # p256_sub(res_y, H, S2); 2768289848Sjkim 2769289848Sjkim movq %xmm0, $r_ptr # restore $r_ptr 2770289848Sjkim 2771289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_z, ONE, in1infty); 2772289848Sjkim movdqa %xmm5, %xmm1 2773289848Sjkim pandn $res_z(%rsp), %xmm0 2774289848Sjkim movdqa %xmm5, %xmm2 2775289848Sjkim pandn $res_z+0x10(%rsp), %xmm1 2776289848Sjkim movdqa %xmm5, %xmm3 2777289848Sjkim pand .LONE_mont(%rip), %xmm2 2778289848Sjkim pand .LONE_mont+0x10(%rip), %xmm3 2779289848Sjkim por %xmm0, %xmm2 2780289848Sjkim por %xmm1, %xmm3 2781289848Sjkim 2782289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty); 2783289848Sjkim movdqa %xmm4, %xmm1 2784289848Sjkim pandn %xmm2, %xmm0 2785289848Sjkim movdqa %xmm4, %xmm2 2786289848Sjkim pandn %xmm3, %xmm1 2787289848Sjkim movdqa %xmm4, %xmm3 2788289848Sjkim pand $in1_z(%rsp), %xmm2 2789289848Sjkim pand $in1_z+0x10(%rsp), %xmm3 2790289848Sjkim por %xmm0, %xmm2 2791289848Sjkim por %xmm1, %xmm3 2792289848Sjkim movdqu %xmm2, 0x40($r_ptr) 2793289848Sjkim movdqu %xmm3, 0x50($r_ptr) 2794289848Sjkim 2795289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty); 2796289848Sjkim movdqa %xmm5, %xmm1 2797289848Sjkim pandn $res_x(%rsp), %xmm0 2798289848Sjkim movdqa %xmm5, %xmm2 2799289848Sjkim pandn $res_x+0x10(%rsp), %xmm1 2800289848Sjkim movdqa %xmm5, %xmm3 2801289848Sjkim pand $in2_x(%rsp), %xmm2 2802289848Sjkim pand $in2_x+0x10(%rsp), %xmm3 2803289848Sjkim por %xmm0, %xmm2 2804289848Sjkim por %xmm1, %xmm3 2805289848Sjkim 2806289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty); 2807289848Sjkim movdqa %xmm4, %xmm1 2808289848Sjkim pandn %xmm2, %xmm0 2809289848Sjkim movdqa %xmm4, %xmm2 2810289848Sjkim pandn %xmm3, %xmm1 2811289848Sjkim movdqa %xmm4, %xmm3 2812289848Sjkim pand $in1_x(%rsp), %xmm2 2813289848Sjkim pand $in1_x+0x10(%rsp), %xmm3 2814289848Sjkim por %xmm0, %xmm2 2815289848Sjkim por %xmm1, %xmm3 2816289848Sjkim movdqu %xmm2, 0x00($r_ptr) 2817289848Sjkim movdqu %xmm3, 0x10($r_ptr) 2818289848Sjkim 2819289848Sjkim movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty); 2820289848Sjkim movdqa %xmm5, %xmm1 2821289848Sjkim pandn $res_y(%rsp), %xmm0 2822289848Sjkim movdqa %xmm5, %xmm2 2823289848Sjkim pandn $res_y+0x10(%rsp), %xmm1 2824289848Sjkim movdqa %xmm5, %xmm3 2825289848Sjkim pand $in2_y(%rsp), %xmm2 2826289848Sjkim pand $in2_y+0x10(%rsp), %xmm3 2827289848Sjkim por %xmm0, %xmm2 2828289848Sjkim por %xmm1, %xmm3 2829289848Sjkim 2830289848Sjkim movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty); 2831289848Sjkim movdqa %xmm4, %xmm1 2832289848Sjkim pandn %xmm2, %xmm0 2833289848Sjkim movdqa %xmm4, %xmm2 2834289848Sjkim pandn %xmm3, %xmm1 2835289848Sjkim movdqa %xmm4, %xmm3 2836289848Sjkim pand $in1_y(%rsp), %xmm2 2837289848Sjkim pand $in1_y+0x10(%rsp), %xmm3 2838289848Sjkim por %xmm0, %xmm2 2839289848Sjkim por %xmm1, %xmm3 2840289848Sjkim movdqu %xmm2, 0x20($r_ptr) 2841289848Sjkim movdqu %xmm3, 0x30($r_ptr) 2842289848Sjkim 2843289848Sjkim add \$32*15+8, %rsp 2844289848Sjkim pop %r15 2845289848Sjkim pop %r14 2846289848Sjkim pop %r13 2847289848Sjkim pop %r12 2848289848Sjkim pop %rbx 2849289848Sjkim pop %rbp 2850289848Sjkim ret 2851289848Sjkim.size ecp_nistz256_point_add_affine$sfx,.-ecp_nistz256_point_add_affine$sfx 2852289848Sjkim___ 2853289848Sjkim} 2854289848Sjkim&gen_add_affine("q"); 2855289848Sjkim 2856289848Sjkim######################################################################## 2857289848Sjkim# AD*X magic 2858289848Sjkim# 2859289848Sjkimif ($addx) { { 2860289848Sjkim######################################################################## 2861289848Sjkim# operate in 4-5-0-1 "name space" that matches multiplication output 2862289848Sjkim# 2863289848Sjkimmy ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3); 2864289848Sjkim 2865289848Sjkim$code.=<<___; 2866289848Sjkim.type __ecp_nistz256_add_tox,\@abi-omnipotent 2867289848Sjkim.align 32 2868289848Sjkim__ecp_nistz256_add_tox: 2869289848Sjkim xor $t4, $t4 2870289848Sjkim adc 8*0($b_ptr), $a0 2871289848Sjkim adc 8*1($b_ptr), $a1 2872289848Sjkim mov $a0, $t0 2873289848Sjkim adc 8*2($b_ptr), $a2 2874289848Sjkim adc 8*3($b_ptr), $a3 2875289848Sjkim mov $a1, $t1 2876289848Sjkim adc \$0, $t4 2877289848Sjkim 2878289848Sjkim xor $t3, $t3 2879289848Sjkim sbb \$-1, $a0 2880289848Sjkim mov $a2, $t2 2881289848Sjkim sbb $poly1, $a1 2882289848Sjkim sbb \$0, $a2 2883289848Sjkim mov $a3, $t3 2884289848Sjkim sbb $poly3, $a3 2885306195Sjkim sbb \$0, $t4 2886289848Sjkim 2887306195Sjkim cmovc $t0, $a0 2888306195Sjkim cmovc $t1, $a1 2889289848Sjkim mov $a0, 8*0($r_ptr) 2890306195Sjkim cmovc $t2, $a2 2891289848Sjkim mov $a1, 8*1($r_ptr) 2892306195Sjkim cmovc $t3, $a3 2893289848Sjkim mov $a2, 8*2($r_ptr) 2894289848Sjkim mov $a3, 8*3($r_ptr) 2895289848Sjkim 2896289848Sjkim ret 2897289848Sjkim.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox 2898289848Sjkim 2899289848Sjkim.type __ecp_nistz256_sub_fromx,\@abi-omnipotent 2900289848Sjkim.align 32 2901289848Sjkim__ecp_nistz256_sub_fromx: 2902289848Sjkim xor $t4, $t4 2903289848Sjkim sbb 8*0($b_ptr), $a0 2904289848Sjkim sbb 8*1($b_ptr), $a1 2905289848Sjkim mov $a0, $t0 2906289848Sjkim sbb 8*2($b_ptr), $a2 2907289848Sjkim sbb 8*3($b_ptr), $a3 2908289848Sjkim mov $a1, $t1 2909289848Sjkim sbb \$0, $t4 2910289848Sjkim 2911289848Sjkim xor $t3, $t3 2912289848Sjkim adc \$-1, $a0 2913289848Sjkim mov $a2, $t2 2914289848Sjkim adc $poly1, $a1 2915289848Sjkim adc \$0, $a2 2916289848Sjkim mov $a3, $t3 2917289848Sjkim adc $poly3, $a3 2918289848Sjkim 2919289848Sjkim bt \$0, $t4 2920289848Sjkim cmovnc $t0, $a0 2921289848Sjkim cmovnc $t1, $a1 2922289848Sjkim mov $a0, 8*0($r_ptr) 2923289848Sjkim cmovnc $t2, $a2 2924289848Sjkim mov $a1, 8*1($r_ptr) 2925289848Sjkim cmovnc $t3, $a3 2926289848Sjkim mov $a2, 8*2($r_ptr) 2927289848Sjkim mov $a3, 8*3($r_ptr) 2928289848Sjkim 2929289848Sjkim ret 2930289848Sjkim.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx 2931289848Sjkim 2932289848Sjkim.type __ecp_nistz256_subx,\@abi-omnipotent 2933289848Sjkim.align 32 2934289848Sjkim__ecp_nistz256_subx: 2935289848Sjkim xor $t4, $t4 2936289848Sjkim sbb $a0, $t0 2937289848Sjkim sbb $a1, $t1 2938289848Sjkim mov $t0, $a0 2939289848Sjkim sbb $a2, $t2 2940289848Sjkim sbb $a3, $t3 2941289848Sjkim mov $t1, $a1 2942289848Sjkim sbb \$0, $t4 2943289848Sjkim 2944289848Sjkim xor $a3 ,$a3 2945289848Sjkim adc \$-1, $t0 2946289848Sjkim mov $t2, $a2 2947289848Sjkim adc $poly1, $t1 2948289848Sjkim adc \$0, $t2 2949289848Sjkim mov $t3, $a3 2950289848Sjkim adc $poly3, $t3 2951289848Sjkim 2952289848Sjkim bt \$0, $t4 2953289848Sjkim cmovc $t0, $a0 2954289848Sjkim cmovc $t1, $a1 2955289848Sjkim cmovc $t2, $a2 2956289848Sjkim cmovc $t3, $a3 2957289848Sjkim 2958289848Sjkim ret 2959289848Sjkim.size __ecp_nistz256_subx,.-__ecp_nistz256_subx 2960289848Sjkim 2961289848Sjkim.type __ecp_nistz256_mul_by_2x,\@abi-omnipotent 2962289848Sjkim.align 32 2963289848Sjkim__ecp_nistz256_mul_by_2x: 2964289848Sjkim xor $t4, $t4 2965289848Sjkim adc $a0, $a0 # a0:a3+a0:a3 2966289848Sjkim adc $a1, $a1 2967289848Sjkim mov $a0, $t0 2968289848Sjkim adc $a2, $a2 2969289848Sjkim adc $a3, $a3 2970289848Sjkim mov $a1, $t1 2971289848Sjkim adc \$0, $t4 2972289848Sjkim 2973289848Sjkim xor $t3, $t3 2974289848Sjkim sbb \$-1, $a0 2975289848Sjkim mov $a2, $t2 2976289848Sjkim sbb $poly1, $a1 2977289848Sjkim sbb \$0, $a2 2978289848Sjkim mov $a3, $t3 2979289848Sjkim sbb $poly3, $a3 2980306195Sjkim sbb \$0, $t4 2981289848Sjkim 2982306195Sjkim cmovc $t0, $a0 2983306195Sjkim cmovc $t1, $a1 2984289848Sjkim mov $a0, 8*0($r_ptr) 2985306195Sjkim cmovc $t2, $a2 2986289848Sjkim mov $a1, 8*1($r_ptr) 2987306195Sjkim cmovc $t3, $a3 2988289848Sjkim mov $a2, 8*2($r_ptr) 2989289848Sjkim mov $a3, 8*3($r_ptr) 2990289848Sjkim 2991289848Sjkim ret 2992289848Sjkim.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x 2993289848Sjkim___ 2994289848Sjkim } 2995289848Sjkim&gen_double("x"); 2996289848Sjkim&gen_add("x"); 2997289848Sjkim&gen_add_affine("x"); 2998289848Sjkim} 2999289848Sjkim}}} 3000289848Sjkim 3001289848Sjkim$code =~ s/\`([^\`]*)\`/eval $1/gem; 3002289848Sjkimprint $code; 3003289848Sjkimclose STDOUT; 3004