1e1051a39Sopenharmony_ci#! /usr/bin/env perl 2e1051a39Sopenharmony_ci# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci# 4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci# this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci# ==================================================================== 11e1051a39Sopenharmony_ci# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 12e1051a39Sopenharmony_ci# project. The module is, however, dual licensed under OpenSSL and 13e1051a39Sopenharmony_ci# CRYPTOGAMS licenses depending on where you obtain it. For further 14e1051a39Sopenharmony_ci# details see http://www.openssl.org/~appro/cryptogams/. 15e1051a39Sopenharmony_ci# ==================================================================== 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci# October 2012. 18e1051a39Sopenharmony_ci# 19e1051a39Sopenharmony_ci# SPARCv9 VIS3 Montgomery multiplication procedure suitable for T3 and 20e1051a39Sopenharmony_ci# onward. There are three new instructions used here: umulxhi, 21e1051a39Sopenharmony_ci# addxc[cc] and initializing store. On T3 RSA private key operations 22e1051a39Sopenharmony_ci# are 1.54/1.87/2.11/2.26 times faster for 512/1024/2048/4096-bit key 23e1051a39Sopenharmony_ci# lengths. This is without dedicated squaring procedure. On T4 24e1051a39Sopenharmony_ci# corresponding coefficients are 1.47/2.10/2.80/2.90x, which is mostly 25e1051a39Sopenharmony_ci# for reference purposes, because T4 has dedicated Montgomery 26e1051a39Sopenharmony_ci# multiplication and squaring *instructions* that deliver even more. 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci$output = pop and open STDOUT,">$output"; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci$frame = "STACK_FRAME"; 31e1051a39Sopenharmony_ci$bias = "STACK_BIAS"; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci$code.=<<___; 34e1051a39Sopenharmony_ci#ifndef __ASSEMBLER__ 35e1051a39Sopenharmony_ci# define __ASSEMBLER__ 1 36e1051a39Sopenharmony_ci#endif 37e1051a39Sopenharmony_ci#include "crypto/sparc_arch.h" 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ci#ifdef __arch64__ 40e1051a39Sopenharmony_ci.register %g2,#scratch 41e1051a39Sopenharmony_ci.register %g3,#scratch 42e1051a39Sopenharmony_ci#endif 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci.section ".text",#alloc,#execinstr 45e1051a39Sopenharmony_ci___ 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)= 48e1051a39Sopenharmony_ci (map("%g$_",(1..5)),map("%o$_",(0..5,7))); 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci# int bn_mul_mont( 51e1051a39Sopenharmony_ci$rp="%o0"; # BN_ULONG *rp, 52e1051a39Sopenharmony_ci$ap="%o1"; # const BN_ULONG *ap, 53e1051a39Sopenharmony_ci$bp="%o2"; # const BN_ULONG *bp, 54e1051a39Sopenharmony_ci$np="%o3"; # const BN_ULONG *np, 55e1051a39Sopenharmony_ci$n0p="%o4"; # const BN_ULONG *n0, 56e1051a39Sopenharmony_ci$num="%o5"; # int num); # caller ensures that num is even 57e1051a39Sopenharmony_ci # and >=6 58e1051a39Sopenharmony_ci$code.=<<___; 59e1051a39Sopenharmony_ci.globl bn_mul_mont_vis3 60e1051a39Sopenharmony_ci.align 32 61e1051a39Sopenharmony_cibn_mul_mont_vis3: 62e1051a39Sopenharmony_ci add %sp, $bias, %g4 ! real top of stack 63e1051a39Sopenharmony_ci sll $num, 2, $num ! size in bytes 64e1051a39Sopenharmony_ci add $num, 63, %g5 65e1051a39Sopenharmony_ci andn %g5, 63, %g5 ! buffer size rounded up to 64 bytes 66e1051a39Sopenharmony_ci add %g5, %g5, %g1 67e1051a39Sopenharmony_ci add %g5, %g1, %g1 ! 3*buffer size 68e1051a39Sopenharmony_ci sub %g4, %g1, %g1 69e1051a39Sopenharmony_ci andn %g1, 63, %g1 ! align at 64 byte 70e1051a39Sopenharmony_ci sub %g1, $frame, %g1 ! new top of stack 71e1051a39Sopenharmony_ci sub %g1, %g4, %g1 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci save %sp, %g1, %sp 74e1051a39Sopenharmony_ci___ 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci# +-------------------------------+<----- %sp 77e1051a39Sopenharmony_ci# . . 78e1051a39Sopenharmony_ci# +-------------------------------+<----- aligned at 64 bytes 79e1051a39Sopenharmony_ci# | __int64 tmp[0] | 80e1051a39Sopenharmony_ci# +-------------------------------+ 81e1051a39Sopenharmony_ci# . . 82e1051a39Sopenharmony_ci# . . 83e1051a39Sopenharmony_ci# +-------------------------------+<----- aligned at 64 bytes 84e1051a39Sopenharmony_ci# | __int64 ap[1..0] | converted ap[] 85e1051a39Sopenharmony_ci# +-------------------------------+ 86e1051a39Sopenharmony_ci# | __int64 np[1..0] | converted np[] 87e1051a39Sopenharmony_ci# +-------------------------------+ 88e1051a39Sopenharmony_ci# | __int64 ap[3..2] | 89e1051a39Sopenharmony_ci# . . 90e1051a39Sopenharmony_ci# . . 91e1051a39Sopenharmony_ci# +-------------------------------+ 92e1051a39Sopenharmony_ci($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5)); 93e1051a39Sopenharmony_ci($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$anp)=map("%l$_",(0..7)); 94e1051a39Sopenharmony_ci($ovf,$i)=($t0,$t1); 95e1051a39Sopenharmony_ci$code.=<<___; 96e1051a39Sopenharmony_ci ld [$n0p+0], $t0 ! pull n0[0..1] value 97e1051a39Sopenharmony_ci add %sp, $bias+$frame, $tp 98e1051a39Sopenharmony_ci ld [$n0p+4], $t1 99e1051a39Sopenharmony_ci add $tp, %g5, $anp 100e1051a39Sopenharmony_ci ld [$bp+0], $t2 ! m0=bp[0] 101e1051a39Sopenharmony_ci sllx $t1, 32, $n0 102e1051a39Sopenharmony_ci ld [$bp+4], $t3 103e1051a39Sopenharmony_ci or $t0, $n0, $n0 104e1051a39Sopenharmony_ci add $bp, 8, $bp 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci ld [$ap+0], $t0 ! ap[0] 107e1051a39Sopenharmony_ci sllx $t3, 32, $m0 108e1051a39Sopenharmony_ci ld [$ap+4], $t1 109e1051a39Sopenharmony_ci or $t2, $m0, $m0 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci ld [$ap+8], $t2 ! ap[1] 112e1051a39Sopenharmony_ci sllx $t1, 32, $aj 113e1051a39Sopenharmony_ci ld [$ap+12], $t3 114e1051a39Sopenharmony_ci or $t0, $aj, $aj 115e1051a39Sopenharmony_ci add $ap, 16, $ap 116e1051a39Sopenharmony_ci stx $aj, [$anp] ! converted ap[0] 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci mulx $aj, $m0, $lo0 ! ap[0]*bp[0] 119e1051a39Sopenharmony_ci umulxhi $aj, $m0, $hi0 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci ld [$np+0], $t0 ! np[0] 122e1051a39Sopenharmony_ci sllx $t3, 32, $aj 123e1051a39Sopenharmony_ci ld [$np+4], $t1 124e1051a39Sopenharmony_ci or $t2, $aj, $aj 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci ld [$np+8], $t2 ! np[1] 127e1051a39Sopenharmony_ci sllx $t1, 32, $nj 128e1051a39Sopenharmony_ci ld [$np+12], $t3 129e1051a39Sopenharmony_ci or $t0, $nj, $nj 130e1051a39Sopenharmony_ci add $np, 16, $np 131e1051a39Sopenharmony_ci stx $nj, [$anp+8] ! converted np[0] 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ci mulx $lo0, $n0, $m1 ! "tp[0]"*n0 134e1051a39Sopenharmony_ci stx $aj, [$anp+16] ! converted ap[1] 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ci mulx $aj, $m0, $alo ! ap[1]*bp[0] 137e1051a39Sopenharmony_ci umulxhi $aj, $m0, $aj ! ahi=aj 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci mulx $nj, $m1, $lo1 ! np[0]*m1 140e1051a39Sopenharmony_ci umulxhi $nj, $m1, $hi1 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci sllx $t3, 32, $nj 143e1051a39Sopenharmony_ci or $t2, $nj, $nj 144e1051a39Sopenharmony_ci stx $nj, [$anp+24] ! converted np[1] 145e1051a39Sopenharmony_ci add $anp, 32, $anp 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci addcc $lo0, $lo1, $lo1 148e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci mulx $nj, $m1, $nlo ! np[1]*m1 151e1051a39Sopenharmony_ci umulxhi $nj, $m1, $nj ! nhi=nj 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci ba .L1st 154e1051a39Sopenharmony_ci sub $num, 24, $cnt ! cnt=num-3 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci.align 16 157e1051a39Sopenharmony_ci.L1st: 158e1051a39Sopenharmony_ci ld [$ap+0], $t0 ! ap[j] 159e1051a39Sopenharmony_ci addcc $alo, $hi0, $lo0 160e1051a39Sopenharmony_ci ld [$ap+4], $t1 161e1051a39Sopenharmony_ci addxc $aj, %g0, $hi0 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ci sllx $t1, 32, $aj 164e1051a39Sopenharmony_ci add $ap, 8, $ap 165e1051a39Sopenharmony_ci or $t0, $aj, $aj 166e1051a39Sopenharmony_ci stx $aj, [$anp] ! converted ap[j] 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ci ld [$np+0], $t2 ! np[j] 169e1051a39Sopenharmony_ci addcc $nlo, $hi1, $lo1 170e1051a39Sopenharmony_ci ld [$np+4], $t3 171e1051a39Sopenharmony_ci addxc $nj, %g0, $hi1 ! nhi=nj 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci sllx $t3, 32, $nj 174e1051a39Sopenharmony_ci add $np, 8, $np 175e1051a39Sopenharmony_ci mulx $aj, $m0, $alo ! ap[j]*bp[0] 176e1051a39Sopenharmony_ci or $t2, $nj, $nj 177e1051a39Sopenharmony_ci umulxhi $aj, $m0, $aj ! ahi=aj 178e1051a39Sopenharmony_ci stx $nj, [$anp+8] ! converted np[j] 179e1051a39Sopenharmony_ci add $anp, 16, $anp ! anp++ 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci mulx $nj, $m1, $nlo ! np[j]*m1 182e1051a39Sopenharmony_ci addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0] 183e1051a39Sopenharmony_ci umulxhi $nj, $m1, $nj ! nhi=nj 184e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 185e1051a39Sopenharmony_ci stx $lo1, [$tp] ! tp[j-1] 186e1051a39Sopenharmony_ci add $tp, 8, $tp ! tp++ 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci brnz,pt $cnt, .L1st 189e1051a39Sopenharmony_ci sub $cnt, 8, $cnt ! j-- 190e1051a39Sopenharmony_ci!.L1st 191e1051a39Sopenharmony_ci addcc $alo, $hi0, $lo0 192e1051a39Sopenharmony_ci addxc $aj, %g0, $hi0 ! ahi=aj 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_ci addcc $nlo, $hi1, $lo1 195e1051a39Sopenharmony_ci addxc $nj, %g0, $hi1 196e1051a39Sopenharmony_ci addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0] 197e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 198e1051a39Sopenharmony_ci stx $lo1, [$tp] ! tp[j-1] 199e1051a39Sopenharmony_ci add $tp, 8, $tp 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci addcc $hi0, $hi1, $hi1 202e1051a39Sopenharmony_ci addxc %g0, %g0, $ovf ! upmost overflow bit 203e1051a39Sopenharmony_ci stx $hi1, [$tp] 204e1051a39Sopenharmony_ci add $tp, 8, $tp 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci ba .Louter 207e1051a39Sopenharmony_ci sub $num, 16, $i ! i=num-2 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci.align 16 210e1051a39Sopenharmony_ci.Louter: 211e1051a39Sopenharmony_ci ld [$bp+0], $t2 ! m0=bp[i] 212e1051a39Sopenharmony_ci ld [$bp+4], $t3 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci sub $anp, $num, $anp ! rewind 215e1051a39Sopenharmony_ci sub $tp, $num, $tp 216e1051a39Sopenharmony_ci sub $anp, $num, $anp 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci add $bp, 8, $bp 219e1051a39Sopenharmony_ci sllx $t3, 32, $m0 220e1051a39Sopenharmony_ci ldx [$anp+0], $aj ! ap[0] 221e1051a39Sopenharmony_ci or $t2, $m0, $m0 222e1051a39Sopenharmony_ci ldx [$anp+8], $nj ! np[0] 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci mulx $aj, $m0, $lo0 ! ap[0]*bp[i] 225e1051a39Sopenharmony_ci ldx [$tp], $tj ! tp[0] 226e1051a39Sopenharmony_ci umulxhi $aj, $m0, $hi0 227e1051a39Sopenharmony_ci ldx [$anp+16], $aj ! ap[1] 228e1051a39Sopenharmony_ci addcc $lo0, $tj, $lo0 ! ap[0]*bp[i]+tp[0] 229e1051a39Sopenharmony_ci mulx $aj, $m0, $alo ! ap[1]*bp[i] 230e1051a39Sopenharmony_ci addxc %g0, $hi0, $hi0 231e1051a39Sopenharmony_ci mulx $lo0, $n0, $m1 ! tp[0]*n0 232e1051a39Sopenharmony_ci umulxhi $aj, $m0, $aj ! ahi=aj 233e1051a39Sopenharmony_ci mulx $nj, $m1, $lo1 ! np[0]*m1 234e1051a39Sopenharmony_ci umulxhi $nj, $m1, $hi1 235e1051a39Sopenharmony_ci ldx [$anp+24], $nj ! np[1] 236e1051a39Sopenharmony_ci add $anp, 32, $anp 237e1051a39Sopenharmony_ci addcc $lo1, $lo0, $lo1 238e1051a39Sopenharmony_ci mulx $nj, $m1, $nlo ! np[1]*m1 239e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 240e1051a39Sopenharmony_ci umulxhi $nj, $m1, $nj ! nhi=nj 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci ba .Linner 243e1051a39Sopenharmony_ci sub $num, 24, $cnt ! cnt=num-3 244e1051a39Sopenharmony_ci.align 16 245e1051a39Sopenharmony_ci.Linner: 246e1051a39Sopenharmony_ci addcc $alo, $hi0, $lo0 247e1051a39Sopenharmony_ci ldx [$tp+8], $tj ! tp[j] 248e1051a39Sopenharmony_ci addxc $aj, %g0, $hi0 ! ahi=aj 249e1051a39Sopenharmony_ci ldx [$anp+0], $aj ! ap[j] 250e1051a39Sopenharmony_ci addcc $nlo, $hi1, $lo1 251e1051a39Sopenharmony_ci mulx $aj, $m0, $alo ! ap[j]*bp[i] 252e1051a39Sopenharmony_ci addxc $nj, %g0, $hi1 ! nhi=nj 253e1051a39Sopenharmony_ci ldx [$anp+8], $nj ! np[j] 254e1051a39Sopenharmony_ci add $anp, 16, $anp 255e1051a39Sopenharmony_ci umulxhi $aj, $m0, $aj ! ahi=aj 256e1051a39Sopenharmony_ci addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j] 257e1051a39Sopenharmony_ci mulx $nj, $m1, $nlo ! np[j]*m1 258e1051a39Sopenharmony_ci addxc %g0, $hi0, $hi0 259e1051a39Sopenharmony_ci umulxhi $nj, $m1, $nj ! nhi=nj 260e1051a39Sopenharmony_ci addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j] 261e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 262e1051a39Sopenharmony_ci stx $lo1, [$tp] ! tp[j-1] 263e1051a39Sopenharmony_ci add $tp, 8, $tp 264e1051a39Sopenharmony_ci brnz,pt $cnt, .Linner 265e1051a39Sopenharmony_ci sub $cnt, 8, $cnt 266e1051a39Sopenharmony_ci!.Linner 267e1051a39Sopenharmony_ci ldx [$tp+8], $tj ! tp[j] 268e1051a39Sopenharmony_ci addcc $alo, $hi0, $lo0 269e1051a39Sopenharmony_ci addxc $aj, %g0, $hi0 ! ahi=aj 270e1051a39Sopenharmony_ci addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j] 271e1051a39Sopenharmony_ci addxc %g0, $hi0, $hi0 272e1051a39Sopenharmony_ci 273e1051a39Sopenharmony_ci addcc $nlo, $hi1, $lo1 274e1051a39Sopenharmony_ci addxc $nj, %g0, $hi1 ! nhi=nj 275e1051a39Sopenharmony_ci addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j] 276e1051a39Sopenharmony_ci addxc %g0, $hi1, $hi1 277e1051a39Sopenharmony_ci stx $lo1, [$tp] ! tp[j-1] 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci subcc %g0, $ovf, %g0 ! move upmost overflow to CCR.xcc 280e1051a39Sopenharmony_ci addxccc $hi1, $hi0, $hi1 281e1051a39Sopenharmony_ci addxc %g0, %g0, $ovf 282e1051a39Sopenharmony_ci stx $hi1, [$tp+8] 283e1051a39Sopenharmony_ci add $tp, 16, $tp 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci brnz,pt $i, .Louter 286e1051a39Sopenharmony_ci sub $i, 8, $i 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ci sub $anp, $num, $anp ! rewind 289e1051a39Sopenharmony_ci sub $tp, $num, $tp 290e1051a39Sopenharmony_ci sub $anp, $num, $anp 291e1051a39Sopenharmony_ci ba .Lsub 292e1051a39Sopenharmony_ci subcc $num, 8, $cnt ! cnt=num-1 and clear CCR.xcc 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ci.align 16 295e1051a39Sopenharmony_ci.Lsub: 296e1051a39Sopenharmony_ci ldx [$tp], $tj 297e1051a39Sopenharmony_ci add $tp, 8, $tp 298e1051a39Sopenharmony_ci ldx [$anp+8], $nj 299e1051a39Sopenharmony_ci add $anp, 16, $anp 300e1051a39Sopenharmony_ci subccc $tj, $nj, $t2 ! tp[j]-np[j] 301e1051a39Sopenharmony_ci srlx $tj, 32, $tj 302e1051a39Sopenharmony_ci srlx $nj, 32, $nj 303e1051a39Sopenharmony_ci subccc $tj, $nj, $t3 304e1051a39Sopenharmony_ci add $rp, 8, $rp 305e1051a39Sopenharmony_ci st $t2, [$rp-4] ! reverse order 306e1051a39Sopenharmony_ci st $t3, [$rp-8] 307e1051a39Sopenharmony_ci brnz,pt $cnt, .Lsub 308e1051a39Sopenharmony_ci sub $cnt, 8, $cnt 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci sub $anp, $num, $anp ! rewind 311e1051a39Sopenharmony_ci sub $tp, $num, $tp 312e1051a39Sopenharmony_ci sub $anp, $num, $anp 313e1051a39Sopenharmony_ci sub $rp, $num, $rp 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_ci subccc $ovf, %g0, $ovf ! handle upmost overflow bit 316e1051a39Sopenharmony_ci ba .Lcopy 317e1051a39Sopenharmony_ci sub $num, 8, $cnt 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci.align 16 320e1051a39Sopenharmony_ci.Lcopy: ! conditional copy 321e1051a39Sopenharmony_ci ld [$tp+0], $t0 322e1051a39Sopenharmony_ci ld [$tp+4], $t1 323e1051a39Sopenharmony_ci ld [$rp+0], $t2 324e1051a39Sopenharmony_ci ld [$rp+4], $t3 325e1051a39Sopenharmony_ci stx %g0, [$tp] ! zap 326e1051a39Sopenharmony_ci add $tp, 8, $tp 327e1051a39Sopenharmony_ci stx %g0, [$anp] ! zap 328e1051a39Sopenharmony_ci stx %g0, [$anp+8] 329e1051a39Sopenharmony_ci add $anp, 16, $anp 330e1051a39Sopenharmony_ci movcs %icc, $t0, $t2 331e1051a39Sopenharmony_ci movcs %icc, $t1, $t3 332e1051a39Sopenharmony_ci st $t3, [$rp+0] ! flip order 333e1051a39Sopenharmony_ci st $t2, [$rp+4] 334e1051a39Sopenharmony_ci add $rp, 8, $rp 335e1051a39Sopenharmony_ci brnz $cnt, .Lcopy 336e1051a39Sopenharmony_ci sub $cnt, 8, $cnt 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_ci mov 1, %o0 339e1051a39Sopenharmony_ci ret 340e1051a39Sopenharmony_ci restore 341e1051a39Sopenharmony_ci.type bn_mul_mont_vis3, #function 342e1051a39Sopenharmony_ci.size bn_mul_mont_vis3, .-bn_mul_mont_vis3 343e1051a39Sopenharmony_ci.asciz "Montgomery Multiplication for SPARCv9 VIS3, CRYPTOGAMS by <appro\@openssl.org>" 344e1051a39Sopenharmony_ci.align 4 345e1051a39Sopenharmony_ci___ 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ci# Purpose of these subroutines is to explicitly encode VIS instructions, 348e1051a39Sopenharmony_ci# so that one can compile the module without having to specify VIS 349e1051a39Sopenharmony_ci# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a. 350e1051a39Sopenharmony_ci# Idea is to reserve for option to produce "universal" binary and let 351e1051a39Sopenharmony_ci# programmer detect if current CPU is VIS capable at run-time. 352e1051a39Sopenharmony_cisub unvis3 { 353e1051a39Sopenharmony_cimy ($mnemonic,$rs1,$rs2,$rd)=@_; 354e1051a39Sopenharmony_cimy %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 ); 355e1051a39Sopenharmony_cimy ($ref,$opf); 356e1051a39Sopenharmony_cimy %visopf = ( "addxc" => 0x011, 357e1051a39Sopenharmony_ci "addxccc" => 0x013, 358e1051a39Sopenharmony_ci "umulxhi" => 0x016 ); 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci $ref = "$mnemonic\t$rs1,$rs2,$rd"; 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci if ($opf=$visopf{$mnemonic}) { 363e1051a39Sopenharmony_ci foreach ($rs1,$rs2,$rd) { 364e1051a39Sopenharmony_ci return $ref if (!/%([goli])([0-9])/); 365e1051a39Sopenharmony_ci $_=$bias{$1}+$2; 366e1051a39Sopenharmony_ci } 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci return sprintf ".word\t0x%08x !%s", 369e1051a39Sopenharmony_ci 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2, 370e1051a39Sopenharmony_ci $ref; 371e1051a39Sopenharmony_ci } else { 372e1051a39Sopenharmony_ci return $ref; 373e1051a39Sopenharmony_ci } 374e1051a39Sopenharmony_ci} 375e1051a39Sopenharmony_ci 376e1051a39Sopenharmony_ciforeach (split("\n",$code)) { 377e1051a39Sopenharmony_ci s/\`([^\`]*)\`/eval $1/ge; 378e1051a39Sopenharmony_ci 379e1051a39Sopenharmony_ci s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/ 380e1051a39Sopenharmony_ci &unvis3($1,$2,$3,$4) 381e1051a39Sopenharmony_ci /ge; 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci print $_,"\n"; 384e1051a39Sopenharmony_ci} 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ciclose STDOUT or die "error closing STDOUT: $!"; 387