1e71b7053SJung-uk Kim#!/usr/bin/env perl 217f01e99SJung-uk Kim# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim# 4b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License"). You may not use 5e71b7053SJung-uk Kim# this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim# 9e71b7053SJung-uk Kim# ==================================================================== 10e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 11e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and 12e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further 13e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/. 14e71b7053SJung-uk Kim# ==================================================================== 15e71b7053SJung-uk Kim# 16e71b7053SJung-uk Kim# X25519 lower-level primitives for x86_64. 17e71b7053SJung-uk Kim# 18e71b7053SJung-uk Kim# February 2018. 19e71b7053SJung-uk Kim# 20e71b7053SJung-uk Kim# This module implements radix 2^51 multiplication and squaring, and 21e71b7053SJung-uk Kim# radix 2^64 multiplication, squaring, addition, subtraction and final 22e71b7053SJung-uk Kim# reduction. Latter radix is used on ADCX/ADOX-capable processors such 23e71b7053SJung-uk Kim# as Broadwell. On related note one should mention that there are 24e71b7053SJung-uk Kim# vector implementations that provide significantly better performance 25e71b7053SJung-uk Kim# on some processors(*), but they are large and overly complex. Which 26e71b7053SJung-uk Kim# in combination with them being effectively processor-specific makes 27e71b7053SJung-uk Kim# the undertaking hard to justify. The goal for this implementation 28e71b7053SJung-uk Kim# is rather versatility and simplicity [and ultimately formal 29e71b7053SJung-uk Kim# verification]. 30e71b7053SJung-uk Kim# 31e71b7053SJung-uk Kim# (*) For example sandy2x should provide ~30% improvement on Sandy 32e71b7053SJung-uk Kim# Bridge, but only nominal ~5% on Haswell [and big loss on 33e71b7053SJung-uk Kim# Broadwell and successors]. 34e71b7053SJung-uk Kim# 35e71b7053SJung-uk Kim###################################################################### 36e71b7053SJung-uk Kim# Improvement coefficients: 37e71b7053SJung-uk Kim# 38e71b7053SJung-uk Kim# amd64-51(*) gcc-5.x(**) 39e71b7053SJung-uk Kim# 40e71b7053SJung-uk Kim# P4 +22% +40% 41e71b7053SJung-uk Kim# Sandy Bridge -3% +11% 42e71b7053SJung-uk Kim# Haswell -1% +13% 43e71b7053SJung-uk Kim# Broadwell(***) +30% +35% 44e71b7053SJung-uk Kim# Skylake(***) +33% +47% 45e71b7053SJung-uk Kim# Silvermont +20% +26% 46e71b7053SJung-uk Kim# Goldmont +40% +50% 47e71b7053SJung-uk Kim# Bulldozer +20% +9% 48e71b7053SJung-uk Kim# Ryzen(***) +43% +40% 49e71b7053SJung-uk Kim# VIA +170% +120% 50e71b7053SJung-uk Kim# 51e71b7053SJung-uk Kim# (*) amd64-51 is popular assembly implementation with 2^51 radix, 52e71b7053SJung-uk Kim# only multiplication and squaring subroutines were linked 53e71b7053SJung-uk Kim# for comparison, but not complete ladder step; gain on most 54e71b7053SJung-uk Kim# processors is because this module refrains from shld, and 55e71b7053SJung-uk Kim# minor regression on others is because this does result in 56e71b7053SJung-uk Kim# higher instruction count; 57e71b7053SJung-uk Kim# (**) compiler is free to inline functions, in assembly one would 58e71b7053SJung-uk Kim# need to implement ladder step to do that, and it will improve 59e71b7053SJung-uk Kim# performance by several percent; 60e71b7053SJung-uk Kim# (***) ADCX/ADOX result for 2^64 radix, there is no corresponding 61e71b7053SJung-uk Kim# C implementation, so that comparison is always against 62e71b7053SJung-uk Kim# 2^51 radix; 63e71b7053SJung-uk Kim 64b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension) 65b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file 66b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; 67b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; 68e71b7053SJung-uk Kim 69e71b7053SJung-uk Kim$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); 70e71b7053SJung-uk Kim 71e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 72e71b7053SJung-uk Kim( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 73e71b7053SJung-uk Kim( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 74e71b7053SJung-uk Kimdie "can't locate x86_64-xlate.pl"; 75e71b7053SJung-uk Kim 76b077aed3SPierre Proncheryopen OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" 77b077aed3SPierre Pronchery or die "can't call $xlate: $!"; 78e71b7053SJung-uk Kim*STDOUT=*OUT; 79e71b7053SJung-uk Kim 80e71b7053SJung-uk Kimif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` 81e71b7053SJung-uk Kim =~ /GNU assembler version ([2-9]\.[0-9]+)/) { 82e71b7053SJung-uk Kim $addx = ($1>=2.23); 83e71b7053SJung-uk Kim} 84e71b7053SJung-uk Kim 85e71b7053SJung-uk Kimif (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && 86e71b7053SJung-uk Kim `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) { 87e71b7053SJung-uk Kim $addx = ($1>=2.10); 88e71b7053SJung-uk Kim} 89e71b7053SJung-uk Kim 90e71b7053SJung-uk Kimif (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && 91e71b7053SJung-uk Kim `ml64 2>&1` =~ /Version ([0-9]+)\./) { 92e71b7053SJung-uk Kim $addx = ($1>=12); 93e71b7053SJung-uk Kim} 94e71b7053SJung-uk Kim 9563c1bb51SJung-uk Kimif (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { 96e71b7053SJung-uk Kim my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 97e71b7053SJung-uk Kim $addx = ($ver>=3.03); 98e71b7053SJung-uk Kim} 99e71b7053SJung-uk Kim 100e71b7053SJung-uk Kim$code.=<<___; 101e71b7053SJung-uk Kim.text 102e71b7053SJung-uk Kim 103e71b7053SJung-uk Kim.globl x25519_fe51_mul 104e71b7053SJung-uk Kim.type x25519_fe51_mul,\@function,3 105e71b7053SJung-uk Kim.align 32 106e71b7053SJung-uk Kimx25519_fe51_mul: 107e71b7053SJung-uk Kim.cfi_startproc 108e71b7053SJung-uk Kim push %rbp 109e71b7053SJung-uk Kim.cfi_push %rbp 110e71b7053SJung-uk Kim push %rbx 111e71b7053SJung-uk Kim.cfi_push %rbx 112e71b7053SJung-uk Kim push %r12 113e71b7053SJung-uk Kim.cfi_push %r12 114e71b7053SJung-uk Kim push %r13 115e71b7053SJung-uk Kim.cfi_push %r13 116e71b7053SJung-uk Kim push %r14 117e71b7053SJung-uk Kim.cfi_push %r14 118e71b7053SJung-uk Kim push %r15 119e71b7053SJung-uk Kim.cfi_push %r15 120e71b7053SJung-uk Kim lea -8*5(%rsp),%rsp 121e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 40 122e71b7053SJung-uk Kim.Lfe51_mul_body: 123e71b7053SJung-uk Kim 124e71b7053SJung-uk Kim mov 8*0(%rsi),%rax # f[0] 125e71b7053SJung-uk Kim mov 8*0(%rdx),%r11 # load g[0-4] 126e71b7053SJung-uk Kim mov 8*1(%rdx),%r12 127e71b7053SJung-uk Kim mov 8*2(%rdx),%r13 128e71b7053SJung-uk Kim mov 8*3(%rdx),%rbp 129e71b7053SJung-uk Kim mov 8*4(%rdx),%r14 130e71b7053SJung-uk Kim 131e71b7053SJung-uk Kim mov %rdi,8*4(%rsp) # offload 1st argument 132e71b7053SJung-uk Kim mov %rax,%rdi 133e71b7053SJung-uk Kim mulq %r11 # f[0]*g[0] 134e71b7053SJung-uk Kim mov %r11,8*0(%rsp) # offload g[0] 135e71b7053SJung-uk Kim mov %rax,%rbx # %rbx:%rcx = h0 136e71b7053SJung-uk Kim mov %rdi,%rax 137e71b7053SJung-uk Kim mov %rdx,%rcx 138e71b7053SJung-uk Kim mulq %r12 # f[0]*g[1] 139e71b7053SJung-uk Kim mov %r12,8*1(%rsp) # offload g[1] 140e71b7053SJung-uk Kim mov %rax,%r8 # %r8:%r9 = h1 141e71b7053SJung-uk Kim mov %rdi,%rax 142e71b7053SJung-uk Kim lea (%r14,%r14,8),%r15 143e71b7053SJung-uk Kim mov %rdx,%r9 144e71b7053SJung-uk Kim mulq %r13 # f[0]*g[2] 145e71b7053SJung-uk Kim mov %r13,8*2(%rsp) # offload g[2] 146e71b7053SJung-uk Kim mov %rax,%r10 # %r10:%r11 = h2 147e71b7053SJung-uk Kim mov %rdi,%rax 148e71b7053SJung-uk Kim lea (%r14,%r15,2),%rdi # g[4]*19 149e71b7053SJung-uk Kim mov %rdx,%r11 150e71b7053SJung-uk Kim mulq %rbp # f[0]*g[3] 151e71b7053SJung-uk Kim mov %rax,%r12 # %r12:%r13 = h3 152e71b7053SJung-uk Kim mov 8*0(%rsi),%rax # f[0] 153e71b7053SJung-uk Kim mov %rdx,%r13 154e71b7053SJung-uk Kim mulq %r14 # f[0]*g[4] 155e71b7053SJung-uk Kim mov %rax,%r14 # %r14:%r15 = h4 156e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # f[1] 157e71b7053SJung-uk Kim mov %rdx,%r15 158e71b7053SJung-uk Kim 159e71b7053SJung-uk Kim mulq %rdi # f[1]*g[4]*19 160e71b7053SJung-uk Kim add %rax,%rbx 161e71b7053SJung-uk Kim mov 8*2(%rsi),%rax # f[2] 162e71b7053SJung-uk Kim adc %rdx,%rcx 163e71b7053SJung-uk Kim mulq %rdi # f[2]*g[4]*19 164e71b7053SJung-uk Kim add %rax,%r8 165e71b7053SJung-uk Kim mov 8*3(%rsi),%rax # f[3] 166e71b7053SJung-uk Kim adc %rdx,%r9 167e71b7053SJung-uk Kim mulq %rdi # f[3]*g[4]*19 168e71b7053SJung-uk Kim add %rax,%r10 169e71b7053SJung-uk Kim mov 8*4(%rsi),%rax # f[4] 170e71b7053SJung-uk Kim adc %rdx,%r11 171e71b7053SJung-uk Kim mulq %rdi # f[4]*g[4]*19 172e71b7053SJung-uk Kim imulq \$19,%rbp,%rdi # g[3]*19 173e71b7053SJung-uk Kim add %rax,%r12 174e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # f[1] 175e71b7053SJung-uk Kim adc %rdx,%r13 176e71b7053SJung-uk Kim mulq %rbp # f[1]*g[3] 177e71b7053SJung-uk Kim mov 8*2(%rsp),%rbp # g[2] 178e71b7053SJung-uk Kim add %rax,%r14 179e71b7053SJung-uk Kim mov 8*2(%rsi),%rax # f[2] 180e71b7053SJung-uk Kim adc %rdx,%r15 181e71b7053SJung-uk Kim 182e71b7053SJung-uk Kim mulq %rdi # f[2]*g[3]*19 183e71b7053SJung-uk Kim add %rax,%rbx 184e71b7053SJung-uk Kim mov 8*3(%rsi),%rax # f[3] 185e71b7053SJung-uk Kim adc %rdx,%rcx 186e71b7053SJung-uk Kim mulq %rdi # f[3]*g[3]*19 187e71b7053SJung-uk Kim add %rax,%r8 188e71b7053SJung-uk Kim mov 8*4(%rsi),%rax # f[4] 189e71b7053SJung-uk Kim adc %rdx,%r9 190e71b7053SJung-uk Kim mulq %rdi # f[4]*g[3]*19 191e71b7053SJung-uk Kim imulq \$19,%rbp,%rdi # g[2]*19 192e71b7053SJung-uk Kim add %rax,%r10 193e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # f[1] 194e71b7053SJung-uk Kim adc %rdx,%r11 195e71b7053SJung-uk Kim mulq %rbp # f[1]*g[2] 196e71b7053SJung-uk Kim add %rax,%r12 197e71b7053SJung-uk Kim mov 8*2(%rsi),%rax # f[2] 198e71b7053SJung-uk Kim adc %rdx,%r13 199e71b7053SJung-uk Kim mulq %rbp # f[2]*g[2] 200e71b7053SJung-uk Kim mov 8*1(%rsp),%rbp # g[1] 201e71b7053SJung-uk Kim add %rax,%r14 202e71b7053SJung-uk Kim mov 8*3(%rsi),%rax # f[3] 203e71b7053SJung-uk Kim adc %rdx,%r15 204e71b7053SJung-uk Kim 205e71b7053SJung-uk Kim mulq %rdi # f[3]*g[2]*19 206e71b7053SJung-uk Kim add %rax,%rbx 207e71b7053SJung-uk Kim mov 8*4(%rsi),%rax # f[3] 208e71b7053SJung-uk Kim adc %rdx,%rcx 209e71b7053SJung-uk Kim mulq %rdi # f[4]*g[2]*19 210e71b7053SJung-uk Kim add %rax,%r8 211e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # f[1] 212e71b7053SJung-uk Kim adc %rdx,%r9 213e71b7053SJung-uk Kim mulq %rbp # f[1]*g[1] 214e71b7053SJung-uk Kim imulq \$19,%rbp,%rdi 215e71b7053SJung-uk Kim add %rax,%r10 216e71b7053SJung-uk Kim mov 8*2(%rsi),%rax # f[2] 217e71b7053SJung-uk Kim adc %rdx,%r11 218e71b7053SJung-uk Kim mulq %rbp # f[2]*g[1] 219e71b7053SJung-uk Kim add %rax,%r12 220e71b7053SJung-uk Kim mov 8*3(%rsi),%rax # f[3] 221e71b7053SJung-uk Kim adc %rdx,%r13 222e71b7053SJung-uk Kim mulq %rbp # f[3]*g[1] 223e71b7053SJung-uk Kim mov 8*0(%rsp),%rbp # g[0] 224e71b7053SJung-uk Kim add %rax,%r14 225e71b7053SJung-uk Kim mov 8*4(%rsi),%rax # f[4] 226e71b7053SJung-uk Kim adc %rdx,%r15 227e71b7053SJung-uk Kim 228e71b7053SJung-uk Kim mulq %rdi # f[4]*g[1]*19 229e71b7053SJung-uk Kim add %rax,%rbx 230e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # f[1] 231e71b7053SJung-uk Kim adc %rdx,%rcx 232e71b7053SJung-uk Kim mul %rbp # f[1]*g[0] 233e71b7053SJung-uk Kim add %rax,%r8 234e71b7053SJung-uk Kim mov 8*2(%rsi),%rax # f[2] 235e71b7053SJung-uk Kim adc %rdx,%r9 236e71b7053SJung-uk Kim mul %rbp # f[2]*g[0] 237e71b7053SJung-uk Kim add %rax,%r10 238e71b7053SJung-uk Kim mov 8*3(%rsi),%rax # f[3] 239e71b7053SJung-uk Kim adc %rdx,%r11 240e71b7053SJung-uk Kim mul %rbp # f[3]*g[0] 241e71b7053SJung-uk Kim add %rax,%r12 242e71b7053SJung-uk Kim mov 8*4(%rsi),%rax # f[4] 243e71b7053SJung-uk Kim adc %rdx,%r13 244e71b7053SJung-uk Kim mulq %rbp # f[4]*g[0] 245e71b7053SJung-uk Kim add %rax,%r14 246e71b7053SJung-uk Kim adc %rdx,%r15 247e71b7053SJung-uk Kim 248e71b7053SJung-uk Kim mov 8*4(%rsp),%rdi # restore 1st argument 249e71b7053SJung-uk Kim jmp .Lreduce51 250e71b7053SJung-uk Kim.Lfe51_mul_epilogue: 251e71b7053SJung-uk Kim.cfi_endproc 252e71b7053SJung-uk Kim.size x25519_fe51_mul,.-x25519_fe51_mul 253e71b7053SJung-uk Kim 254e71b7053SJung-uk Kim.globl x25519_fe51_sqr 255e71b7053SJung-uk Kim.type x25519_fe51_sqr,\@function,2 256e71b7053SJung-uk Kim.align 32 257e71b7053SJung-uk Kimx25519_fe51_sqr: 258e71b7053SJung-uk Kim.cfi_startproc 259e71b7053SJung-uk Kim push %rbp 260e71b7053SJung-uk Kim.cfi_push %rbp 261e71b7053SJung-uk Kim push %rbx 262e71b7053SJung-uk Kim.cfi_push %rbx 263e71b7053SJung-uk Kim push %r12 264e71b7053SJung-uk Kim.cfi_push %r12 265e71b7053SJung-uk Kim push %r13 266e71b7053SJung-uk Kim.cfi_push %r13 267e71b7053SJung-uk Kim push %r14 268e71b7053SJung-uk Kim.cfi_push %r14 269e71b7053SJung-uk Kim push %r15 270e71b7053SJung-uk Kim.cfi_push %r15 271e71b7053SJung-uk Kim lea -8*5(%rsp),%rsp 272e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 40 273e71b7053SJung-uk Kim.Lfe51_sqr_body: 274e71b7053SJung-uk Kim 275e71b7053SJung-uk Kim mov 8*0(%rsi),%rax # g[0] 276e71b7053SJung-uk Kim mov 8*2(%rsi),%r15 # g[2] 277e71b7053SJung-uk Kim mov 8*4(%rsi),%rbp # g[4] 278e71b7053SJung-uk Kim 279e71b7053SJung-uk Kim mov %rdi,8*4(%rsp) # offload 1st argument 280e71b7053SJung-uk Kim lea (%rax,%rax),%r14 281e71b7053SJung-uk Kim mulq %rax # g[0]*g[0] 282e71b7053SJung-uk Kim mov %rax,%rbx 283e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # g[1] 284e71b7053SJung-uk Kim mov %rdx,%rcx 285e71b7053SJung-uk Kim mulq %r14 # 2*g[0]*g[1] 286e71b7053SJung-uk Kim mov %rax,%r8 287e71b7053SJung-uk Kim mov %r15,%rax 288e71b7053SJung-uk Kim mov %r15,8*0(%rsp) # offload g[2] 289e71b7053SJung-uk Kim mov %rdx,%r9 290e71b7053SJung-uk Kim mulq %r14 # 2*g[0]*g[2] 291e71b7053SJung-uk Kim mov %rax,%r10 292e71b7053SJung-uk Kim mov 8*3(%rsi),%rax 293e71b7053SJung-uk Kim mov %rdx,%r11 294e71b7053SJung-uk Kim imulq \$19,%rbp,%rdi # g[4]*19 295e71b7053SJung-uk Kim mulq %r14 # 2*g[0]*g[3] 296e71b7053SJung-uk Kim mov %rax,%r12 297e71b7053SJung-uk Kim mov %rbp,%rax 298e71b7053SJung-uk Kim mov %rdx,%r13 299e71b7053SJung-uk Kim mulq %r14 # 2*g[0]*g[4] 300e71b7053SJung-uk Kim mov %rax,%r14 301e71b7053SJung-uk Kim mov %rbp,%rax 302e71b7053SJung-uk Kim mov %rdx,%r15 303e71b7053SJung-uk Kim 304e71b7053SJung-uk Kim mulq %rdi # g[4]*g[4]*19 305e71b7053SJung-uk Kim add %rax,%r12 306e71b7053SJung-uk Kim mov 8*1(%rsi),%rax # g[1] 307e71b7053SJung-uk Kim adc %rdx,%r13 308e71b7053SJung-uk Kim 309e71b7053SJung-uk Kim mov 8*3(%rsi),%rsi # g[3] 310e71b7053SJung-uk Kim lea (%rax,%rax),%rbp 311e71b7053SJung-uk Kim mulq %rax # g[1]*g[1] 312e71b7053SJung-uk Kim add %rax,%r10 313e71b7053SJung-uk Kim mov 8*0(%rsp),%rax # g[2] 314e71b7053SJung-uk Kim adc %rdx,%r11 315e71b7053SJung-uk Kim mulq %rbp # 2*g[1]*g[2] 316e71b7053SJung-uk Kim add %rax,%r12 317e71b7053SJung-uk Kim mov %rbp,%rax 318e71b7053SJung-uk Kim adc %rdx,%r13 319e71b7053SJung-uk Kim mulq %rsi # 2*g[1]*g[3] 320e71b7053SJung-uk Kim add %rax,%r14 321e71b7053SJung-uk Kim mov %rbp,%rax 322e71b7053SJung-uk Kim adc %rdx,%r15 323e71b7053SJung-uk Kim imulq \$19,%rsi,%rbp # g[3]*19 324e71b7053SJung-uk Kim mulq %rdi # 2*g[1]*g[4]*19 325e71b7053SJung-uk Kim add %rax,%rbx 326e71b7053SJung-uk Kim lea (%rsi,%rsi),%rax 327e71b7053SJung-uk Kim adc %rdx,%rcx 328e71b7053SJung-uk Kim 329e71b7053SJung-uk Kim mulq %rdi # 2*g[3]*g[4]*19 330e71b7053SJung-uk Kim add %rax,%r10 331e71b7053SJung-uk Kim mov %rsi,%rax 332e71b7053SJung-uk Kim adc %rdx,%r11 333e71b7053SJung-uk Kim mulq %rbp # g[3]*g[3]*19 334e71b7053SJung-uk Kim add %rax,%r8 335e71b7053SJung-uk Kim mov 8*0(%rsp),%rax # g[2] 336e71b7053SJung-uk Kim adc %rdx,%r9 337e71b7053SJung-uk Kim 338e71b7053SJung-uk Kim lea (%rax,%rax),%rsi 339e71b7053SJung-uk Kim mulq %rax # g[2]*g[2] 340e71b7053SJung-uk Kim add %rax,%r14 341e71b7053SJung-uk Kim mov %rbp,%rax 342e71b7053SJung-uk Kim adc %rdx,%r15 343e71b7053SJung-uk Kim mulq %rsi # 2*g[2]*g[3]*19 344e71b7053SJung-uk Kim add %rax,%rbx 345e71b7053SJung-uk Kim mov %rsi,%rax 346e71b7053SJung-uk Kim adc %rdx,%rcx 347e71b7053SJung-uk Kim mulq %rdi # 2*g[2]*g[4]*19 348e71b7053SJung-uk Kim add %rax,%r8 349e71b7053SJung-uk Kim adc %rdx,%r9 350e71b7053SJung-uk Kim 351e71b7053SJung-uk Kim mov 8*4(%rsp),%rdi # restore 1st argument 352e71b7053SJung-uk Kim jmp .Lreduce51 353e71b7053SJung-uk Kim 354e71b7053SJung-uk Kim.align 32 355e71b7053SJung-uk Kim.Lreduce51: 356e71b7053SJung-uk Kim mov \$0x7ffffffffffff,%rbp 357e71b7053SJung-uk Kim 358e71b7053SJung-uk Kim mov %r10,%rdx 359e71b7053SJung-uk Kim shr \$51,%r10 360e71b7053SJung-uk Kim shl \$13,%r11 361e71b7053SJung-uk Kim and %rbp,%rdx # %rdx = g2 = h2 & mask 362e71b7053SJung-uk Kim or %r10,%r11 # h2>>51 363e71b7053SJung-uk Kim add %r11,%r12 364e71b7053SJung-uk Kim adc \$0,%r13 # h3 += h2>>51 365e71b7053SJung-uk Kim 366e71b7053SJung-uk Kim mov %rbx,%rax 367e71b7053SJung-uk Kim shr \$51,%rbx 368e71b7053SJung-uk Kim shl \$13,%rcx 369e71b7053SJung-uk Kim and %rbp,%rax # %rax = g0 = h0 & mask 370e71b7053SJung-uk Kim or %rbx,%rcx # h0>>51 371e71b7053SJung-uk Kim add %rcx,%r8 # h1 += h0>>51 372e71b7053SJung-uk Kim adc \$0,%r9 373e71b7053SJung-uk Kim 374e71b7053SJung-uk Kim mov %r12,%rbx 375e71b7053SJung-uk Kim shr \$51,%r12 376e71b7053SJung-uk Kim shl \$13,%r13 377e71b7053SJung-uk Kim and %rbp,%rbx # %rbx = g3 = h3 & mask 378e71b7053SJung-uk Kim or %r12,%r13 # h3>>51 379e71b7053SJung-uk Kim add %r13,%r14 # h4 += h3>>51 380e71b7053SJung-uk Kim adc \$0,%r15 381e71b7053SJung-uk Kim 382e71b7053SJung-uk Kim mov %r8,%rcx 383e71b7053SJung-uk Kim shr \$51,%r8 384e71b7053SJung-uk Kim shl \$13,%r9 385e71b7053SJung-uk Kim and %rbp,%rcx # %rcx = g1 = h1 & mask 386e71b7053SJung-uk Kim or %r8,%r9 387e71b7053SJung-uk Kim add %r9,%rdx # g2 += h1>>51 388e71b7053SJung-uk Kim 389e71b7053SJung-uk Kim mov %r14,%r10 390e71b7053SJung-uk Kim shr \$51,%r14 391e71b7053SJung-uk Kim shl \$13,%r15 392e71b7053SJung-uk Kim and %rbp,%r10 # %r10 = g4 = h0 & mask 393e71b7053SJung-uk Kim or %r14,%r15 # h0>>51 394e71b7053SJung-uk Kim 395e71b7053SJung-uk Kim lea (%r15,%r15,8),%r14 396e71b7053SJung-uk Kim lea (%r15,%r14,2),%r15 397e71b7053SJung-uk Kim add %r15,%rax # g0 += (h0>>51)*19 398e71b7053SJung-uk Kim 399e71b7053SJung-uk Kim mov %rdx,%r8 400e71b7053SJung-uk Kim and %rbp,%rdx # g2 &= mask 401e71b7053SJung-uk Kim shr \$51,%r8 402e71b7053SJung-uk Kim add %r8,%rbx # g3 += g2>>51 403e71b7053SJung-uk Kim 404e71b7053SJung-uk Kim mov %rax,%r9 405e71b7053SJung-uk Kim and %rbp,%rax # g0 &= mask 406e71b7053SJung-uk Kim shr \$51,%r9 407e71b7053SJung-uk Kim add %r9,%rcx # g1 += g0>>51 408e71b7053SJung-uk Kim 409e71b7053SJung-uk Kim mov %rax,8*0(%rdi) # save the result 410e71b7053SJung-uk Kim mov %rcx,8*1(%rdi) 411e71b7053SJung-uk Kim mov %rdx,8*2(%rdi) 412e71b7053SJung-uk Kim mov %rbx,8*3(%rdi) 413e71b7053SJung-uk Kim mov %r10,8*4(%rdi) 414e71b7053SJung-uk Kim 415e71b7053SJung-uk Kim mov 8*5(%rsp),%r15 416e71b7053SJung-uk Kim.cfi_restore %r15 417e71b7053SJung-uk Kim mov 8*6(%rsp),%r14 418e71b7053SJung-uk Kim.cfi_restore %r14 419e71b7053SJung-uk Kim mov 8*7(%rsp),%r13 420e71b7053SJung-uk Kim.cfi_restore %r13 421e71b7053SJung-uk Kim mov 8*8(%rsp),%r12 422e71b7053SJung-uk Kim.cfi_restore %r12 423e71b7053SJung-uk Kim mov 8*9(%rsp),%rbx 424e71b7053SJung-uk Kim.cfi_restore %rbx 425e71b7053SJung-uk Kim mov 8*10(%rsp),%rbp 426e71b7053SJung-uk Kim.cfi_restore %rbp 427e71b7053SJung-uk Kim lea 8*11(%rsp),%rsp 428e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 88 429e71b7053SJung-uk Kim.Lfe51_sqr_epilogue: 430e71b7053SJung-uk Kim ret 431e71b7053SJung-uk Kim.cfi_endproc 432e71b7053SJung-uk Kim.size x25519_fe51_sqr,.-x25519_fe51_sqr 433e71b7053SJung-uk Kim 434e71b7053SJung-uk Kim.globl x25519_fe51_mul121666 435e71b7053SJung-uk Kim.type x25519_fe51_mul121666,\@function,2 436e71b7053SJung-uk Kim.align 32 437e71b7053SJung-uk Kimx25519_fe51_mul121666: 438e71b7053SJung-uk Kim.cfi_startproc 439e71b7053SJung-uk Kim push %rbp 440e71b7053SJung-uk Kim.cfi_push %rbp 441e71b7053SJung-uk Kim push %rbx 442e71b7053SJung-uk Kim.cfi_push %rbx 443e71b7053SJung-uk Kim push %r12 444e71b7053SJung-uk Kim.cfi_push %r12 445e71b7053SJung-uk Kim push %r13 446e71b7053SJung-uk Kim.cfi_push %r13 447e71b7053SJung-uk Kim push %r14 448e71b7053SJung-uk Kim.cfi_push %r14 449e71b7053SJung-uk Kim push %r15 450e71b7053SJung-uk Kim.cfi_push %r15 451e71b7053SJung-uk Kim lea -8*5(%rsp),%rsp 452e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 40 453e71b7053SJung-uk Kim.Lfe51_mul121666_body: 454e71b7053SJung-uk Kim mov \$121666,%eax 455e71b7053SJung-uk Kim 456e71b7053SJung-uk Kim mulq 8*0(%rsi) 457e71b7053SJung-uk Kim mov %rax,%rbx # %rbx:%rcx = h0 458e71b7053SJung-uk Kim mov \$121666,%eax 459e71b7053SJung-uk Kim mov %rdx,%rcx 460e71b7053SJung-uk Kim mulq 8*1(%rsi) 461e71b7053SJung-uk Kim mov %rax,%r8 # %r8:%r9 = h1 462e71b7053SJung-uk Kim mov \$121666,%eax 463e71b7053SJung-uk Kim mov %rdx,%r9 464e71b7053SJung-uk Kim mulq 8*2(%rsi) 465e71b7053SJung-uk Kim mov %rax,%r10 # %r10:%r11 = h2 466e71b7053SJung-uk Kim mov \$121666,%eax 467e71b7053SJung-uk Kim mov %rdx,%r11 468e71b7053SJung-uk Kim mulq 8*3(%rsi) 469e71b7053SJung-uk Kim mov %rax,%r12 # %r12:%r13 = h3 470e71b7053SJung-uk Kim mov \$121666,%eax # f[0] 471e71b7053SJung-uk Kim mov %rdx,%r13 472e71b7053SJung-uk Kim mulq 8*4(%rsi) 473e71b7053SJung-uk Kim mov %rax,%r14 # %r14:%r15 = h4 474e71b7053SJung-uk Kim mov %rdx,%r15 475e71b7053SJung-uk Kim 476e71b7053SJung-uk Kim jmp .Lreduce51 477e71b7053SJung-uk Kim.Lfe51_mul121666_epilogue: 478e71b7053SJung-uk Kim.cfi_endproc 479e71b7053SJung-uk Kim.size x25519_fe51_mul121666,.-x25519_fe51_mul121666 480e71b7053SJung-uk Kim___ 481e71b7053SJung-uk Kim######################################################################## 482e71b7053SJung-uk Kim# Base 2^64 subroutines modulo 2*(2^255-19) 483e71b7053SJung-uk Kim# 484e71b7053SJung-uk Kimif ($addx) { 485e71b7053SJung-uk Kimmy ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7) = map("%r$_",(8..15)); 486e71b7053SJung-uk Kim 487e71b7053SJung-uk Kim$code.=<<___; 488e71b7053SJung-uk Kim.extern OPENSSL_ia32cap_P 489e71b7053SJung-uk Kim.globl x25519_fe64_eligible 490e71b7053SJung-uk Kim.type x25519_fe64_eligible,\@abi-omnipotent 491e71b7053SJung-uk Kim.align 32 492e71b7053SJung-uk Kimx25519_fe64_eligible: 49317f01e99SJung-uk Kim.cfi_startproc 494e71b7053SJung-uk Kim mov OPENSSL_ia32cap_P+8(%rip),%ecx 495e71b7053SJung-uk Kim xor %eax,%eax 496e71b7053SJung-uk Kim and \$0x80100,%ecx 497e71b7053SJung-uk Kim cmp \$0x80100,%ecx 498e71b7053SJung-uk Kim cmove %ecx,%eax 499e71b7053SJung-uk Kim ret 50017f01e99SJung-uk Kim.cfi_endproc 501e71b7053SJung-uk Kim.size x25519_fe64_eligible,.-x25519_fe64_eligible 502e71b7053SJung-uk Kim 503e71b7053SJung-uk Kim.globl x25519_fe64_mul 504e71b7053SJung-uk Kim.type x25519_fe64_mul,\@function,3 505e71b7053SJung-uk Kim.align 32 506e71b7053SJung-uk Kimx25519_fe64_mul: 507e71b7053SJung-uk Kim.cfi_startproc 508e71b7053SJung-uk Kim push %rbp 509e71b7053SJung-uk Kim.cfi_push %rbp 510e71b7053SJung-uk Kim push %rbx 511e71b7053SJung-uk Kim.cfi_push %rbx 512e71b7053SJung-uk Kim push %r12 513e71b7053SJung-uk Kim.cfi_push %r12 514e71b7053SJung-uk Kim push %r13 515e71b7053SJung-uk Kim.cfi_push %r13 516e71b7053SJung-uk Kim push %r14 517e71b7053SJung-uk Kim.cfi_push %r14 518e71b7053SJung-uk Kim push %r15 519e71b7053SJung-uk Kim.cfi_push %r15 520e71b7053SJung-uk Kim push %rdi # offload dst 521e71b7053SJung-uk Kim.cfi_push %rdi 522e71b7053SJung-uk Kim lea -8*2(%rsp),%rsp 523e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 16 524e71b7053SJung-uk Kim.Lfe64_mul_body: 525e71b7053SJung-uk Kim 526e71b7053SJung-uk Kim mov %rdx,%rax 527e71b7053SJung-uk Kim mov 8*0(%rdx),%rbp # b[0] 528e71b7053SJung-uk Kim mov 8*0(%rsi),%rdx # a[0] 529e71b7053SJung-uk Kim mov 8*1(%rax),%rcx # b[1] 530e71b7053SJung-uk Kim mov 8*2(%rax),$acc6 # b[2] 531e71b7053SJung-uk Kim mov 8*3(%rax),$acc7 # b[3] 532e71b7053SJung-uk Kim 533e71b7053SJung-uk Kim mulx %rbp,$acc0,%rax # a[0]*b[0] 534e71b7053SJung-uk Kim xor %edi,%edi # cf=0,of=0 535e71b7053SJung-uk Kim mulx %rcx,$acc1,%rbx # a[0]*b[1] 536e71b7053SJung-uk Kim adcx %rax,$acc1 537e71b7053SJung-uk Kim mulx $acc6,$acc2,%rax # a[0]*b[2] 538e71b7053SJung-uk Kim adcx %rbx,$acc2 539e71b7053SJung-uk Kim mulx $acc7,$acc3,$acc4 # a[0]*b[3] 540e71b7053SJung-uk Kim mov 8*1(%rsi),%rdx # a[1] 541e71b7053SJung-uk Kim adcx %rax,$acc3 542e71b7053SJung-uk Kim mov $acc6,(%rsp) # offload b[2] 543e71b7053SJung-uk Kim adcx %rdi,$acc4 # cf=0 544e71b7053SJung-uk Kim 545e71b7053SJung-uk Kim mulx %rbp,%rax,%rbx # a[1]*b[0] 546e71b7053SJung-uk Kim adox %rax,$acc1 547e71b7053SJung-uk Kim adcx %rbx,$acc2 548e71b7053SJung-uk Kim mulx %rcx,%rax,%rbx # a[1]*b[1] 549e71b7053SJung-uk Kim adox %rax,$acc2 550e71b7053SJung-uk Kim adcx %rbx,$acc3 551e71b7053SJung-uk Kim mulx $acc6,%rax,%rbx # a[1]*b[2] 552e71b7053SJung-uk Kim adox %rax,$acc3 553e71b7053SJung-uk Kim adcx %rbx,$acc4 554e71b7053SJung-uk Kim mulx $acc7,%rax,$acc5 # a[1]*b[3] 555e71b7053SJung-uk Kim mov 8*2(%rsi),%rdx # a[2] 556e71b7053SJung-uk Kim adox %rax,$acc4 557e71b7053SJung-uk Kim adcx %rdi,$acc5 # cf=0 558e71b7053SJung-uk Kim adox %rdi,$acc5 # of=0 559e71b7053SJung-uk Kim 560e71b7053SJung-uk Kim mulx %rbp,%rax,%rbx # a[2]*b[0] 561e71b7053SJung-uk Kim adcx %rax,$acc2 562e71b7053SJung-uk Kim adox %rbx,$acc3 563e71b7053SJung-uk Kim mulx %rcx,%rax,%rbx # a[2]*b[1] 564e71b7053SJung-uk Kim adcx %rax,$acc3 565e71b7053SJung-uk Kim adox %rbx,$acc4 566e71b7053SJung-uk Kim mulx $acc6,%rax,%rbx # a[2]*b[2] 567e71b7053SJung-uk Kim adcx %rax,$acc4 568e71b7053SJung-uk Kim adox %rbx,$acc5 569e71b7053SJung-uk Kim mulx $acc7,%rax,$acc6 # a[2]*b[3] 570e71b7053SJung-uk Kim mov 8*3(%rsi),%rdx # a[3] 571e71b7053SJung-uk Kim adcx %rax,$acc5 572e71b7053SJung-uk Kim adox %rdi,$acc6 # of=0 573e71b7053SJung-uk Kim adcx %rdi,$acc6 # cf=0 574e71b7053SJung-uk Kim 575e71b7053SJung-uk Kim mulx %rbp,%rax,%rbx # a[3]*b[0] 576e71b7053SJung-uk Kim adox %rax,$acc3 577e71b7053SJung-uk Kim adcx %rbx,$acc4 578e71b7053SJung-uk Kim mulx %rcx,%rax,%rbx # a[3]*b[1] 579e71b7053SJung-uk Kim adox %rax,$acc4 580e71b7053SJung-uk Kim adcx %rbx,$acc5 581e71b7053SJung-uk Kim mulx (%rsp),%rax,%rbx # a[3]*b[2] 582e71b7053SJung-uk Kim adox %rax,$acc5 583e71b7053SJung-uk Kim adcx %rbx,$acc6 584e71b7053SJung-uk Kim mulx $acc7,%rax,$acc7 # a[3]*b[3] 585e71b7053SJung-uk Kim mov \$38,%edx 586e71b7053SJung-uk Kim adox %rax,$acc6 587e71b7053SJung-uk Kim adcx %rdi,$acc7 # cf=0 588e71b7053SJung-uk Kim adox %rdi,$acc7 # of=0 589e71b7053SJung-uk Kim 590e71b7053SJung-uk Kim jmp .Lreduce64 591e71b7053SJung-uk Kim.Lfe64_mul_epilogue: 592e71b7053SJung-uk Kim.cfi_endproc 593e71b7053SJung-uk Kim.size x25519_fe64_mul,.-x25519_fe64_mul 594e71b7053SJung-uk Kim 595e71b7053SJung-uk Kim.globl x25519_fe64_sqr 596e71b7053SJung-uk Kim.type x25519_fe64_sqr,\@function,2 597e71b7053SJung-uk Kim.align 32 598e71b7053SJung-uk Kimx25519_fe64_sqr: 599e71b7053SJung-uk Kim.cfi_startproc 600e71b7053SJung-uk Kim push %rbp 601e71b7053SJung-uk Kim.cfi_push %rbp 602e71b7053SJung-uk Kim push %rbx 603e71b7053SJung-uk Kim.cfi_push %rbx 604e71b7053SJung-uk Kim push %r12 605e71b7053SJung-uk Kim.cfi_push %r12 606e71b7053SJung-uk Kim push %r13 607e71b7053SJung-uk Kim.cfi_push %r13 608e71b7053SJung-uk Kim push %r14 609e71b7053SJung-uk Kim.cfi_push %r14 610e71b7053SJung-uk Kim push %r15 611e71b7053SJung-uk Kim.cfi_push %r15 612e71b7053SJung-uk Kim push %rdi # offload dst 613e71b7053SJung-uk Kim.cfi_push %rdi 614e71b7053SJung-uk Kim lea -8*2(%rsp),%rsp 615e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 16 616e71b7053SJung-uk Kim.Lfe64_sqr_body: 617e71b7053SJung-uk Kim 618e71b7053SJung-uk Kim mov 8*0(%rsi),%rdx # a[0] 619e71b7053SJung-uk Kim mov 8*1(%rsi),%rcx # a[1] 620e71b7053SJung-uk Kim mov 8*2(%rsi),%rbp # a[2] 621e71b7053SJung-uk Kim mov 8*3(%rsi),%rsi # a[3] 622e71b7053SJung-uk Kim 623e71b7053SJung-uk Kim ################################################################ 624e71b7053SJung-uk Kim mulx %rdx,$acc0,$acc7 # a[0]*a[0] 625e71b7053SJung-uk Kim mulx %rcx,$acc1,%rax # a[0]*a[1] 626e71b7053SJung-uk Kim xor %edi,%edi # cf=0,of=0 627e71b7053SJung-uk Kim mulx %rbp,$acc2,%rbx # a[0]*a[2] 628e71b7053SJung-uk Kim adcx %rax,$acc2 629e71b7053SJung-uk Kim mulx %rsi,$acc3,$acc4 # a[0]*a[3] 630e71b7053SJung-uk Kim mov %rcx,%rdx # a[1] 631e71b7053SJung-uk Kim adcx %rbx,$acc3 632e71b7053SJung-uk Kim adcx %rdi,$acc4 # cf=0 633e71b7053SJung-uk Kim 634e71b7053SJung-uk Kim ################################################################ 635e71b7053SJung-uk Kim mulx %rbp,%rax,%rbx # a[1]*a[2] 636e71b7053SJung-uk Kim adox %rax,$acc3 637e71b7053SJung-uk Kim adcx %rbx,$acc4 638e71b7053SJung-uk Kim mulx %rsi,%rax,$acc5 # a[1]*a[3] 639e71b7053SJung-uk Kim mov %rbp,%rdx # a[2] 640e71b7053SJung-uk Kim adox %rax,$acc4 641e71b7053SJung-uk Kim adcx %rdi,$acc5 642e71b7053SJung-uk Kim 643e71b7053SJung-uk Kim ################################################################ 644e71b7053SJung-uk Kim mulx %rsi,%rax,$acc6 # a[2]*a[3] 645e71b7053SJung-uk Kim mov %rcx,%rdx # a[1] 646e71b7053SJung-uk Kim adox %rax,$acc5 647e71b7053SJung-uk Kim adcx %rdi,$acc6 # cf=0 648e71b7053SJung-uk Kim adox %rdi,$acc6 # of=0 649e71b7053SJung-uk Kim 650e71b7053SJung-uk Kim adcx $acc1,$acc1 # acc1:6<<1 651e71b7053SJung-uk Kim adox $acc7,$acc1 652e71b7053SJung-uk Kim adcx $acc2,$acc2 653e71b7053SJung-uk Kim mulx %rdx,%rax,%rbx # a[1]*a[1] 654e71b7053SJung-uk Kim mov %rbp,%rdx # a[2] 655e71b7053SJung-uk Kim adcx $acc3,$acc3 656e71b7053SJung-uk Kim adox %rax,$acc2 657e71b7053SJung-uk Kim adcx $acc4,$acc4 658e71b7053SJung-uk Kim adox %rbx,$acc3 659e71b7053SJung-uk Kim mulx %rdx,%rax,%rbx # a[2]*a[2] 660e71b7053SJung-uk Kim mov %rsi,%rdx # a[3] 661e71b7053SJung-uk Kim adcx $acc5,$acc5 662e71b7053SJung-uk Kim adox %rax,$acc4 663e71b7053SJung-uk Kim adcx $acc6,$acc6 664e71b7053SJung-uk Kim adox %rbx,$acc5 665e71b7053SJung-uk Kim mulx %rdx,%rax,$acc7 # a[3]*a[3] 666e71b7053SJung-uk Kim mov \$38,%edx 667e71b7053SJung-uk Kim adox %rax,$acc6 668e71b7053SJung-uk Kim adcx %rdi,$acc7 # cf=0 669e71b7053SJung-uk Kim adox %rdi,$acc7 # of=0 670e71b7053SJung-uk Kim jmp .Lreduce64 671e71b7053SJung-uk Kim 672e71b7053SJung-uk Kim.align 32 673e71b7053SJung-uk Kim.Lreduce64: 674e71b7053SJung-uk Kim mulx $acc4,%rax,%rbx 675e71b7053SJung-uk Kim adcx %rax,$acc0 676e71b7053SJung-uk Kim adox %rbx,$acc1 677e71b7053SJung-uk Kim mulx $acc5,%rax,%rbx 678e71b7053SJung-uk Kim adcx %rax,$acc1 679e71b7053SJung-uk Kim adox %rbx,$acc2 680e71b7053SJung-uk Kim mulx $acc6,%rax,%rbx 681e71b7053SJung-uk Kim adcx %rax,$acc2 682e71b7053SJung-uk Kim adox %rbx,$acc3 683e71b7053SJung-uk Kim mulx $acc7,%rax,$acc4 684e71b7053SJung-uk Kim adcx %rax,$acc3 685e71b7053SJung-uk Kim adox %rdi,$acc4 686e71b7053SJung-uk Kim adcx %rdi,$acc4 687e71b7053SJung-uk Kim 688e71b7053SJung-uk Kim mov 8*2(%rsp),%rdi # restore dst 689e71b7053SJung-uk Kim imulq %rdx,$acc4 690e71b7053SJung-uk Kim 691e71b7053SJung-uk Kim add $acc4,$acc0 692e71b7053SJung-uk Kim adc \$0,$acc1 693e71b7053SJung-uk Kim adc \$0,$acc2 694e71b7053SJung-uk Kim adc \$0,$acc3 695e71b7053SJung-uk Kim 696e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 697e71b7053SJung-uk Kim and \$38,%rax 698e71b7053SJung-uk Kim 699e71b7053SJung-uk Kim add %rax,$acc0 700e71b7053SJung-uk Kim mov $acc1,8*1(%rdi) 701e71b7053SJung-uk Kim mov $acc2,8*2(%rdi) 702e71b7053SJung-uk Kim mov $acc3,8*3(%rdi) 703e71b7053SJung-uk Kim mov $acc0,8*0(%rdi) 704e71b7053SJung-uk Kim 705e71b7053SJung-uk Kim mov 8*3(%rsp),%r15 706e71b7053SJung-uk Kim.cfi_restore %r15 707e71b7053SJung-uk Kim mov 8*4(%rsp),%r14 708e71b7053SJung-uk Kim.cfi_restore %r14 709e71b7053SJung-uk Kim mov 8*5(%rsp),%r13 710e71b7053SJung-uk Kim.cfi_restore %r13 711e71b7053SJung-uk Kim mov 8*6(%rsp),%r12 712e71b7053SJung-uk Kim.cfi_restore %r12 713e71b7053SJung-uk Kim mov 8*7(%rsp),%rbx 714e71b7053SJung-uk Kim.cfi_restore %rbx 715e71b7053SJung-uk Kim mov 8*8(%rsp),%rbp 716e71b7053SJung-uk Kim.cfi_restore %rbp 717e71b7053SJung-uk Kim lea 8*9(%rsp),%rsp 718e71b7053SJung-uk Kim.cfi_adjust_cfa_offset 88 719e71b7053SJung-uk Kim.Lfe64_sqr_epilogue: 720e71b7053SJung-uk Kim ret 721e71b7053SJung-uk Kim.cfi_endproc 722e71b7053SJung-uk Kim.size x25519_fe64_sqr,.-x25519_fe64_sqr 723e71b7053SJung-uk Kim 724e71b7053SJung-uk Kim.globl x25519_fe64_mul121666 725e71b7053SJung-uk Kim.type x25519_fe64_mul121666,\@function,2 726e71b7053SJung-uk Kim.align 32 727e71b7053SJung-uk Kimx25519_fe64_mul121666: 728e71b7053SJung-uk Kim.Lfe64_mul121666_body: 72917f01e99SJung-uk Kim.cfi_startproc 730e71b7053SJung-uk Kim mov \$121666,%edx 731e71b7053SJung-uk Kim mulx 8*0(%rsi),$acc0,%rcx 732e71b7053SJung-uk Kim mulx 8*1(%rsi),$acc1,%rax 733e71b7053SJung-uk Kim add %rcx,$acc1 734e71b7053SJung-uk Kim mulx 8*2(%rsi),$acc2,%rcx 735e71b7053SJung-uk Kim adc %rax,$acc2 736e71b7053SJung-uk Kim mulx 8*3(%rsi),$acc3,%rax 737e71b7053SJung-uk Kim adc %rcx,$acc3 738e71b7053SJung-uk Kim adc \$0,%rax 739e71b7053SJung-uk Kim 740e71b7053SJung-uk Kim imulq \$38,%rax,%rax 741e71b7053SJung-uk Kim 742e71b7053SJung-uk Kim add %rax,$acc0 743e71b7053SJung-uk Kim adc \$0,$acc1 744e71b7053SJung-uk Kim adc \$0,$acc2 745e71b7053SJung-uk Kim adc \$0,$acc3 746e71b7053SJung-uk Kim 747e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 748e71b7053SJung-uk Kim and \$38,%rax 749e71b7053SJung-uk Kim 750e71b7053SJung-uk Kim add %rax,$acc0 751e71b7053SJung-uk Kim mov $acc1,8*1(%rdi) 752e71b7053SJung-uk Kim mov $acc2,8*2(%rdi) 753e71b7053SJung-uk Kim mov $acc3,8*3(%rdi) 754e71b7053SJung-uk Kim mov $acc0,8*0(%rdi) 755e71b7053SJung-uk Kim 756e71b7053SJung-uk Kim.Lfe64_mul121666_epilogue: 757e71b7053SJung-uk Kim ret 75817f01e99SJung-uk Kim.cfi_endproc 759e71b7053SJung-uk Kim.size x25519_fe64_mul121666,.-x25519_fe64_mul121666 760e71b7053SJung-uk Kim 761e71b7053SJung-uk Kim.globl x25519_fe64_add 762e71b7053SJung-uk Kim.type x25519_fe64_add,\@function,3 763e71b7053SJung-uk Kim.align 32 764e71b7053SJung-uk Kimx25519_fe64_add: 765e71b7053SJung-uk Kim.Lfe64_add_body: 76617f01e99SJung-uk Kim.cfi_startproc 767e71b7053SJung-uk Kim mov 8*0(%rsi),$acc0 768e71b7053SJung-uk Kim mov 8*1(%rsi),$acc1 769e71b7053SJung-uk Kim mov 8*2(%rsi),$acc2 770e71b7053SJung-uk Kim mov 8*3(%rsi),$acc3 771e71b7053SJung-uk Kim 772e71b7053SJung-uk Kim add 8*0(%rdx),$acc0 773e71b7053SJung-uk Kim adc 8*1(%rdx),$acc1 774e71b7053SJung-uk Kim adc 8*2(%rdx),$acc2 775e71b7053SJung-uk Kim adc 8*3(%rdx),$acc3 776e71b7053SJung-uk Kim 777e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 778e71b7053SJung-uk Kim and \$38,%rax 779e71b7053SJung-uk Kim 780e71b7053SJung-uk Kim add %rax,$acc0 781e71b7053SJung-uk Kim adc \$0,$acc1 782e71b7053SJung-uk Kim adc \$0,$acc2 783e71b7053SJung-uk Kim mov $acc1,8*1(%rdi) 784e71b7053SJung-uk Kim adc \$0,$acc3 785e71b7053SJung-uk Kim mov $acc2,8*2(%rdi) 786e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 787e71b7053SJung-uk Kim mov $acc3,8*3(%rdi) 788e71b7053SJung-uk Kim and \$38,%rax 789e71b7053SJung-uk Kim 790e71b7053SJung-uk Kim add %rax,$acc0 791e71b7053SJung-uk Kim mov $acc0,8*0(%rdi) 792e71b7053SJung-uk Kim 793e71b7053SJung-uk Kim.Lfe64_add_epilogue: 794e71b7053SJung-uk Kim ret 79517f01e99SJung-uk Kim.cfi_endproc 796e71b7053SJung-uk Kim.size x25519_fe64_add,.-x25519_fe64_add 797e71b7053SJung-uk Kim 798e71b7053SJung-uk Kim.globl x25519_fe64_sub 799e71b7053SJung-uk Kim.type x25519_fe64_sub,\@function,3 800e71b7053SJung-uk Kim.align 32 801e71b7053SJung-uk Kimx25519_fe64_sub: 802e71b7053SJung-uk Kim.Lfe64_sub_body: 80317f01e99SJung-uk Kim.cfi_startproc 804e71b7053SJung-uk Kim mov 8*0(%rsi),$acc0 805e71b7053SJung-uk Kim mov 8*1(%rsi),$acc1 806e71b7053SJung-uk Kim mov 8*2(%rsi),$acc2 807e71b7053SJung-uk Kim mov 8*3(%rsi),$acc3 808e71b7053SJung-uk Kim 809e71b7053SJung-uk Kim sub 8*0(%rdx),$acc0 810e71b7053SJung-uk Kim sbb 8*1(%rdx),$acc1 811e71b7053SJung-uk Kim sbb 8*2(%rdx),$acc2 812e71b7053SJung-uk Kim sbb 8*3(%rdx),$acc3 813e71b7053SJung-uk Kim 814e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 815e71b7053SJung-uk Kim and \$38,%rax 816e71b7053SJung-uk Kim 817e71b7053SJung-uk Kim sub %rax,$acc0 818e71b7053SJung-uk Kim sbb \$0,$acc1 819e71b7053SJung-uk Kim sbb \$0,$acc2 820e71b7053SJung-uk Kim mov $acc1,8*1(%rdi) 821e71b7053SJung-uk Kim sbb \$0,$acc3 822e71b7053SJung-uk Kim mov $acc2,8*2(%rdi) 823e71b7053SJung-uk Kim sbb %rax,%rax # cf -> mask 824e71b7053SJung-uk Kim mov $acc3,8*3(%rdi) 825e71b7053SJung-uk Kim and \$38,%rax 826e71b7053SJung-uk Kim 827e71b7053SJung-uk Kim sub %rax,$acc0 828e71b7053SJung-uk Kim mov $acc0,8*0(%rdi) 829e71b7053SJung-uk Kim 830e71b7053SJung-uk Kim.Lfe64_sub_epilogue: 831e71b7053SJung-uk Kim ret 83217f01e99SJung-uk Kim.cfi_endproc 833e71b7053SJung-uk Kim.size x25519_fe64_sub,.-x25519_fe64_sub 834e71b7053SJung-uk Kim 835e71b7053SJung-uk Kim.globl x25519_fe64_tobytes 836e71b7053SJung-uk Kim.type x25519_fe64_tobytes,\@function,2 837e71b7053SJung-uk Kim.align 32 838e71b7053SJung-uk Kimx25519_fe64_tobytes: 839e71b7053SJung-uk Kim.Lfe64_to_body: 84017f01e99SJung-uk Kim.cfi_startproc 841e71b7053SJung-uk Kim mov 8*0(%rsi),$acc0 842e71b7053SJung-uk Kim mov 8*1(%rsi),$acc1 843e71b7053SJung-uk Kim mov 8*2(%rsi),$acc2 844e71b7053SJung-uk Kim mov 8*3(%rsi),$acc3 845e71b7053SJung-uk Kim 846e71b7053SJung-uk Kim ################################# reduction modulo 2^255-19 847e71b7053SJung-uk Kim lea ($acc3,$acc3),%rax 848e71b7053SJung-uk Kim sar \$63,$acc3 # most significant bit -> mask 849e71b7053SJung-uk Kim shr \$1,%rax # most significant bit cleared 850e71b7053SJung-uk Kim and \$19,$acc3 851e71b7053SJung-uk Kim add \$19,$acc3 # compare to modulus in the same go 852e71b7053SJung-uk Kim 853e71b7053SJung-uk Kim add $acc3,$acc0 854e71b7053SJung-uk Kim adc \$0,$acc1 855e71b7053SJung-uk Kim adc \$0,$acc2 856e71b7053SJung-uk Kim adc \$0,%rax 857e71b7053SJung-uk Kim 858e71b7053SJung-uk Kim lea (%rax,%rax),$acc3 859e71b7053SJung-uk Kim sar \$63,%rax # most significant bit -> mask 860e71b7053SJung-uk Kim shr \$1,$acc3 # most significant bit cleared 861e71b7053SJung-uk Kim not %rax 862e71b7053SJung-uk Kim and \$19,%rax 863e71b7053SJung-uk Kim 864e71b7053SJung-uk Kim sub %rax,$acc0 865e71b7053SJung-uk Kim sbb \$0,$acc1 866e71b7053SJung-uk Kim sbb \$0,$acc2 867e71b7053SJung-uk Kim sbb \$0,$acc3 868e71b7053SJung-uk Kim 869e71b7053SJung-uk Kim mov $acc0,8*0(%rdi) 870e71b7053SJung-uk Kim mov $acc1,8*1(%rdi) 871e71b7053SJung-uk Kim mov $acc2,8*2(%rdi) 872e71b7053SJung-uk Kim mov $acc3,8*3(%rdi) 873e71b7053SJung-uk Kim 874e71b7053SJung-uk Kim.Lfe64_to_epilogue: 875e71b7053SJung-uk Kim ret 87617f01e99SJung-uk Kim.cfi_endproc 877e71b7053SJung-uk Kim.size x25519_fe64_tobytes,.-x25519_fe64_tobytes 878e71b7053SJung-uk Kim___ 879e71b7053SJung-uk Kim} else { 880e71b7053SJung-uk Kim$code.=<<___; 881e71b7053SJung-uk Kim.globl x25519_fe64_eligible 882e71b7053SJung-uk Kim.type x25519_fe64_eligible,\@abi-omnipotent 883e71b7053SJung-uk Kim.align 32 884e71b7053SJung-uk Kimx25519_fe64_eligible: 88517f01e99SJung-uk Kim.cfi_startproc 886e71b7053SJung-uk Kim xor %eax,%eax 887e71b7053SJung-uk Kim ret 88817f01e99SJung-uk Kim.cfi_endproc 889e71b7053SJung-uk Kim.size x25519_fe64_eligible,.-x25519_fe64_eligible 890e71b7053SJung-uk Kim 891e71b7053SJung-uk Kim.globl x25519_fe64_mul 892e71b7053SJung-uk Kim.type x25519_fe64_mul,\@abi-omnipotent 893e71b7053SJung-uk Kim.globl x25519_fe64_sqr 894e71b7053SJung-uk Kim.globl x25519_fe64_mul121666 895e71b7053SJung-uk Kim.globl x25519_fe64_add 896e71b7053SJung-uk Kim.globl x25519_fe64_sub 897e71b7053SJung-uk Kim.globl x25519_fe64_tobytes 898e71b7053SJung-uk Kimx25519_fe64_mul: 899e71b7053SJung-uk Kimx25519_fe64_sqr: 900e71b7053SJung-uk Kimx25519_fe64_mul121666: 901e71b7053SJung-uk Kimx25519_fe64_add: 902e71b7053SJung-uk Kimx25519_fe64_sub: 903e71b7053SJung-uk Kimx25519_fe64_tobytes: 90417f01e99SJung-uk Kim.cfi_startproc 905e71b7053SJung-uk Kim .byte 0x0f,0x0b # ud2 906e71b7053SJung-uk Kim ret 90717f01e99SJung-uk Kim.cfi_endproc 908e71b7053SJung-uk Kim.size x25519_fe64_mul,.-x25519_fe64_mul 909e71b7053SJung-uk Kim___ 910e71b7053SJung-uk Kim} 911e71b7053SJung-uk Kim$code.=<<___; 912e71b7053SJung-uk Kim.asciz "X25519 primitives for x86_64, CRYPTOGAMS by <appro\@openssl.org>" 913e71b7053SJung-uk Kim___ 914e71b7053SJung-uk Kim 915e71b7053SJung-uk Kim# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, 916e71b7053SJung-uk Kim# CONTEXT *context,DISPATCHER_CONTEXT *disp) 917e71b7053SJung-uk Kimif ($win64) { 918e71b7053SJung-uk Kim$rec="%rcx"; 919e71b7053SJung-uk Kim$frame="%rdx"; 920e71b7053SJung-uk Kim$context="%r8"; 921e71b7053SJung-uk Kim$disp="%r9"; 922e71b7053SJung-uk Kim 923e71b7053SJung-uk Kim$code.=<<___; 924e71b7053SJung-uk Kim.extern __imp_RtlVirtualUnwind 925e71b7053SJung-uk Kim 926e71b7053SJung-uk Kim.type short_handler,\@abi-omnipotent 927e71b7053SJung-uk Kim.align 16 928e71b7053SJung-uk Kimshort_handler: 929e71b7053SJung-uk Kim push %rsi 930e71b7053SJung-uk Kim push %rdi 931e71b7053SJung-uk Kim push %rbx 932e71b7053SJung-uk Kim push %rbp 933e71b7053SJung-uk Kim push %r12 934e71b7053SJung-uk Kim push %r13 935e71b7053SJung-uk Kim push %r14 936e71b7053SJung-uk Kim push %r15 937e71b7053SJung-uk Kim pushfq 938e71b7053SJung-uk Kim sub \$64,%rsp 939e71b7053SJung-uk Kim 940e71b7053SJung-uk Kim mov 120($context),%rax # pull context->Rax 941e71b7053SJung-uk Kim mov 248($context),%rbx # pull context->Rip 942e71b7053SJung-uk Kim 943e71b7053SJung-uk Kim mov 8($disp),%rsi # disp->ImageBase 944e71b7053SJung-uk Kim mov 56($disp),%r11 # disp->HandlerData 945e71b7053SJung-uk Kim 946e71b7053SJung-uk Kim mov 0(%r11),%r10d # HandlerData[0] 947e71b7053SJung-uk Kim lea (%rsi,%r10),%r10 # end of prologue label 948e71b7053SJung-uk Kim cmp %r10,%rbx # context->Rip<end of prologue label 949e71b7053SJung-uk Kim jb .Lcommon_seh_tail 950e71b7053SJung-uk Kim 951e71b7053SJung-uk Kim mov 152($context),%rax # pull context->Rsp 952e71b7053SJung-uk Kim jmp .Lcommon_seh_tail 953e71b7053SJung-uk Kim.size short_handler,.-short_handler 954e71b7053SJung-uk Kim 955e71b7053SJung-uk Kim.type full_handler,\@abi-omnipotent 956e71b7053SJung-uk Kim.align 16 957e71b7053SJung-uk Kimfull_handler: 958e71b7053SJung-uk Kim push %rsi 959e71b7053SJung-uk Kim push %rdi 960e71b7053SJung-uk Kim push %rbx 961e71b7053SJung-uk Kim push %rbp 962e71b7053SJung-uk Kim push %r12 963e71b7053SJung-uk Kim push %r13 964e71b7053SJung-uk Kim push %r14 965e71b7053SJung-uk Kim push %r15 966e71b7053SJung-uk Kim pushfq 967e71b7053SJung-uk Kim sub \$64,%rsp 968e71b7053SJung-uk Kim 969e71b7053SJung-uk Kim mov 120($context),%rax # pull context->Rax 970e71b7053SJung-uk Kim mov 248($context),%rbx # pull context->Rip 971e71b7053SJung-uk Kim 972e71b7053SJung-uk Kim mov 8($disp),%rsi # disp->ImageBase 973e71b7053SJung-uk Kim mov 56($disp),%r11 # disp->HandlerData 974e71b7053SJung-uk Kim 975e71b7053SJung-uk Kim mov 0(%r11),%r10d # HandlerData[0] 976e71b7053SJung-uk Kim lea (%rsi,%r10),%r10 # end of prologue label 977e71b7053SJung-uk Kim cmp %r10,%rbx # context->Rip<end of prologue label 978e71b7053SJung-uk Kim jb .Lcommon_seh_tail 979e71b7053SJung-uk Kim 980e71b7053SJung-uk Kim mov 152($context),%rax # pull context->Rsp 981e71b7053SJung-uk Kim 982e71b7053SJung-uk Kim mov 4(%r11),%r10d # HandlerData[1] 983e71b7053SJung-uk Kim lea (%rsi,%r10),%r10 # epilogue label 984e71b7053SJung-uk Kim cmp %r10,%rbx # context->Rip>=epilogue label 985e71b7053SJung-uk Kim jae .Lcommon_seh_tail 986e71b7053SJung-uk Kim 987e71b7053SJung-uk Kim mov 8(%r11),%r10d # HandlerData[2] 988e71b7053SJung-uk Kim lea (%rax,%r10),%rax 989e71b7053SJung-uk Kim 990e71b7053SJung-uk Kim mov -8(%rax),%rbp 991e71b7053SJung-uk Kim mov -16(%rax),%rbx 992e71b7053SJung-uk Kim mov -24(%rax),%r12 993e71b7053SJung-uk Kim mov -32(%rax),%r13 994e71b7053SJung-uk Kim mov -40(%rax),%r14 995e71b7053SJung-uk Kim mov -48(%rax),%r15 996e71b7053SJung-uk Kim mov %rbx,144($context) # restore context->Rbx 997e71b7053SJung-uk Kim mov %rbp,160($context) # restore context->Rbp 998e71b7053SJung-uk Kim mov %r12,216($context) # restore context->R12 999e71b7053SJung-uk Kim mov %r13,224($context) # restore context->R13 1000e71b7053SJung-uk Kim mov %r14,232($context) # restore context->R14 1001e71b7053SJung-uk Kim mov %r15,240($context) # restore context->R15 1002e71b7053SJung-uk Kim 1003e71b7053SJung-uk Kim.Lcommon_seh_tail: 1004e71b7053SJung-uk Kim mov 8(%rax),%rdi 1005e71b7053SJung-uk Kim mov 16(%rax),%rsi 1006e71b7053SJung-uk Kim mov %rax,152($context) # restore context->Rsp 1007e71b7053SJung-uk Kim mov %rsi,168($context) # restore context->Rsi 1008e71b7053SJung-uk Kim mov %rdi,176($context) # restore context->Rdi 1009e71b7053SJung-uk Kim 1010e71b7053SJung-uk Kim mov 40($disp),%rdi # disp->ContextRecord 1011e71b7053SJung-uk Kim mov $context,%rsi # context 1012e71b7053SJung-uk Kim mov \$154,%ecx # sizeof(CONTEXT) 1013e71b7053SJung-uk Kim .long 0xa548f3fc # cld; rep movsq 1014e71b7053SJung-uk Kim 1015e71b7053SJung-uk Kim mov $disp,%rsi 1016e71b7053SJung-uk Kim xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER 1017e71b7053SJung-uk Kim mov 8(%rsi),%rdx # arg2, disp->ImageBase 1018e71b7053SJung-uk Kim mov 0(%rsi),%r8 # arg3, disp->ControlPc 1019e71b7053SJung-uk Kim mov 16(%rsi),%r9 # arg4, disp->FunctionEntry 1020e71b7053SJung-uk Kim mov 40(%rsi),%r10 # disp->ContextRecord 1021e71b7053SJung-uk Kim lea 56(%rsi),%r11 # &disp->HandlerData 1022e71b7053SJung-uk Kim lea 24(%rsi),%r12 # &disp->EstablisherFrame 1023e71b7053SJung-uk Kim mov %r10,32(%rsp) # arg5 1024e71b7053SJung-uk Kim mov %r11,40(%rsp) # arg6 1025e71b7053SJung-uk Kim mov %r12,48(%rsp) # arg7 1026e71b7053SJung-uk Kim mov %rcx,56(%rsp) # arg8, (NULL) 1027e71b7053SJung-uk Kim call *__imp_RtlVirtualUnwind(%rip) 1028e71b7053SJung-uk Kim 1029e71b7053SJung-uk Kim mov \$1,%eax # ExceptionContinueSearch 1030e71b7053SJung-uk Kim add \$64,%rsp 1031e71b7053SJung-uk Kim popfq 1032e71b7053SJung-uk Kim pop %r15 1033e71b7053SJung-uk Kim pop %r14 1034e71b7053SJung-uk Kim pop %r13 1035e71b7053SJung-uk Kim pop %r12 1036e71b7053SJung-uk Kim pop %rbp 1037e71b7053SJung-uk Kim pop %rbx 1038e71b7053SJung-uk Kim pop %rdi 1039e71b7053SJung-uk Kim pop %rsi 1040e71b7053SJung-uk Kim ret 1041e71b7053SJung-uk Kim.size full_handler,.-full_handler 1042e71b7053SJung-uk Kim 1043e71b7053SJung-uk Kim.section .pdata 1044e71b7053SJung-uk Kim.align 4 1045e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe51_mul 1046e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe51_mul 1047e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe51_mul 1048e71b7053SJung-uk Kim 1049e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe51_sqr 1050e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe51_sqr 1051e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe51_sqr 1052e71b7053SJung-uk Kim 1053e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe51_mul121666 1054e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe51_mul121666 1055e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe51_mul121666 1056e71b7053SJung-uk Kim___ 1057e71b7053SJung-uk Kim$code.=<<___ if ($addx); 1058e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_mul 1059e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_mul 1060e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_mul 1061e71b7053SJung-uk Kim 1062e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_sqr 1063e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_sqr 1064e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_sqr 1065e71b7053SJung-uk Kim 1066e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_mul121666 1067e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_mul121666 1068e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_mul121666 1069e71b7053SJung-uk Kim 1070e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_add 1071e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_add 1072e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_add 1073e71b7053SJung-uk Kim 1074e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_sub 1075e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_sub 1076e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_sub 1077e71b7053SJung-uk Kim 1078e71b7053SJung-uk Kim .rva .LSEH_begin_x25519_fe64_tobytes 1079e71b7053SJung-uk Kim .rva .LSEH_end_x25519_fe64_tobytes 1080e71b7053SJung-uk Kim .rva .LSEH_info_x25519_fe64_tobytes 1081e71b7053SJung-uk Kim___ 1082e71b7053SJung-uk Kim$code.=<<___; 1083e71b7053SJung-uk Kim.section .xdata 1084e71b7053SJung-uk Kim.align 8 1085e71b7053SJung-uk Kim.LSEH_info_x25519_fe51_mul: 1086e71b7053SJung-uk Kim .byte 9,0,0,0 1087e71b7053SJung-uk Kim .rva full_handler 1088e71b7053SJung-uk Kim .rva .Lfe51_mul_body,.Lfe51_mul_epilogue # HandlerData[] 1089e71b7053SJung-uk Kim .long 88,0 1090e71b7053SJung-uk Kim.LSEH_info_x25519_fe51_sqr: 1091e71b7053SJung-uk Kim .byte 9,0,0,0 1092e71b7053SJung-uk Kim .rva full_handler 1093e71b7053SJung-uk Kim .rva .Lfe51_sqr_body,.Lfe51_sqr_epilogue # HandlerData[] 1094e71b7053SJung-uk Kim .long 88,0 1095e71b7053SJung-uk Kim.LSEH_info_x25519_fe51_mul121666: 1096e71b7053SJung-uk Kim .byte 9,0,0,0 1097e71b7053SJung-uk Kim .rva full_handler 1098e71b7053SJung-uk Kim .rva .Lfe51_mul121666_body,.Lfe51_mul121666_epilogue # HandlerData[] 1099e71b7053SJung-uk Kim .long 88,0 1100e71b7053SJung-uk Kim___ 1101e71b7053SJung-uk Kim$code.=<<___ if ($addx); 1102e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_mul: 1103e71b7053SJung-uk Kim .byte 9,0,0,0 1104e71b7053SJung-uk Kim .rva full_handler 1105e71b7053SJung-uk Kim .rva .Lfe64_mul_body,.Lfe64_mul_epilogue # HandlerData[] 1106e71b7053SJung-uk Kim .long 72,0 1107e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_sqr: 1108e71b7053SJung-uk Kim .byte 9,0,0,0 1109e71b7053SJung-uk Kim .rva full_handler 1110e71b7053SJung-uk Kim .rva .Lfe64_sqr_body,.Lfe64_sqr_epilogue # HandlerData[] 1111e71b7053SJung-uk Kim .long 72,0 1112e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_mul121666: 1113e71b7053SJung-uk Kim .byte 9,0,0,0 1114e71b7053SJung-uk Kim .rva short_handler 1115e71b7053SJung-uk Kim .rva .Lfe64_mul121666_body,.Lfe64_mul121666_epilogue # HandlerData[] 1116e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_add: 1117e71b7053SJung-uk Kim .byte 9,0,0,0 1118e71b7053SJung-uk Kim .rva short_handler 1119e71b7053SJung-uk Kim .rva .Lfe64_add_body,.Lfe64_add_epilogue # HandlerData[] 1120e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_sub: 1121e71b7053SJung-uk Kim .byte 9,0,0,0 1122e71b7053SJung-uk Kim .rva short_handler 1123e71b7053SJung-uk Kim .rva .Lfe64_sub_body,.Lfe64_sub_epilogue # HandlerData[] 1124e71b7053SJung-uk Kim.LSEH_info_x25519_fe64_tobytes: 1125e71b7053SJung-uk Kim .byte 9,0,0,0 1126e71b7053SJung-uk Kim .rva short_handler 1127e71b7053SJung-uk Kim .rva .Lfe64_to_body,.Lfe64_to_epilogue # HandlerData[] 1128e71b7053SJung-uk Kim___ 1129e71b7053SJung-uk Kim} 1130e71b7053SJung-uk Kim 1131e71b7053SJung-uk Kim$code =~ s/\`([^\`]*)\`/eval $1/gem; 1132e71b7053SJung-uk Kimprint $code; 113317f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!"; 1134